================
@@ -693,6 +696,101 @@ void LoweringPreparePass::lowerUnaryOp(cir::UnaryOp op) {
op.erase();
}
+cir::FuncOp LoweringPreparePass::getOrCreateDtorFunc(CIRBaseBuilderTy &builder,
+ cir::GlobalOp op,
+ mlir::Region &dtorRegion,
+ cir::CallOp &dtorCall) {
+ assert(!cir::MissingFeatures::astVarDeclInterface());
+ assert(!cir::MissingFeatures::opGlobalThreadLocal());
+
+ cir::VoidType voidTy = builder.getVoidTy();
+ auto voidPtrTy = cir::PointerType::get(voidTy);
+
+ // Look for operations in dtorBlock
+ mlir::Block &dtorBlock = dtorRegion.front();
+
+ // The first operation should be a get_global to retrieve the address
+ // of the global variable we're destroying.
+ auto opIt = dtorBlock.getOperations().begin();
+ cir::GetGlobalOp ggop = mlir::cast<cir::GetGlobalOp>(*opIt);
+
+ // The simple case is just a call to a destructor, like this:
+ //
+ // %0 = cir.get_global %globalS : !cir.ptr<!rec_S>
+ // cir.call %_ZN1SD1Ev(%0) : (!cir.ptr<!rec_S>) -> ()
+ // (implicit cir.yield)
+ //
+ // That is, if the second operation is a call that takes the get_global
result
+ // as its only operand, and the only other operation is a yield, then we can
+ // just return the called function.
+ if (dtorBlock.getOperations().size() == 3) {
+ auto callOp = mlir::dyn_cast<cir::CallOp>(&*(++opIt));
+ auto yieldOp = mlir::dyn_cast<cir::YieldOp>(&*(++opIt));
+ if (yieldOp && callOp && callOp.getNumOperands() == 1 &&
+ callOp.getArgOperand(0) == ggop) {
+ dtorCall = callOp;
+ return getCalledFunction(callOp);
+ }
+ }
+
+ // Otherwise, we need to create a helper function to replace the dtor region.
+ // This name is kind of arbitrary, but it matches the name that classic
+ // codegen uses, based on the expected case that gets us here.
+ builder.setInsertionPointAfter(op);
+ SmallString<256> fnName("__cxx_global_array_dtor");
+ uint32_t cnt = dynamicInitializerNames[fnName]++;
+ if (cnt)
+ fnName += "." + llvm::Twine(cnt).str();
----------------
erichkeane wrote:
Oh, I'm not complaining about HOW we're uniquing them, just how we are
constructing the string.
The twine.str causes a new string to be created. Then the operator+ prepends a
"." to it, which requires 2nd string to be allocated (for the result), which
can finally THEN be added to the fnName.
I was suggesting we do the `'.' + llvm::Twine(cnt)` math as a single
twine+twine operation, which reduces the 2 string allocations to 1 (see putting
the parens around the '.' and hte llvm::Twine ctor.
https://github.com/llvm/llvm-project/pull/169070
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits