This is an archive of the discontinued LLVM Phabricator instance.

FunctionPropertiesAnalysis: handle callsite BBs that loose edges
ClosedPublic

Authored by mtrofin on Jun 8 2022, 3:05 PM.

Details

Summary

There could be successors that were reached before but now are only
reachable from elsewhere in the CFG.

Suppose the following diamond CFG (lines are arrows pointing down):

   A
 /   \
B     C
 \   /
   D

There's a call site in C that is inlined. Upon doing that, it turns out
it expands to:

call void @llvm.trap()
unreachable

D isn't reachable from C anymore, but we did discount it when we set up
FunctionPropertiesUpdater, so we need to re-include it here.

The patch also updates loop accounting to use LoopInfo rather than traverse BBs.

Diff Detail

Event Timeline

mtrofin created this revision.Jun 8 2022, 3:05 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 8 2022, 3:05 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
mtrofin requested review of this revision.Jun 8 2022, 3:05 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 8 2022, 3:05 PM
mtrofin edited the summary of this revision. (Show Details)Jun 9 2022, 3:01 PM
kazu added inline comments.Jun 9 2022, 3:16 PM
llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
195

I may be being paranoid here, but is pred_empty(Succ) a correct condition here?

If Succ doesn't have any incoming edge, we can certainly disregard it. Now, if Succ has at least one incoming edge, could we have a corner case like this?

  • SuccA has no incoming edge after inlining, and
  • SuccB has an incoming edge from SuccA after inlining with no other incoming edge.

In this case, neither SuccA nor SuccB is reachable from the entry basic block, but your algorithm would end up re-including SuccB.

If we know for sure that this kind of thing never happens, I wonder if we can put an assert somewhere. For example, each successor has exactly one incoming edge prior to inlining because of exception semantics or something, we may be able to assert that as we populate Successors.

mtrofin marked an inline comment as done.Jun 9 2022, 7:20 PM
mtrofin added inline comments.
llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
195

Good point - thanks - and we should be probably just using the dominator tree to see if a BB is reachable from the entry point. I need D127467 landed first, as this fix then depends on that.

mtrofin updated this revision to Diff 436482.Jun 13 2022, 11:14 AM
mtrofin marked an inline comment as done.

updated to use domtree instead of counting preds

mtrofin edited the summary of this revision. (Show Details)Jun 13 2022, 11:15 AM
mtrofin retitled this revision from FunctionPropertiesAnalysis: handle callsite BBs that lose edges to FunctionPropertiesAnalysis: handle callsite BBs that loose edges.Jun 13 2022, 4:26 PM
kazu accepted this revision.Jun 14 2022, 2:07 PM

LGTM with some cosmetic suggestions. Thanks!

llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
75
llvm::append_range(Worklist, LI);
81–82
llvm::append_range(Worklist, L->getSubLoops());
196–201

Could we simplify this a little bit like so?

for (const auto *Succ : Successors)
  if (DT.isReachableFromEntry(Succ) && ReIncluded.insert(Succ).second)
    FPI.reIncludeBB(*Succ);

We could use a SetVector as a uniquified work list and prime it with Successors as sentinels, thereby eliminating the two if statements in the while loop above like so:

SetVector<const BasicBlock *> Worklist;

if (&CallSiteBB != &*Caller.begin()) {
  FPI.reIncludeBB(*Caller.begin());
  Worklist.insert(&*Caller.begin());
}

for (const auto *Succ : Successors)
  if (DT.isReachableFromEntry(Succ) && Worklist.insert(Succ))
    FPI.reIncludeBB(*Succ);

unsigned InitialPos = Worklist.size();
Worklist.insert(&CallSiteBB);
for (unsigned I = InitialPos; I != Worklist.size(); I++) {
  const auto *BB = Worklist[I];
  FPI.reIncludeBB(*BB);
  for (const auto *Succ : successors(BB))
    Worklist.insert(Succ);
}

I hear that you have a follow-up patch. Take this suggestion only if it's compatible with your upcoming changes, of course.

This revision is now accepted and ready to land.Jun 14 2022, 2:07 PM
mtrofin marked 3 inline comments as done.Jun 14 2022, 3:19 PM
mtrofin added inline comments.
llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
196–201

Thanks, this looks neat!

This revision was landed with ongoing or failed builds.Jun 14 2022, 3:20 PM
This revision was automatically updated to reflect the committed changes.
mtrofin marked an inline comment as done.