This is an archive of the discontinued LLVM Phabricator instance.

[llvm][CallBrPrepare] use SSAUpdater to use intrinsic value
ClosedPublic

Authored by nickdesaulniers on Dec 13 2022, 2:12 PM.

Details

Summary

Now that we've inserted a call to an intrinsic, we need to update
certain previous uses of CallBrInst values to use the value of this
intrinsic instead.

There are 3 cases to handle:

  1. The @llvm.callbr.landingpad.<type>() intrinsic call is in the same BasicBlock as the use of the callbr we're replacing.
  2. The use is dominated by the direct destination.
  3. The use is not dominated by the direct destination, and may or may not be dominated by the indirect destination.

Part 2c of
https://discourse.llvm.org/t/rfc-syncing-asm-goto-with-outputs-with-gcc/65453/8.

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptDec 13 2022, 2:12 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
nickdesaulniers requested review of this revision.Dec 13 2022, 2:12 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 13 2022, 2:12 PM
aeubanks added inline comments.Dec 14 2022, 4:04 PM
llvm/lib/CodeGen/CallBrPrepare.cpp
62

this is dangerous to keep in the FunctionPass since they can be reused

I'd create it per-invocation in run()

166

make this a reference since it's required

176

I'd just ifndef NDEBUG around these two lines and remove the empty PrintDebugDomInfo implementation

182–184

maybe I'm misunderstanding what is going on, but can this be U.set(Intrinsic)?

llvm/lib/CodeGen/CallBrPrepare.cpp
175

This will loop infinitely if we update a Use in flight;

diff --git a/llvm/lib/CodeGen/CallBrPrepare.cpp b/llvm/lib/CodeGen/CallBrPrepare.cpp
index bbf14c5f8e97..7e9ad9593f45 100644
--- a/llvm/lib/CodeGen/CallBrPrepare.cpp
+++ b/llvm/lib/CodeGen/CallBrPrepare.cpp
@@ -176,8 +176,11 @@ void CallBrPrepare::UpdateSSA(DominatorTree *DT) const {
     CallBrInst *CBR = Pair.second;
     BasicBlock *DefaultDest = CBR->getDefaultDest();
     BasicBlock *LandingPad = Intrinsic->getParent();
+    SmallPtrSet<Use *, 2> Visited;
 
     for (Use &U : CBR->uses()) {
+      if (Visited.insert(&U).second)
+        continue;
       PrintDebugDomInfo(DT, U, LandingPad, /*IsDefaultDest*/ false);
       PrintDebugDomInfo(DT, U, DefaultDest, /*IsDefaultDest*/ true);
llvm/lib/CodeGen/CallBrPrepare.cpp
175

errr, more like:

diff --git a/llvm/lib/CodeGen/CallBrPrepare.cpp b/llvm/lib/CodeGen/CallBrPrepare.cpp
index bbf14c5f8e97..c9542de943a2 100644
--- a/llvm/lib/CodeGen/CallBrPrepare.cpp
+++ b/llvm/lib/CodeGen/CallBrPrepare.cpp
@@ -190,8 +190,9 @@ void CallBrPrepare::UpdateSSA(DominatorTree *DT) const {
         continue;
       }
 
-      // If the Use is dominated by the default dest, do not touch it.
-      if (DT->dominates(DefaultDest, U))
+      // If the Use is in the default dest BasicBlock, or dominated by the
+      // default dest, do not touch it.
+      if (IsInSameBasicBlock(U, DefaultDest) || DT->dominates(DefaultDest, U))
         continue;
 
       SSAUpdate.Initialize(U->getType(), U->getName());
nickdesaulniers planned changes to this revision.Dec 15 2022, 4:31 PM
llvm/lib/CodeGen/CallBrPrepare.cpp
175

bah, neither of those are right. Ok, WIP.

nickdesaulniers marked 3 inline comments as done.
  • fix inf loop from revisiting uses with SSAUpdater
  • reinstantiate CallInst* to CallBrInst* mapping per function run
  • use reference rather than ptr
  • use Use::set rather than SSAUpdater for simple case
llvm/lib/CodeGen/CallBrPrepare.cpp
176

Slight disagree, but could be convinced otherwise. Do you feel strongly about this?

182–184

oh! yeah, nice!

Thanks for the review!

llvm/lib/CodeGen/CallBrPrepare.cpp
176

To expand on why I disagree; I'm optimizing for readability of the import part of the code (the part that's doing meaningful work). I'd prefer to hide the ugly ifdefs around the optional debug routine.

  • rebase, format
efriedma added inline comments.Jan 18 2023, 11:56 AM
llvm/lib/CodeGen/CallBrPrepare.cpp
177

You can't iterate this way if you're going to modify the uses, I think? Once you rewrite a use, it refers to a different use-list, so the iterator's increment won't do the right thing.

199

This usage of SSAUpdater seems a little strange. It would be more efficient to construct one SSAUpdater per callbr, instead of one SSAUpdater per use. You can construct the SSAUpdater, AddAvailableValue all the intrinsic call for that callbr, then rewrite all the relevant uses using that SSAUpdater.

void added inline comments.Jan 18 2023, 3:47 PM
llvm/lib/CodeGen/CallBrPrepare.cpp
163

Instead of having an empty function here, why not wrap calls in #ifndef NDEBUG?

nickdesaulniers planned changes to this revision.Jan 18 2023, 3:49 PM
llvm/lib/CodeGen/CallBrPrepare.cpp
177

You're right, I'll add a test for that. I have one locally that's failing due to this. Will add it.

199

You're right, I'll add a test for that. I have one locally that's failing due to this. Will add it.

199

sorry, wrong comment on wrong thread.

nickdesaulniers marked 4 inline comments as done.
  • create one SSAUpdater per callbr, initialize it once. as per @efriedma
  • fix iteration invalidation bug in uses, add test, as per @efriedma
  • move NDEBUG, as per @auebanks and @void

Instead of having InsertIntrinsicCalls construct a map of SSAUpdaters, then have UpdateSSA iterate through it, can you just perform all the SSA updates involving a given SSAUpdater immediately after constructing it? The separation seems to add complexity without any benefit.

nickdesaulniers planned changes to this revision.Jan 19 2023, 4:24 PM

Instead of having InsertIntrinsicCalls construct a map of SSAUpdaters, then have UpdateSSA iterate through it, can you just perform all the SSA updates involving a given SSAUpdater immediately after constructing it? The separation seems to add complexity without any benefit.

Yeah, that was a nice cleanup. PTAL.

This revision is now accepted and ready to land.Jan 25 2023, 9:18 AM
jyknight accepted this revision.Jan 27 2023, 2:50 PM
void accepted this revision.Jan 31 2023, 4:16 PM
  • merge D142940 test changes, final rebase
This revision was landed with ongoing or failed builds.Feb 16 2023, 6:04 PM
This revision was automatically updated to reflect the committed changes.