diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 45 | 
1 files changed, 45 insertions, 0 deletions
| diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 94483b816e3..c7fff548bca 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -14,6 +14,7 @@  #include "llvm/Transforms/Utils/Local.h"  #include "llvm/Constants.h" +#include "llvm/GlobalAlias.h"  #include "llvm/GlobalVariable.h"  #include "llvm/DerivedTypes.h"  #include "llvm/Instructions.h" @@ -28,6 +29,50 @@  using namespace llvm;  //===----------------------------------------------------------------------===// +//  Local analysis. +// + +/// isSafeToLoadUnconditionally - Return true if we know that executing a load +/// from this value cannot trap.  If it is not obviously safe to load from the +/// specified pointer, we do a quick local scan of the basic block containing +/// ScanFrom, to determine if the address is already accessed. +bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom) { +  // If it is an alloca it is always safe to load from. +  if (isa<AllocaInst>(V)) return true; + +  // If it is a global variable it is mostly safe to load from. +  if (const GlobalValue *GV = dyn_cast<GlobalVariable>(V)) +    // Don't try to evaluate aliases.  External weak GV can be null. +    return !isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage(); + +  // Otherwise, be a little bit agressive by scanning the local block where we +  // want to check to see if the pointer is already being loaded or stored +  // from/to.  If so, the previous load or store would have already trapped, +  // so there is no harm doing an extra load (also, CSE will later eliminate +  // the load entirely). +  BasicBlock::iterator BBI = ScanFrom, E = ScanFrom->getParent()->begin(); + +  while (BBI != E) { +    --BBI; + +    // If we see a free or a call which may write to memory (i.e. which might do +    // a free) the pointer could be marked invalid. +    if (isa<FreeInst>(BBI) ||  +        (isa<CallInst>(BBI) && BBI->mayWriteToMemory() && +         !isa<DbgInfoIntrinsic>(BBI))) +      return false; + +    if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) { +      if (LI->getOperand(0) == V) return true; +    } else if (StoreInst *SI = dyn_cast<StoreInst>(BBI)) { +      if (SI->getOperand(1) == V) return true; +    } +  } +  return false; +} + + +//===----------------------------------------------------------------------===//  //  Local constant propagation.  // | 

