mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
SimplifyCFG: Use existing constant folding logic when forming switch tables.
Both simpler and more powerful than the hand-rolled folding logic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194475 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
92e94a2ee4
commit
f681437cb0
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
#include "llvm/Analysis/ConstantFolding.h"
|
||||||
#include "llvm/Analysis/InstructionSimplify.h"
|
#include "llvm/Analysis/InstructionSimplify.h"
|
||||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||||
#include "llvm/Analysis/ValueTracking.h"
|
#include "llvm/Analysis/ValueTracking.h"
|
||||||
@ -3323,28 +3324,10 @@ static Constant *LookupConstant(Value *V,
|
|||||||
/// simple instructions such as binary operations where both operands are
|
/// simple instructions such as binary operations where both operands are
|
||||||
/// constant or can be replaced by constants from the ConstantPool. Returns the
|
/// constant or can be replaced by constants from the ConstantPool. Returns the
|
||||||
/// resulting constant on success, 0 otherwise.
|
/// resulting constant on success, 0 otherwise.
|
||||||
static Constant *ConstantFold(Instruction *I,
|
static Constant *
|
||||||
const SmallDenseMap<Value*, Constant*>& ConstantPool) {
|
ConstantFold(Instruction *I,
|
||||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) {
|
const SmallDenseMap<Value *, Constant *> &ConstantPool,
|
||||||
Constant *A = LookupConstant(BO->getOperand(0), ConstantPool);
|
const DataLayout *DL) {
|
||||||
if (!A)
|
|
||||||
return 0;
|
|
||||||
Constant *B = LookupConstant(BO->getOperand(1), ConstantPool);
|
|
||||||
if (!B)
|
|
||||||
return 0;
|
|
||||||
return ConstantExpr::get(BO->getOpcode(), A, B);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CmpInst *Cmp = dyn_cast<CmpInst>(I)) {
|
|
||||||
Constant *A = LookupConstant(I->getOperand(0), ConstantPool);
|
|
||||||
if (!A)
|
|
||||||
return 0;
|
|
||||||
Constant *B = LookupConstant(I->getOperand(1), ConstantPool);
|
|
||||||
if (!B)
|
|
||||||
return 0;
|
|
||||||
return ConstantExpr::getCompare(Cmp->getPredicate(), A, B);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SelectInst *Select = dyn_cast<SelectInst>(I)) {
|
if (SelectInst *Select = dyn_cast<SelectInst>(I)) {
|
||||||
Constant *A = LookupConstant(Select->getCondition(), ConstantPool);
|
Constant *A = LookupConstant(Select->getCondition(), ConstantPool);
|
||||||
if (!A)
|
if (!A)
|
||||||
@ -3356,14 +3339,19 @@ static Constant *ConstantFold(Instruction *I,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CastInst *Cast = dyn_cast<CastInst>(I)) {
|
SmallVector<Constant *, 4> COps;
|
||||||
Constant *A = LookupConstant(I->getOperand(0), ConstantPool);
|
for (unsigned N = 0, E = I->getNumOperands(); N != E; ++N) {
|
||||||
if (!A)
|
if (Constant *A = LookupConstant(I->getOperand(N), ConstantPool))
|
||||||
|
COps.push_back(A);
|
||||||
|
else
|
||||||
return 0;
|
return 0;
|
||||||
return ConstantExpr::getCast(Cast->getOpcode(), A, Cast->getDestTy());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if (CmpInst *Cmp = dyn_cast<CmpInst>(I))
|
||||||
|
return ConstantFoldCompareInstOperands(Cmp->getPredicate(), COps[0],
|
||||||
|
COps[1], DL);
|
||||||
|
|
||||||
|
return ConstantFoldInstOperands(I->getOpcode(), I->getType(), COps, DL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GetCaseResults - Try to determine the resulting constant values in phi nodes
|
/// GetCaseResults - Try to determine the resulting constant values in phi nodes
|
||||||
@ -3375,7 +3363,8 @@ GetCaseResults(SwitchInst *SI,
|
|||||||
ConstantInt *CaseVal,
|
ConstantInt *CaseVal,
|
||||||
BasicBlock *CaseDest,
|
BasicBlock *CaseDest,
|
||||||
BasicBlock **CommonDest,
|
BasicBlock **CommonDest,
|
||||||
SmallVectorImpl<std::pair<PHINode*,Constant*> > &Res) {
|
SmallVectorImpl<std::pair<PHINode *, Constant *> > &Res,
|
||||||
|
const DataLayout *DL) {
|
||||||
// The block from which we enter the common destination.
|
// The block from which we enter the common destination.
|
||||||
BasicBlock *Pred = SI->getParent();
|
BasicBlock *Pred = SI->getParent();
|
||||||
|
|
||||||
@ -3394,7 +3383,7 @@ GetCaseResults(SwitchInst *SI,
|
|||||||
} else if (isa<DbgInfoIntrinsic>(I)) {
|
} else if (isa<DbgInfoIntrinsic>(I)) {
|
||||||
// Skip debug intrinsic.
|
// Skip debug intrinsic.
|
||||||
continue;
|
continue;
|
||||||
} else if (Constant *C = ConstantFold(I, ConstantPool)) {
|
} else if (Constant *C = ConstantFold(I, ConstantPool, DL)) {
|
||||||
// Instruction is side-effect free and constant.
|
// Instruction is side-effect free and constant.
|
||||||
ConstantPool.insert(std::make_pair(I, C));
|
ConstantPool.insert(std::make_pair(I, C));
|
||||||
} else {
|
} else {
|
||||||
@ -3718,7 +3707,7 @@ static bool SwitchToLookupTable(SwitchInst *SI,
|
|||||||
typedef SmallVector<std::pair<PHINode*, Constant*>, 4> ResultsTy;
|
typedef SmallVector<std::pair<PHINode*, Constant*>, 4> ResultsTy;
|
||||||
ResultsTy Results;
|
ResultsTy Results;
|
||||||
if (!GetCaseResults(SI, CaseVal, CI.getCaseSuccessor(), &CommonDest,
|
if (!GetCaseResults(SI, CaseVal, CI.getCaseSuccessor(), &CommonDest,
|
||||||
Results))
|
Results, TD))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Append the result from this case to the list for each phi.
|
// Append the result from this case to the list for each phi.
|
||||||
@ -3732,7 +3721,7 @@ static bool SwitchToLookupTable(SwitchInst *SI,
|
|||||||
// Get the resulting values for the default case.
|
// Get the resulting values for the default case.
|
||||||
SmallVector<std::pair<PHINode*, Constant*>, 4> DefaultResultsList;
|
SmallVector<std::pair<PHINode*, Constant*>, 4> DefaultResultsList;
|
||||||
if (!GetCaseResults(SI, 0, SI->getDefaultDest(), &CommonDest,
|
if (!GetCaseResults(SI, 0, SI->getDefaultDest(), &CommonDest,
|
||||||
DefaultResultsList))
|
DefaultResultsList, TD))
|
||||||
return false;
|
return false;
|
||||||
for (size_t I = 0, E = DefaultResultsList.size(); I != E; ++I) {
|
for (size_t I = 0, E = DefaultResultsList.size(); I != E; ++I) {
|
||||||
PHINode *PHI = DefaultResultsList[I].first;
|
PHINode *PHI = DefaultResultsList[I].first;
|
||||||
|
@ -711,7 +711,7 @@ return:
|
|||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @cprop(i32 %x) {
|
define i32 @cprop(i32 %x, i32 %y) {
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 1, label %return
|
i32 1, label %return
|
||||||
@ -727,7 +727,8 @@ sw.bb1: br label %return
|
|||||||
|
|
||||||
sw.bb2:
|
sw.bb2:
|
||||||
%and = and i32 %x, 1
|
%and = and i32 %x, 1
|
||||||
%tobool = icmp ne i32 %and, 0
|
%and.ptr = inttoptr i32 %and to i8*
|
||||||
|
%tobool = icmp ne i8* %and.ptr, null
|
||||||
%cond = select i1 %tobool, i32 -123, i32 456
|
%cond = select i1 %tobool, i32 -123, i32 456
|
||||||
%sub = sub nsw i32 %x, %cond
|
%sub = sub nsw i32 %x, %cond
|
||||||
br label %return
|
br label %return
|
||||||
@ -735,13 +736,15 @@ sw.bb2:
|
|||||||
sw.bb3:
|
sw.bb3:
|
||||||
%trunc = trunc i32 %x to i8
|
%trunc = trunc i32 %x to i8
|
||||||
%sext = sext i8 %trunc to i32
|
%sext = sext i8 %trunc to i32
|
||||||
|
%select.i = icmp sgt i32 %sext, 0
|
||||||
|
%select = select i1 %select.i, i32 %sext, i32 %y
|
||||||
br label %return
|
br label %return
|
||||||
|
|
||||||
sw.default:
|
sw.default:
|
||||||
br label %return
|
br label %return
|
||||||
|
|
||||||
return:
|
return:
|
||||||
%retval.0 = phi i32 [ 123, %sw.default ], [ %sext, %sw.bb3 ], [ %sub, %sw.bb2 ], [ 42, %sw.bb1 ], [ 5, %entry ]
|
%retval.0 = phi i32 [ 123, %sw.default ], [ %select, %sw.bb3 ], [ %sub, %sw.bb2 ], [ 42, %sw.bb1 ], [ 5, %entry ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
|
||||||
; CHECK-LABEL: @cprop(
|
; CHECK-LABEL: @cprop(
|
||||||
|
Loading…
Reference in New Issue
Block a user