mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
Generalize instcombine's isSafeToLoadUnconditionally() function
to ignore readonly calls, and factor it out of instcombine so that it can be used by other passes. Patch by Frits van Bommel! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73506 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
003263bb9f
commit
6cc8a93c48
@ -30,6 +30,16 @@ struct DbgInfoIntrinsic;
|
||||
|
||||
template<typename T> class SmallVectorImpl;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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 isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Local constant propagation.
|
||||
//
|
||||
|
@ -11419,45 +11419,6 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// 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.
|
||||
static bool 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 might do a free) the pointer could be
|
||||
// marked invalid.
|
||||
if (isa<FreeInst>(BBI) ||
|
||||
(isa<CallInst>(BBI) && !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;
|
||||
}
|
||||
|
||||
Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
||||
Value *Op = LI.getOperand(0);
|
||||
|
||||
|
@ -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"
|
||||
@ -27,6 +28,50 @@
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
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.
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user