[PATCH] D16319: [Inliner/WinEH] Honor implicit nounwinds

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 19 09:29:35 PST 2016


majnemer added inline comments.

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:359
@@ +358,3 @@
+  Value *UnwindDestToken = getUnwindDestTokenHelper(EHPad, MemoMap);
+  assert((UnwindDestToken == nullptr) ^ (MemoMap.count(EHPad) != 0));
+  if (UnwindDestToken)
----------------
I'd use logical not-equal instead of bit-wise xor

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:392-409
@@ +391,20 @@
+  SmallVector<Instruction *, 8> Worklist;
+  for (Instruction *UselessPad = LastUselessPad;;
+       UselessPad = Worklist.pop_back_val()) {
+    assert(!MemoMap.count(UselessPad) || MemoMap[UselessPad] == nullptr);
+    MemoMap[UselessPad] = UnwindDestToken;
+    if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(UselessPad)) {
+      for (BasicBlock *HandlerBlock : CatchSwitch->handlers())
+        for (User *U : HandlerBlock->getFirstNonPHI()->users())
+          if (isa<CatchSwitchInst>(U) || isa<CleanupPadInst>(U))
+            Worklist.push_back(cast<Instruction>(U));
+    } else {
+      assert(isa<CleanupPadInst>(UselessPad));
+      for (User *U : UselessPad->users())
+        if (isa<CatchSwitchInst>(U) || isa<CleanupPadInst>(U))
+          Worklist.push_back(cast<Instruction>(U));
+    }
+    if (Worklist.empty())
+      break;
+  }
+
----------------
Would it be more idiomatic to start the worklist with `UselessPad` and switch the loop to something like `while (!Worklist.empty())`

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:445-453
@@ +444,11 @@
+        continue;
+      assert(FuncletUnwindMap->count(
+                 isa<CatchPadInst>(FuncletPad)
+                     ? cast<CatchPadInst>(FuncletPad)->getCatchSwitch()
+                     : FuncletPad) &&
+             (*FuncletUnwindMap)[isa<CatchPadInst>(FuncletPad)
+                                     ? cast<CatchPadInst>(FuncletPad)
+                                           ->getCatchSwitch()
+                                     : FuncletPad] == UnwindDestToken &&
+             "must get memoized to avoid confusing later searches");
+    }
----------------
I think this might be easier with `#ifndef NDEBUG`

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:449-452
@@ +448,6 @@
+                     : FuncletPad) &&
+             (*FuncletUnwindMap)[isa<CatchPadInst>(FuncletPad)
+                                     ? cast<CatchPadInst>(FuncletPad)
+                                           ->getCatchSwitch()
+                                     : FuncletPad] == UnwindDestToken &&
+             "must get memoized to avoid confusing later searches");
----------------
If we are in this case, can we also assert that `UnwindDestToken` is not null?

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:616-625
@@ +615,12 @@
+        Value *UnwindDestToken;
+        if (auto *ParentPad =
+                dyn_cast<Instruction>(CatchSwitch->getParentPad())) {
+          // This catchswitch is nested inside another funclet.  If that
+          // funclet has an unwind destination within the inlinee, then
+          // unwinding out of this catchswitch would be UB.  Rewriting this
+          // catchswitch to unwind to the inlined invoke's unwind dest would
+          // give the parent funclet multiple unwind destinations, which is
+          // something that subsequent EH table generation can't handle and
+          // that the veirifer rejects.  So when we see such a call, leave it
+          // as "unwind to caller".
+          UnwindDestToken = getUnwindDestToken(ParentPad, FuncletUnwindMap);
----------------
Does this case only arise when you have an unwind-to-caller catchswitch nested inside an unwind-to-caller catchswitch/cleanuppad?

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:630
@@ +629,3 @@
+        } else {
+          // This catchswitch has no patern to inherit constraints from, and
+          // none of its descendants can have an unwind edge that exits it and
----------------
patern -> parent?


http://reviews.llvm.org/D16319





More information about the llvm-commits mailing list