================
@@ -325,19 +374,47 @@ mlir::LogicalResult
ItaniumEHLowering::lowerFunc(cir::FuncOp funcOp) {
if (!funcOp.getPersonality())
funcOp.setPersonality(kGxxPersonality);
- // Lower each initiate and all EH ops connected to it. The token map is
- // shared across all initiate operations. Multiple initiates may flow into
the
- // same dispatch block, and the map ensures the arguments are registered
- // only once. Dispatch ops are scheduled for deferred removal so that sibling
- // initiates can still read catch types from a shared dispatch.
+ // Compute, read-only and before any destructive lowering, the dispatches
each
+ // initiate's exception can reach (innermost first; more than one for nested
+ // try/catch). A landing pad's catch types are a property of the EH graph,
so
+ // deriving them here keeps them independent of the order in which the
+ // destructive per-initiate traversal in lowerEhInitiate tears down shared
+ // token-graph edges. Otherwise a sibling or outer dispatch could be missed,
+ // leaving a landing pad without its catch clause (it would resume past the
+ // handler to std::terminate) or an un-lowered leftover dispatch.
+ llvm::DenseMap<mlir::Operation *, SmallVector<cir::EhDispatchOp>>
+ reachedDispatches;
+ llvm::DenseMap<mlir::Operation *, bool> reachesCleanup;
+ SmallVector<cir::EhDispatchOp> dispatchesToLower;
+ for (cir::EhInitiateOp initiateOp : initiateOps) {
+ SmallVector<cir::EhDispatchOp> reached;
+ bool cleanupOnPath = false;
+ collectReachableDispatches(initiateOp.getEhToken(), reached,
cleanupOnPath);
+ for (cir::EhDispatchOp dispatch : reached)
+ if (!llvm::is_contained(dispatchesToLower, dispatch))
+ dispatchesToLower.push_back(dispatch);
+ reachedDispatches[initiateOp.getOperation()] = std::move(reached);
+ reachesCleanup[initiateOp.getOperation()] = cleanupOnPath;
+ }
+
EhTokenMap ehTokenMap;
SmallVector<mlir::Operation *> deadOps;
for (cir::EhInitiateOp initiateOp : initiateOps)
- if (mlir::failed(lowerEhInitiate(initiateOp, ehTokenMap, deadOps)))
+ if (mlir::failed(lowerEhInitiate(
+ initiateOp, reachedDispatches[initiateOp.getOperation()],
+ reachesCleanup[initiateOp.getOperation()], ehTokenMap, deadOps)))
return mlir::failure();
+ // Lower each dispatch exactly once. Every initiate's token block-argument
+ // (ptr, u32) replacements are registered in ehTokenMap by now, so each
+ // dispatch's own (exnPtr, typeId) pair is available.
+ for (cir::EhDispatchOp dispatch : dispatchesToLower) {
+ auto [exnPtr, typeId] = ehTokenMap.lookup(dispatch.getEhToken());
----------------
adams381 wrote:
Added `assert(exnPtr && typeId && ...)` before the `lowerDispatch` call.
https://github.com/llvm/llvm-project/pull/205638
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits