@@ -257,8 +257,9 @@ mlir::Block *CIRGenFunction::getEHResumeBlock(bool isCleanup) {
257
257
// pointer but only use it to denote we're tracking things, but there
258
258
// shouldn't be any changes to that block after work done in this function.
259
259
auto catchOp = currLexScope->getExceptionInfo ().catchOp ;
260
- assert (catchOp && catchOp.getNumRegions () && " expected at least one region" );
261
- auto &fallbackRegion = catchOp.getRegion (catchOp.getNumRegions () - 1 );
260
+ unsigned numCatchRegions = catchOp.getCatchRegions ().size ();
261
+ assert (catchOp && numCatchRegions && " expected at least one region" );
262
+ auto &fallbackRegion = catchOp.getCatchRegions ()[numCatchRegions - 1 ];
262
263
263
264
auto *resumeBlock = &fallbackRegion.getBlocks ().back ();
264
265
if (!resumeBlock->empty ())
@@ -322,7 +323,6 @@ CIRGenFunction::buildCXXTryStmtUnderScope(const CXXTryStmt &S) {
322
323
323
324
auto numHandlers = S.getNumHandlers ();
324
325
auto tryLoc = getLoc (S.getBeginLoc ());
325
- auto scopeLoc = getLoc (S.getSourceRange ());
326
326
327
327
mlir::OpBuilder::InsertPoint beginInsertTryBody;
328
328
auto ehPtrTy = mlir::cir::PointerType::get (
@@ -335,28 +335,21 @@ CIRGenFunction::buildCXXTryStmtUnderScope(const CXXTryStmt &S) {
335
335
// info but don't emit the bulk right away, for now only make sure the
336
336
// scope returns the exception information.
337
337
auto tryScope = builder.create <mlir::cir::TryOp>(
338
- scopeLoc , /* scopeBuilder=*/
339
- [&](mlir::OpBuilder &b, mlir::Type &yieldTy, mlir:: Location loc) {
338
+ tryLoc , /* scopeBuilder=*/
339
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
340
340
// Allocate space for our exception info that might be passed down
341
341
// to `cir.try_call` everytime a call happens.
342
- yieldTy = ehPtrTy;
343
342
exceptionInfoInsideTry = b.create <mlir::cir::AllocaOp>(
344
- loc, /* addr type*/ getBuilder ().getPointerTo (yieldTy ),
345
- /* var type*/ yieldTy , " __exception_ptr" ,
343
+ loc, /* addr type*/ getBuilder ().getPointerTo (ehPtrTy ),
344
+ /* var type*/ ehPtrTy , " __exception_ptr" ,
346
345
CGM.getSize (CharUnits::One ()), nullptr );
347
346
348
347
beginInsertTryBody = getBuilder ().saveInsertionPoint ();
349
- });
350
-
351
- // The catch {} parts consume the exception information provided by a
352
- // try scope. Also don't emit the code right away for catch clauses, for
353
- // now create the regions and consume the try scope result.
354
- // Note that clauses are later populated in
355
- // CIRGenFunction::buildLandingPad.
356
- auto catchOp = builder.create <mlir::cir::CatchOp>(
357
- tryLoc,
358
- tryScope->getResult (
359
- 0 ), // FIXME(cir): we can do better source location here.
348
+ },
349
+ // Don't emit the code right away for catch clauses, for
350
+ // now create the regions and consume the try scope result.
351
+ // Note that clauses are later populated in
352
+ // CIRGenFunction::buildLandingPad.
360
353
[&](mlir::OpBuilder &b, mlir::Location loc,
361
354
mlir::OperationState &result) {
362
355
mlir::OpBuilder::InsertionGuard guard (b);
@@ -372,28 +365,24 @@ CIRGenFunction::buildCXXTryStmtUnderScope(const CXXTryStmt &S) {
372
365
373
366
// Finally emit the body for try/catch.
374
367
auto emitTryCatchBody = [&]() -> mlir::LogicalResult {
375
- auto loc = catchOp .getLoc ();
368
+ auto loc = tryScope .getLoc ();
376
369
mlir::OpBuilder::InsertionGuard guard (getBuilder ());
377
370
getBuilder ().restoreInsertionPoint (beginInsertTryBody);
378
371
CIRGenFunction::LexicalScope lexScope{*this , loc,
379
372
getBuilder ().getInsertionBlock ()};
380
373
381
374
{
382
- lexScope.setExceptionInfo ({exceptionInfoInsideTry, catchOp});
383
- // Attach the basic blocks for the catchOp regions into ScopeCatch
384
- // info.
385
- enterCXXTryStmt (S, catchOp);
375
+ lexScope.setExceptionInfo ({exceptionInfoInsideTry, tryScope});
376
+ // Attach the basic blocks for the catch regions.
377
+ enterCXXTryStmt (S, tryScope);
386
378
// Emit the body for the `try {}` part.
387
379
if (buildStmt (S.getTryBlock (), /* useCurrentScope=*/ true ).failed ())
388
380
return mlir::failure ();
389
-
390
- auto v = getBuilder ().create <mlir::cir::LoadOp>(loc, ehPtrTy,
391
- exceptionInfoInsideTry);
392
- getBuilder ().create <mlir::cir::YieldOp>(loc, v.getResult ());
381
+ getBuilder ().create <mlir::cir::YieldOp>(loc);
393
382
}
394
383
395
384
{
396
- lexScope.setExceptionInfo ({tryScope-> getResult ( 0 ), catchOp });
385
+ lexScope.setExceptionInfo ({nullptr , tryScope });
397
386
// Emit catch clauses.
398
387
exitCXXTryStmt (S);
399
388
}
@@ -452,7 +441,7 @@ static void buildCatchDispatchBlock(CIRGenFunction &CGF,
452
441
// If the next handler is a catch-all, we're at the end, and the
453
442
// next block is that handler.
454
443
} else if (catchScope.getHandler (i + 1 ).isCatchAll ()) {
455
- // Block already created when creating CatchOp , just mark this
444
+ // Block already created when creating catch regions , just mark this
456
445
// is the end.
457
446
nextIsEnd = true ;
458
447
}
@@ -464,14 +453,14 @@ static void buildCatchDispatchBlock(CIRGenFunction &CGF,
464
453
}
465
454
466
455
void CIRGenFunction::enterCXXTryStmt (const CXXTryStmt &S,
467
- mlir::cir::CatchOp catchOp,
456
+ mlir::cir::TryOp catchOp,
468
457
bool IsFnTryBlock) {
469
458
unsigned NumHandlers = S.getNumHandlers ();
470
459
EHCatchScope *CatchScope = EHStack.pushCatch (NumHandlers);
471
460
for (unsigned I = 0 ; I != NumHandlers; ++I) {
472
461
const CXXCatchStmt *C = S.getHandler (I);
473
462
474
- mlir::Block *Handler = &catchOp.getRegion (I) .getBlocks ().front ();
463
+ mlir::Block *Handler = &catchOp.getCatchRegions ()[I] .getBlocks ().front ();
475
464
if (C->getExceptionDecl ()) {
476
465
// FIXME: Dropping the reference type on the type into makes it
477
466
// impossible to correctly implement catch-by-reference
@@ -510,7 +499,18 @@ void CIRGenFunction::exitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
510
499
if (!CatchScope.hasEHBranches ()) {
511
500
CatchScope.clearHandlerBlocks ();
512
501
EHStack.popCatch ();
513
- currLexScope->getExceptionInfo ().catchOp ->erase ();
502
+ // Drop all basic block from all catch regions.
503
+ auto tryOp = currLexScope->getExceptionInfo ().catchOp ;
504
+ SmallVector<mlir::Block *> eraseBlocks;
505
+ for (mlir::Region &r : tryOp.getCatchRegions ()) {
506
+ if (r.empty ())
507
+ continue ;
508
+ for (mlir::Block &b : r.getBlocks ())
509
+ eraseBlocks.push_back (&b);
510
+ }
511
+ for (mlir::Block *b : eraseBlocks)
512
+ b->erase ();
513
+ tryOp.setCatchTypesAttr ({});
514
514
return ;
515
515
}
516
516
@@ -630,43 +630,13 @@ mlir::Operation *CIRGenFunction::buildLandingPad() {
630
630
return lpad;
631
631
}
632
632
633
- // If there's an existing CatchOp , it means we got a `cir.try` scope
633
+ // If there's an existing TryOp , it means we got a `cir.try` scope
634
634
// that leads to this "landing pad" creation site. Otherwise, exceptions
635
- // are enabled but a throwing function is called anyways.
636
- auto catchOp = currLexScope->getExceptionInfo ().catchOp ;
637
- if (!catchOp) {
638
- auto loc = *currSrcLoc;
639
- auto ehPtrTy = mlir::cir::PointerType::get (
640
- getBuilder ().getContext (),
641
- getBuilder ().getType <::mlir::cir::ExceptionInfoType>());
642
-
643
- mlir::Value exceptionAddr;
644
- {
645
- // Get a new alloca within the current scope.
646
- mlir::OpBuilder::InsertionGuard guard (builder);
647
- exceptionAddr = buildAlloca (
648
- " __exception_ptr" , ehPtrTy, loc, CharUnits::One (),
649
- builder.getBestAllocaInsertPoint (builder.getInsertionBlock ()));
650
- }
651
-
652
- {
653
- // Insert catch at the end of the block, and place the insert pointer
654
- // back to where it was.
655
- mlir::OpBuilder::InsertionGuard guard (builder);
656
- auto exceptionPtr =
657
- builder.create <mlir::cir::LoadOp>(loc, ehPtrTy, exceptionAddr);
658
- catchOp = builder.create <mlir::cir::CatchOp>(
659
- loc, exceptionPtr,
660
- [&](mlir::OpBuilder &b, mlir::Location loc,
661
- mlir::OperationState &result) {
662
- // There's no source code level catch here, create one region for
663
- // the resume block.
664
- mlir::OpBuilder::InsertionGuard guard (b);
665
- auto *r = result.addRegion ();
666
- builder.createBlock (r);
667
- });
668
- }
669
- currLexScope->setExceptionInfo ({exceptionAddr, catchOp});
635
+ // are enabled but a throwing function is called anyways (common pattern
636
+ // with function local static initializers).
637
+ auto tryOp = currLexScope->getExceptionInfo ().catchOp ;
638
+ if (!tryOp) {
639
+ llvm_unreachable (" NYI" );
670
640
}
671
641
672
642
{
@@ -752,17 +722,17 @@ mlir::Operation *CIRGenFunction::buildLandingPad() {
752
722
assert (!MissingFeatures::setLandingPadCleanup ());
753
723
}
754
724
755
- assert ((clauses.size () > 0 || hasCleanup) && " CatchOp has no clauses!" );
725
+ assert ((clauses.size () > 0 || hasCleanup) && " no catch clauses!" );
756
726
757
727
// If there's no catch_all, attach the unwind region. This needs to be the
758
- // last region in the CatchOp operation.
728
+ // last region in the TryOp operation catch list .
759
729
if (!hasCatchAll) {
760
730
auto catchUnwind = mlir::cir::CatchUnwindAttr::get (builder.getContext ());
761
731
clauses.push_back (catchUnwind);
762
732
}
763
733
764
- // Add final array of clauses into catchOp .
765
- catchOp. setCatchersAttr (
734
+ // Add final array of clauses into TryOp .
735
+ tryOp. setCatchTypesAttr (
766
736
mlir::ArrayAttr::get (builder.getContext (), clauses));
767
737
768
738
// In traditional LLVM codegen. this tells the backend how to generate the
@@ -772,7 +742,7 @@ mlir::Operation *CIRGenFunction::buildLandingPad() {
772
742
(void )getEHDispatchBlock (EHStack.getInnermostEHScope ());
773
743
}
774
744
775
- return catchOp ;
745
+ return tryOp ;
776
746
}
777
747
778
748
// Differently from LLVM traditional codegen, there are no dispatch blocks
0 commit comments