From: Benjamin Kramer Date: Mon, 5 Dec 2011 17:23:27 +0000 (+0000) Subject: Add a little heuristic to Value::isUsedInBasicBlock to speed it up for small basic... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=4da7f90b1780e4d1ba38da64c849b9c2b1c67071;p=oota-llvm.git Add a little heuristic to Value::isUsedInBasicBlock to speed it up for small basic blocks. - Calling getUser in a loop is much more expensive than iterating over a few instructions. - Use it instead of the open-coded loop in AddrModeMatcher. - 5% speedup on ARMDisassembler.cpp Release builds. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145810 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Utils/AddrModeMatcher.cpp b/lib/Transforms/Utils/AddrModeMatcher.cpp index 8e5a1eb2c84..d83145289ce 100644 --- a/lib/Transforms/Utils/AddrModeMatcher.cpp +++ b/lib/Transforms/Utils/AddrModeMatcher.cpp @@ -473,14 +473,7 @@ bool AddressingModeMatcher::ValueAlreadyLiveAtInst(Value *Val,Value *KnownLive1, // Check to see if this value is already used in the memory instruction's // block. If so, it's already live into the block at the very least, so we // can reasonably fold it. - BasicBlock *MemBB = MemoryInst->getParent(); - for (Value::use_iterator UI = Val->use_begin(), E = Val->use_end(); - UI != E; ++UI) - // We know that uses of arguments and instructions have to be instructions. - if (cast(*UI)->getParent() == MemBB) - return true; - - return false; + return Val->isUsedInBasicBlock(MemoryInst->getParent()); } diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 291df917706..a5f1918e55d 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -108,6 +108,19 @@ bool Value::hasNUsesOrMore(unsigned N) const { /// isUsedInBasicBlock - Return true if this value is used in the specified /// basic block. bool Value::isUsedInBasicBlock(const BasicBlock *BB) const { + // Start by scanning over the instructions looking for a use before we start + // the expensive use iteration. + unsigned MaxBlockSize = 3; + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { + if (std::find(I->op_begin(), I->op_end(), this) != I->op_end()) + return true; + if (MaxBlockSize-- == 0) // If the block is larger fall back to use_iterator + break; + } + + if (MaxBlockSize != 0) // We scanned the entire block and found no use. + return false; + for (const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) { const Instruction *User = dyn_cast(*I); if (User && User->getParent() == BB)