mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 04:35:00 +00:00
Add support for simplifying a load from a computed value to a load from a global when it
is provable that they're equivalent. This fixes PR4855. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112994 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ac53061464
commit
1593dd6779
@ -452,14 +452,15 @@ LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) {
|
||||
|
||||
// If this is a pointer, and there's a load from that pointer in this BB,
|
||||
// then we know that the pointer can't be NULL.
|
||||
bool NotNull = false;
|
||||
if (Val->getType()->isPointerTy()) {
|
||||
const PointerType *PTy = cast<PointerType>(Val->getType());
|
||||
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();BI != BE;++BI){
|
||||
LoadInst *L = dyn_cast<LoadInst>(BI);
|
||||
if (L && L->getPointerAddressSpace() == 0 &&
|
||||
L->getPointerOperand()->getUnderlyingObject() ==
|
||||
Val->getUnderlyingObject()) {
|
||||
return LVILatticeVal::getNot(ConstantPointerNull::get(PTy));
|
||||
NotNull = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -475,11 +476,19 @@ LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) {
|
||||
if (Result.isOverdefined()) {
|
||||
DEBUG(dbgs() << " compute BB '" << BB->getName()
|
||||
<< "' - overdefined because of pred.\n");
|
||||
// If we previously determined that this is a pointer that can't be null
|
||||
// then return that rather than giving up entirely.
|
||||
if (NotNull) {
|
||||
const PointerType *PTy = cast<PointerType>(Val->getType());
|
||||
Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy));
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
++NumPreds;
|
||||
}
|
||||
|
||||
|
||||
// If this is the entry block, we must be asking about an argument. The
|
||||
// value is overdefined.
|
||||
if (NumPreds == 0 && BB == &BB->getParent()->front()) {
|
||||
|
@ -21,8 +21,9 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
using namespace llvm;
|
||||
|
||||
STATISTIC(NumPhis, "Number of phis propagated");
|
||||
STATISTIC(NumSelects, "Number of selects propagated");
|
||||
STATISTIC(NumPhis, "Number of phis propagated");
|
||||
STATISTIC(NumSelects, "Number of selects propagated");
|
||||
STATISTIC(NumMemAccess, "Number of memory access targets propagated");
|
||||
|
||||
namespace {
|
||||
class CorrelatedValuePropagation : public FunctionPass {
|
||||
@ -30,6 +31,7 @@ namespace {
|
||||
|
||||
bool processSelect(SelectInst *SI);
|
||||
bool processPHI(PHINode *P);
|
||||
bool processMemAccess(Instruction *I);
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
@ -54,6 +56,7 @@ Pass *llvm::createCorrelatedValuePropagationPass() {
|
||||
|
||||
bool CorrelatedValuePropagation::processSelect(SelectInst *S) {
|
||||
if (S->getType()->isVectorTy()) return false;
|
||||
if (isa<Constant>(S->getOperand(0))) return false;
|
||||
|
||||
Constant *C = LVI->getConstant(S->getOperand(0), S->getParent());
|
||||
if (!C) return false;
|
||||
@ -97,6 +100,23 @@ bool CorrelatedValuePropagation::processPHI(PHINode *P) {
|
||||
return Changed;
|
||||
}
|
||||
|
||||
bool CorrelatedValuePropagation::processMemAccess(Instruction *I) {
|
||||
Value *Pointer = 0;
|
||||
if (LoadInst *L = dyn_cast<LoadInst>(I))
|
||||
Pointer = L->getPointerOperand();
|
||||
else
|
||||
Pointer = cast<StoreInst>(I)->getPointerOperand();
|
||||
|
||||
if (isa<Constant>(Pointer)) return false;
|
||||
|
||||
Constant *C = LVI->getConstant(Pointer, I->getParent());
|
||||
if (!C) return false;
|
||||
|
||||
++NumMemAccess;
|
||||
I->replaceUsesOfWith(Pointer, C);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CorrelatedValuePropagation::runOnFunction(Function &F) {
|
||||
LVI = &getAnalysis<LazyValueInfo>();
|
||||
|
||||
@ -106,10 +126,18 @@ bool CorrelatedValuePropagation::runOnFunction(Function &F) {
|
||||
bool BBChanged = false;
|
||||
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) {
|
||||
Instruction *II = BI++;
|
||||
if (SelectInst *SI = dyn_cast<SelectInst>(II))
|
||||
BBChanged |= processSelect(SI);
|
||||
else if (PHINode *P = dyn_cast<PHINode>(II))
|
||||
BBChanged |= processPHI(P);
|
||||
switch (II->getOpcode()) {
|
||||
case Instruction::Select:
|
||||
BBChanged |= processSelect(cast<SelectInst>(II));
|
||||
break;
|
||||
case Instruction::PHI:
|
||||
BBChanged |= processPHI(cast<PHINode>(II));
|
||||
break;
|
||||
case Instruction::Load:
|
||||
case Instruction::Store:
|
||||
BBChanged |= processMemAccess(II);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Propagating correlated values might leave cruft around.
|
||||
|
@ -39,3 +39,21 @@ bb3: ; preds = %bb1
|
||||
; CHECK: ret i1 %res
|
||||
ret i1 %res
|
||||
}
|
||||
|
||||
; PR4855
|
||||
@gv = internal constant i8 7
|
||||
; CHECK: @test3
|
||||
define i8 @test3(i8* %a) nounwind {
|
||||
entry:
|
||||
%cond = icmp eq i8* %a, @gv
|
||||
br i1 %cond, label %bb2, label %bb
|
||||
|
||||
bb: ; preds = %entry
|
||||
ret i8 0
|
||||
|
||||
bb2: ; preds = %entry
|
||||
; CHECK-NOT: load i8* %a
|
||||
%should_be_const = load i8* %a
|
||||
; CHECK: ret i8 7
|
||||
ret i8 %should_be_const
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user