mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +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,
|
// 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.
|
// then we know that the pointer can't be NULL.
|
||||||
|
bool NotNull = false;
|
||||||
if (Val->getType()->isPointerTy()) {
|
if (Val->getType()->isPointerTy()) {
|
||||||
const PointerType *PTy = cast<PointerType>(Val->getType());
|
|
||||||
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();BI != BE;++BI){
|
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();BI != BE;++BI){
|
||||||
LoadInst *L = dyn_cast<LoadInst>(BI);
|
LoadInst *L = dyn_cast<LoadInst>(BI);
|
||||||
if (L && L->getPointerAddressSpace() == 0 &&
|
if (L && L->getPointerAddressSpace() == 0 &&
|
||||||
L->getPointerOperand()->getUnderlyingObject() ==
|
L->getPointerOperand()->getUnderlyingObject() ==
|
||||||
Val->getUnderlyingObject()) {
|
Val->getUnderlyingObject()) {
|
||||||
return LVILatticeVal::getNot(ConstantPointerNull::get(PTy));
|
NotNull = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -475,11 +476,19 @@ LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) {
|
|||||||
if (Result.isOverdefined()) {
|
if (Result.isOverdefined()) {
|
||||||
DEBUG(dbgs() << " compute BB '" << BB->getName()
|
DEBUG(dbgs() << " compute BB '" << BB->getName()
|
||||||
<< "' - overdefined because of pred.\n");
|
<< "' - 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;
|
return Result;
|
||||||
}
|
}
|
||||||
++NumPreds;
|
++NumPreds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// If this is the entry block, we must be asking about an argument. The
|
// If this is the entry block, we must be asking about an argument. The
|
||||||
// value is overdefined.
|
// value is overdefined.
|
||||||
if (NumPreds == 0 && BB == &BB->getParent()->front()) {
|
if (NumPreds == 0 && BB == &BB->getParent()->front()) {
|
||||||
|
@ -21,8 +21,9 @@
|
|||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
STATISTIC(NumPhis, "Number of phis propagated");
|
STATISTIC(NumPhis, "Number of phis propagated");
|
||||||
STATISTIC(NumSelects, "Number of selects propagated");
|
STATISTIC(NumSelects, "Number of selects propagated");
|
||||||
|
STATISTIC(NumMemAccess, "Number of memory access targets propagated");
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class CorrelatedValuePropagation : public FunctionPass {
|
class CorrelatedValuePropagation : public FunctionPass {
|
||||||
@ -30,6 +31,7 @@ namespace {
|
|||||||
|
|
||||||
bool processSelect(SelectInst *SI);
|
bool processSelect(SelectInst *SI);
|
||||||
bool processPHI(PHINode *P);
|
bool processPHI(PHINode *P);
|
||||||
|
bool processMemAccess(Instruction *I);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static char ID;
|
static char ID;
|
||||||
@ -54,6 +56,7 @@ Pass *llvm::createCorrelatedValuePropagationPass() {
|
|||||||
|
|
||||||
bool CorrelatedValuePropagation::processSelect(SelectInst *S) {
|
bool CorrelatedValuePropagation::processSelect(SelectInst *S) {
|
||||||
if (S->getType()->isVectorTy()) return false;
|
if (S->getType()->isVectorTy()) return false;
|
||||||
|
if (isa<Constant>(S->getOperand(0))) return false;
|
||||||
|
|
||||||
Constant *C = LVI->getConstant(S->getOperand(0), S->getParent());
|
Constant *C = LVI->getConstant(S->getOperand(0), S->getParent());
|
||||||
if (!C) return false;
|
if (!C) return false;
|
||||||
@ -97,6 +100,23 @@ bool CorrelatedValuePropagation::processPHI(PHINode *P) {
|
|||||||
return Changed;
|
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) {
|
bool CorrelatedValuePropagation::runOnFunction(Function &F) {
|
||||||
LVI = &getAnalysis<LazyValueInfo>();
|
LVI = &getAnalysis<LazyValueInfo>();
|
||||||
|
|
||||||
@ -106,10 +126,18 @@ bool CorrelatedValuePropagation::runOnFunction(Function &F) {
|
|||||||
bool BBChanged = false;
|
bool BBChanged = false;
|
||||||
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) {
|
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) {
|
||||||
Instruction *II = BI++;
|
Instruction *II = BI++;
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(II))
|
switch (II->getOpcode()) {
|
||||||
BBChanged |= processSelect(SI);
|
case Instruction::Select:
|
||||||
else if (PHINode *P = dyn_cast<PHINode>(II))
|
BBChanged |= processSelect(cast<SelectInst>(II));
|
||||||
BBChanged |= processPHI(P);
|
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.
|
// Propagating correlated values might leave cruft around.
|
||||||
|
@ -39,3 +39,21 @@ bb3: ; preds = %bb1
|
|||||||
; CHECK: ret i1 %res
|
; CHECK: ret i1 %res
|
||||||
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