This is an archive of the discontinued LLVM Phabricator instance.

Compute safety information in a much finer granularity.
ClosedPublic

Authored by trentxintong on Apr 24 2017, 7:05 AM.

Details

Summary

Instead of keeping a variable indicating whether there are early exits
in the loop. We keep all the early exits. This improves LICM's ability to
move instructions out of the loop based on is-guaranteed-to-execute.

I measured noise-level compilation time difference on SPECINT2006.

Diff Detail

Repository
rL LLVM

Event Timeline

trentxintong created this revision.Apr 24 2017, 7:05 AM

Update test case.

hfinkel accepted this revision.Apr 24 2017, 9:09 AM

LGTM

include/llvm/Transforms/Utils/LoopUtils.h
49 ↗(On Diff #96394)

The comment here should explain that these are calls that might throw, etc.

This revision is now accepted and ready to land.Apr 24 2017, 9:09 AM

Address comment

trentxintong edited the summary of this revision. (Show Details)Apr 24 2017, 10:24 AM
This revision was automatically updated to reflect the committed changes.
sanjoy added inline comments.Apr 24 2017, 10:52 AM
llvm/trunk/lib/Transforms/Scalar/LICM.cpp
482

This can be a range for over blocks().

485

This can be a range for also.

487

This is subjective, but in this kind of situation, I tend to avoid early exits since you just have one line after the early exit.

llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
1049

Note: you could use all_of here, but this is fine too.

efriedma added inline comments.Apr 24 2017, 12:20 PM
llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
1050

This could be slow: if the two instructions are in the same basic block, dominates() will iterate over the whole block. And you don't attempt to prune the EarlyExits list, which could make LICM O(N^3) overall for a large loop with a single basic block.

I guess we'll see if it matters in practice.

dberlin added inline comments.
llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
1050

Two fixes, one short term we should do, one longer term

  1. Let that dominates call take an OBB as an optional argument
  1. Just provide global + local dominance ordering as an analysis that encapsulates both the OBB + DT solution, and remove that use of dominates in favor of the analysis.
hfinkel added inline comments.Apr 24 2017, 3:39 PM
llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
1050

Ack; I forgot about that scanning behavior. Using an OBB is right here. Right now, you need to do:

if (I1->getParent() == I2->getParent())
  return OBB->dominates(I1, I2);
else
  return DT->dominates(I1, I2);

I don't think we can yet hand an OBB directly to the DT (although that would certainly be a nice enhancement). I presume that we'd actually need a map of OBBs, as in Utils/PredicateInfo.h. Maybe stick it into LoopSafetyInfo?

dberlin added inline comments.Apr 27 2017, 1:32 PM
llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
1050

That is right, we can't do it yet, but seems simple enough.
We'd need a map.
Either add to loop safety info, or just define a struct that has the right properties and pass it along.