mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Propagate non-local comparisons. Fixes PR1757.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113025 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2429e2ac23
commit
597dad35b8
@ -17,6 +17,7 @@
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Analysis/LazyValueInfo.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
using namespace llvm;
|
||||
@ -24,6 +25,7 @@ using namespace llvm;
|
||||
STATISTIC(NumPhis, "Number of phis propagated");
|
||||
STATISTIC(NumSelects, "Number of selects propagated");
|
||||
STATISTIC(NumMemAccess, "Number of memory access targets propagated");
|
||||
STATISTIC(NumCmps, "Number of comparisons propagated");
|
||||
|
||||
namespace {
|
||||
class CorrelatedValuePropagation : public FunctionPass {
|
||||
@ -32,6 +34,7 @@ namespace {
|
||||
bool processSelect(SelectInst *SI);
|
||||
bool processPHI(PHINode *P);
|
||||
bool processMemAccess(Instruction *I);
|
||||
bool processCmp(CmpInst *C);
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
@ -117,6 +120,47 @@ bool CorrelatedValuePropagation::processMemAccess(Instruction *I) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// processCmp - If the value of this comparison could be determined locally,
|
||||
/// constant propagation would already have figured it out. Instead, walk
|
||||
/// the predecessors and statically evaluate the comparison based on information
|
||||
/// available on that edge. If a given static evaluation is true on ALL
|
||||
/// incoming edges, then it's true universally and we can simplify the compare.
|
||||
bool CorrelatedValuePropagation::processCmp(CmpInst *C) {
|
||||
Value *Op0 = C->getOperand(0);
|
||||
if (isa<Instruction>(Op0) &&
|
||||
cast<Instruction>(Op0)->getParent() == C->getParent())
|
||||
return false;
|
||||
|
||||
Constant *Op1 = dyn_cast<Constant>(C->getOperand(1));
|
||||
if (!Op1) return false;
|
||||
|
||||
pred_iterator PI = pred_begin(C->getParent()), PE = pred_end(C->getParent());
|
||||
if (PI == PE) return false;
|
||||
|
||||
LazyValueInfo::Tristate Result = LVI->getPredicateOnEdge(C->getPredicate(),
|
||||
C->getOperand(0), Op1, *PI, C->getParent());
|
||||
if (Result == LazyValueInfo::Unknown) return false;
|
||||
|
||||
++PI;
|
||||
while (PI != PE) {
|
||||
LazyValueInfo::Tristate Res = LVI->getPredicateOnEdge(C->getPredicate(),
|
||||
C->getOperand(0), Op1, *PI, C->getParent());
|
||||
if (Res != Result) return false;
|
||||
++PI;
|
||||
}
|
||||
|
||||
++NumCmps;
|
||||
|
||||
if (Result == LazyValueInfo::True)
|
||||
C->replaceAllUsesWith(ConstantInt::getTrue(C->getContext()));
|
||||
else
|
||||
C->replaceAllUsesWith(ConstantInt::getFalse(C->getContext()));
|
||||
|
||||
C->eraseFromParent();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CorrelatedValuePropagation::runOnFunction(Function &F) {
|
||||
LVI = &getAnalysis<LazyValueInfo>();
|
||||
|
||||
@ -133,6 +177,10 @@ bool CorrelatedValuePropagation::runOnFunction(Function &F) {
|
||||
case Instruction::PHI:
|
||||
BBChanged |= processPHI(cast<PHINode>(II));
|
||||
break;
|
||||
case Instruction::ICmp:
|
||||
case Instruction::FCmp:
|
||||
BBChanged |= processCmp(cast<CmpInst>(II));
|
||||
break;
|
||||
case Instruction::Load:
|
||||
case Instruction::Store:
|
||||
BBChanged |= processMemAccess(II);
|
||||
|
@ -57,3 +57,27 @@ bb2: ; preds = %entry
|
||||
; CHECK: ret i8 7
|
||||
ret i8 %should_be_const
|
||||
}
|
||||
|
||||
; PR1757
|
||||
; CHECK: @test4
|
||||
define i32 @test4(i32) {
|
||||
EntryBlock:
|
||||
; CHECK: icmp sgt i32 %0, 2
|
||||
%.demorgan = icmp sgt i32 %0, 2
|
||||
br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
|
||||
|
||||
GreaterThanTwo:
|
||||
; CHECK-NOT: icmp eq i32 %0, 2
|
||||
icmp eq i32 %0, 2
|
||||
; CHECK: br i1 false
|
||||
br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
|
||||
|
||||
NotTwoAndGreaterThanTwo:
|
||||
ret i32 2
|
||||
|
||||
Impossible:
|
||||
ret i32 1
|
||||
|
||||
LessThanOrEqualToTwo:
|
||||
ret i32 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user