This is an archive of the discontinued LLVM Phabricator instance.

Quick look-up for block in loop
ClosedPublic

Authored by shawfly on Oct 24 2013, 6:06 AM.

Details

Reviewers
atrick
Summary

In LoopInfo.cpp and LoopInfoImpl.h, it is frequently to judge a specified block is in a loop or not, eg. getExitBlocks();

Currently the implementation is like this:
a. Copy all blocks into a vector and sort it, then use binary search to look up it.
b. Construct SmallPtrSet to implement quick search, when the set is small, it is same as the linear search in vector.

These two ways are proven very inefficient, it causes 2~4% performance penalty of llc for the cases with many loops; such as 458.sjeng, 429.mcf, 456.hmmer in CPUSpec2006.

This patch implement quick_contains() to look up a block in loop:

  1. when the block size is small, look up the block vector directly to avoid construction of any other data container.
  2. otherwise construct DenseSet to implement quick look-up.

This patch could introduce 2~3% compilation time improvement in llc for the benchmark with many loops.

Diff Detail

Event Timeline

Wan,

Do you think that it would be worthwhile to cache the DenseSet once constructed?

Also, in LCSSA, we currently keep a cache of the sorted loop blocks array, solely for the purpose of this function:

/// inLoop - returns true if the given block is within the current loop
bool inLoop(BasicBlock *B) const {
  return std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), B);
}

With this new, more-efficient, functionality in LoopInfo, especially if we cache the resulting set, I think that it would make sense to remove this inLoop implementation from LCSSA and let it call the regular contains(BB) function.

Finally, when you post patches to llvm-reviews, please generate them with -U999999 so that we can see the full context in the web interface.

Thanks,
Hal

  • Original Message -----

Hi atrick,

In LoopInfo.cpp and LoopInfoImpl.h, it is frequently to judge a
specified block is in a loop or not, eg. getExitBlocks();

Currently the implementation is like this:
a. Copy all blocks into a vector and sort it, then use binary search
to look up it.
b. Construct SmallPtrSet to implement quick search, when the set is
small, it is same as the linear search in vector.

These two ways are proven very inefficient, it causes 2~4%
performance penalty of llc for the cases with many loops; such as
458.sjeng, 429.mcf, 456.hmmer in CPUSpec2006.

This patch implement quick_contains() to look up a block in loop:

  1. when the block size is small, look up the block vector directly to

avoid construction of any other data container.

  1. otherwise construct DenseSet to implement quick look-up.

This patch could introduce 2~3% compilation time improvement in llc
for the benchmark with many loops.

http://llvm-reviews.chandlerc.com/D2014

Files:

include/llvm/Analysis/LoopInfo.h
include/llvm/Analysis/LoopInfoImpl.h
lib/Analysis/LoopInfo.cpp

llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Hal:

Thanks for your comments, I don't think the DenseSet could be cached since the blocks in loop may be changed.

Finally, when you post patches to llvm-reviews, please generate them with -U999999 so that we can see the full context in the web interface.
~~~~What diff tool do you usually use, it seems svn diff has no option -U999999, thanks.

Thanks
Wan Xiaofei

  • Original Message -----
Hal:

Thanks for your comments, I don't think the DenseSet could be
cached since the blocks in loop may be changed.

I think that, normally, blocks can't be added or removed from a loop without either invalidating the LoopInfo, or updating it (calling LoopInfo::removeBlock, changeLoopFor, etc.). I think that to get a mutable copy of the blocks array directly, getBlocksVector needs to be called (and it could invalidate the cache, and prevent further caching after it is called).

Finally, when you post patches to llvm-reviews, please generate
them with -U999999 so that we can see the full context in the web
interface.
~~~~What diff tool do you usually use, it seems svn diff has no
option -U999999, thanks.

http://llvm.org/docs/Phabricator.html says:

svn diff --diff-cmd=diff -x -U999999

Personally, I use git-svn, so it is a bit easier.

Thanks,
Hal

Thanks
Wan Xiaofei

http://llvm-reviews.chandlerc.com/D2014

How do you think only exposing two write interfaces for block vector (remove block & add block, it is enough); then the DenseSet could be cached and maintained easily.

It could introduce some extra performance benefit if the DenseSet needn't be constructed each time.
Take 458.sjeng as example, the time in LoopInfo is about ~4% without this patch, now it is ~1% with this patch, so it may introduce ~1% extra performance gain if DenseSet is cached.

Thanks
Wan Xiaofei

shawfly updated this revision to Unknown Object (????).Oct 24 2013, 7:09 AM

Show full context for this patch

shawfly updated this revision to Unknown Object (????).Oct 24 2013, 8:34 AM

Remove getBlocksVector() to make it easier to cache the DenseSet.

Wan,

Please remove the tabs.

-Hal

  • Original Message -----

Remove getBlocksVector() to make it easier to cache the DenseSet.

Hi atrick,

http://llvm-reviews.chandlerc.com/D2014

CHANGE SINCE LAST DIFF

http://llvm-reviews.chandlerc.com/D2014?vs=5126&id=5131#toc

Files:

include/llvm/Analysis/LoopInfoImpl.h
include/llvm/Analysis/LoopInfo.h
lib/Transforms/Vectorize/LoopVectorize.cpp
lib/Transforms/Utils/LCSSA.cpp
lib/Analysis/LoopInfo.cpp
shawfly updated this revision to Unknown Object (????).Oct 24 2013, 8:56 AM

Remove tabs

Thanks Xiaofei. If you address my two inline comments, I think this is ready to checkin.

include/llvm/Analysis/LoopInfo.h
278–281

Why does this clear the cache?

include/llvm/Analysis/LoopInfoImpl.h
421

Oh no. Why don't we reserve the block vector any more? Can you just add an API for it?

shawfly updated this revision to Unknown Object (????).Oct 25 2013, 5:47 PM

Update according Andy's comments.

LGTM. When you commit, please do s/reserveBlock/reserveBlocks/g.

atrick accepted this revision.Oct 25 2013, 7:06 PM
Eugene.Zelenko closed this revision.Oct 4 2016, 5:12 PM
Eugene.Zelenko added a subscriber: Eugene.Zelenko.

Committed in rL193460.