This is an archive of the discontinued LLVM Phabricator instance.

[BasicAA] Cache nonEscapingLocalObjects for alias() calls.
ClosedPublic

Authored by asbirlea on Feb 1 2019, 3:10 PM.

Details

Summary

Use a small cache for Values tested by nonEscapingLocalObject().
Since the calls to PointerMayBeCaptured are fairly expensive, this saves
a good amount of compile time for anything relying heavily on
BasicAA.alias() calls.

This uses the same approach as the AliasCache, i.e. the cache is reset
after each alias() call. The cache is not used or updated by modRefInfo
calls since it's harder to know when to reset the cache.

Testcases that show improvements with this patch are too large to
include. Example compile time improvement: 7s to 6s.

Diff Detail

Repository
rL LLVM

Event Timeline

asbirlea created this revision.Feb 1 2019, 3:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 1 2019, 3:10 PM
Herald added subscribers: jlebar, sanjoy. · View Herald Transcript
chandlerc added inline comments.Feb 1 2019, 5:20 PM
lib/Analysis/BasicAliasAnalysis.cpp
122–126 ↗(On Diff #184859)

Can this function ever be re-entered? It seems unlikely given the structure.

If not, hoist the CacheIt iterator out, use insert, and then update it below rather than doing another lookup?

154–155 ↗(On Diff #184859)

Why not cache this too?

asbirlea updated this revision to Diff 185109.Feb 4 2019, 11:38 AM
asbirlea marked 4 inline comments as done.

Address comments.

Also wondered if the duplicated 4 lines are worth adding a lambda. Didn't seem worth it, but if you feel differently, I'll be happy to update it.

lib/Analysis/BasicAliasAnalysis.cpp
122–126 ↗(On Diff #184859)

IIUC, insert doesn't do a lookup. So using insert below (instead of []) should be equivalent to your suggestion? We are guaranteed we need to insert if we reached that point..

154–155 ↗(On Diff #184859)

I debated between sinking the cache search into each of the above ifs, or caching this.

Performance-wise, I see no difference between the cache search on all queries vs the checks inside the above ifs. So, sure, let's cache this too :)

If other folks find that querying the cache is more expensive when all conditions (isa+isNoAliasCall+ dyn_cast+attributes check) are false, then I can refactor this.

Just think we can poke the map a bit better here.

lib/Analysis/BasicAliasAnalysis.cpp
122–126 ↗(On Diff #184859)

Er, insert does do a lookup?

auto CacheIt;
if (IsCapturedCache) {
  bool Inserted;
  std::tie(CacheIt, Inserted) = IsCapturedCache->insert({V, false});
  if (!Inserted)
    // Found cached result, return it!
    return CacheIt->second;
}
...
bool Ret = !PointerMayBeCaptured(...);
if (IsCapturedCache)
  CacheIt->second = Ret;
return Ret;

This kind of code pattern should do a single lookup into the map instead of doing two.

154–155 ↗(On Diff #184859)

Sure, but will have to pull this all the way before the initial query to the cache. =D

Anyways, this makes sense to me.

asbirlea updated this revision to Diff 185420.Feb 5 2019, 3:13 PM
asbirlea marked 3 inline comments as done.

Address comment.

lib/Analysis/BasicAliasAnalysis.cpp
122–126 ↗(On Diff #184859)

Ah, you're right! Not sure why I was thinking that if *I* know the value is not in the set, the *set* will magically know too...

Thanks, updated.

chandlerc accepted this revision.Feb 5 2019, 3:20 PM

LGTM!

This revision is now accepted and ready to land.Feb 5 2019, 3:20 PM
This revision was automatically updated to reflect the committed changes.