From fd3ba1d17ccd8c0ed8bef1040275735ab9c2593a Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Fri, 13 Sep 2024 16:34:13 -0700 Subject: [PATCH] [CIR][CIRGen][NFC] Exceptions: Move the logic to create surrounding try to be close to call generation --- clang/lib/CIR/CodeGen/CIRGenCall.cpp | 52 ++++++++++++++----- clang/lib/CIR/CodeGen/CIRGenCleanup.cpp | 4 +- clang/lib/CIR/CodeGen/CIRGenException.cpp | 38 +------------- clang/lib/CIR/CodeGen/CIRGenFunction.h | 6 +-- clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 2 +- 5 files changed, 48 insertions(+), 54 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index cdf9bccdd062..a446cc641dda 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -450,6 +450,31 @@ buildCallLikeOp(CIRGenFunction &CGF, mlir::Location callLoc, mlir::cir::CallingConv callingConv, mlir::cir::ExtraFuncAttributesAttr extraFnAttrs) { auto &builder = CGF.getBuilder(); + auto getOrCreateSurroundingTryOp = [&]() { + // In OG, we build the landing pad for this scope. In CIR, we emit a + // synthetic cir.try because this didn't come from codegenerating from a + // try/catch in C++. + auto op = CGF.currLexScope->getClosestTryParent(); + if (op) + return op; + + op = builder.create( + *CGF.currSrcLoc, /*scopeBuilder=*/ + [&](mlir::OpBuilder &b, mlir::Location loc) {}, + // Don't emit the code right away for catch clauses, for + // now create the regions and consume the try scope result. + // Note that clauses are later populated in + // CIRGenFunction::buildLandingPad. + [&](mlir::OpBuilder &b, mlir::Location loc, + mlir::OperationState &result) { + // Since this didn't come from an explicit try, we only need one + // handler: unwind. + auto *r = result.addRegion(); + builder.createBlock(r); + }); + op.setSynthetic(true); + return op; + }; if (isInvoke) { // This call can throw, few options: @@ -457,33 +482,37 @@ buildCallLikeOp(CIRGenFunction &CGF, mlir::Location callLoc, // one provided by InvokeDest, // - User written try/catch clauses require calls to handle // exceptions under cir.try. - auto *invokeDest = CGF.getInvokeDest(); - auto tryOp = dyn_cast_if_present(invokeDest); + auto tryOp = getOrCreateSurroundingTryOp(); + assert(tryOp && "expected"); + mlir::OpBuilder::InsertPoint ip = builder.saveInsertionPoint(); - bool changeInsertion = tryOp && tryOp.getSynthetic(); - if (changeInsertion) { + if (tryOp.getSynthetic()) { mlir::Block *lastBlock = &tryOp.getTryRegion().back(); builder.setInsertionPointToStart(lastBlock); } else { assert(builder.getInsertionBlock() && "expected valid basic block"); } - mlir::cir::CallOp tryCallOp; + mlir::cir::CallOp callOpWithExceptions; // TODO(cir): Set calling convention for `cir.try_call`. assert(callingConv == mlir::cir::CallingConv::C && "NYI"); if (indirectFuncTy) { - tryCallOp = builder.createIndirectTryCallOp(callLoc, indirectFuncVal, - indirectFuncTy, CIRCallArgs); + callOpWithExceptions = builder.createIndirectTryCallOp( + callLoc, indirectFuncVal, indirectFuncTy, CIRCallArgs); } else { - tryCallOp = builder.createTryCallOp(callLoc, directFuncOp, CIRCallArgs); + callOpWithExceptions = + builder.createTryCallOp(callLoc, directFuncOp, CIRCallArgs); } - tryCallOp->setAttr("extra_attrs", extraFnAttrs); + callOpWithExceptions->setAttr("extra_attrs", extraFnAttrs); + + auto *invokeDest = CGF.getInvokeDest(tryOp); + (void)invokeDest; - if (changeInsertion) { + if (tryOp.getSynthetic()) { builder.create(tryOp.getLoc()); builder.restoreInsertionPoint(ip); } - return tryCallOp; + return callOpWithExceptions; } assert(builder.getInsertionBlock() && "expected valid basic block"); @@ -731,7 +760,6 @@ RValue CIRGenFunction::buildCall(const CIRGenFunctionInfo &CallInfo, noThrowAttr.getMnemonic())) CannotThrow = true; } - // mlir::Operation *InvokeDest = CannotThrow ? nullptr : getInvokeDest(); bool isInvoke = CannotThrow ? false : isInvokeDest(); // TODO: UnusedReturnSizePtr diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp index 6147c0285971..183ba2a6d0f5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp @@ -248,7 +248,7 @@ void CIRGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (!RequiresNormalCleanup) { // Mark CPP scope end for passed-by-value Arg temp // per Windows ABI which is "normally" Cleanup in callee - if (IsEHa && getInvokeDest()) { + if (IsEHa && isInvokeDest()) { // If we are deactivating a normal cleanup then we don't have a // fallthrough. Restore original IP to emit CPP scope ends in the correct // block. @@ -319,7 +319,7 @@ void CIRGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (!Personality.isMSVCPersonality()) { EHStack.pushTerminate(); PushedTerminate = true; - } else if (IsEHa && getInvokeDest()) { + } else if (IsEHa && isInvokeDest()) { llvm_unreachable("NYI"); } diff --git a/clang/lib/CIR/CodeGen/CIRGenException.cpp b/clang/lib/CIR/CodeGen/CIRGenException.cpp index 1c3d4c2a436f..87a441c64cb9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenException.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp @@ -831,12 +831,10 @@ bool CIRGenFunction::isInvokeDest() { return true; } -mlir::Operation *CIRGenFunction::getInvokeDestImpl() { +mlir::Operation *CIRGenFunction::getInvokeDestImpl(mlir::cir::TryOp tryOp) { assert(EHStack.requiresLandingPad()); assert(!EHStack.empty()); - - if (!isInvokeDest()) - return nullptr; + assert(isInvokeDest()); // Check the innermost scope for a cached landing pad. If this is // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad. @@ -850,43 +848,11 @@ mlir::Operation *CIRGenFunction::getInvokeDestImpl() { // if (!CurFn->hasPersonalityFn()) // CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality)); - auto createSurroundingTryOp = [&]() { - // In OG, we build the landing pad for this scope. In CIR, we emit a - // synthetic cir.try because this didn't come from codegenerating from a - // try/catch in C++. - auto tryOp = builder.create( - *currSrcLoc, /*scopeBuilder=*/ - [&](mlir::OpBuilder &b, mlir::Location loc) {}, - // Don't emit the code right away for catch clauses, for - // now create the regions and consume the try scope result. - // Note that clauses are later populated in - // CIRGenFunction::buildLandingPad. - [&](mlir::OpBuilder &b, mlir::Location loc, - mlir::OperationState &result) { - // Since this didn't come from an explicit try, we only need one - // handler: unwind. - auto *r = result.addRegion(); - builder.createBlock(r); - }); - tryOp.setSynthetic(true); - return tryOp; - }; - if (Personality.usesFuncletPads()) { // We don't need separate landing pads in the funclet model. llvm::errs() << "PersonalityFn: " << Personality.PersonalityFn << "\n"; llvm_unreachable("NYI"); } else { - mlir::cir::TryOp tryOp = nullptr; - // Attempt to find a suitable existing parent try/catch, if none - // is available, create a synthetic cir.try in order to wrap the side - // effects of a potential throw. - if (currLexScope) - tryOp = currLexScope->getClosestTryParent(); - if (!tryOp) - tryOp = createSurroundingTryOp(); - - assert(tryOp && "cir.try expected"); LP = buildLandingPad(tryOp); } diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 6ed823751160..ee6ecfdd3712 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1759,13 +1759,13 @@ class CIRGenFunction : public CIRGenTypeCache { /// parameters. EHScopeStack::stable_iterator PrologueCleanupDepth; - mlir::Operation *getInvokeDestImpl(); - mlir::Operation *getInvokeDest() { + mlir::Operation *getInvokeDestImpl(mlir::cir::TryOp tryOp); + mlir::Operation *getInvokeDest(mlir::cir::TryOp tryOp) { if (!EHStack.requiresLandingPad()) return nullptr; // Return the respective cir.try, this can be used to compute // any other relevant information. - return getInvokeDestImpl(); + return getInvokeDestImpl(tryOp); } bool isInvokeDest(); diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index 5f50a264c1f4..0c1279beea19 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -2227,7 +2227,7 @@ void CIRGenItaniumCXXABI::buildThrow(CIRGenFunction &CGF, // FIXME: When adding support for invoking, we should wrap the throw op // below into a try, and let CFG flatten pass to generate a cir.try_call. - assert(!CGF.getInvokeDest() && "landing pad like logic NYI"); + assert(!CGF.isInvokeDest() && "landing pad like logic NYI"); // Now throw the exception. mlir::Location loc = CGF.getLoc(E->getSourceRange());