aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-07-29 03:27:26 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-07-29 03:27:26 +0000
commitd536f2328ededb3aae6563c721c6134c735f1918 (patch)
tree3d65c25e2093384cf070d6f3b8be9f9eaffbac78 /llvm/lib/Analysis/ConstantFolding.cpp
parentc7de3a101885c5b9b167a82b0be37dfb23551aa2 (diff)
downloadllvm-d536f2328ededb3aae6563c721c6134c735f1918.zip
llvm-d536f2328ededb3aae6563c721c6134c735f1918.tar.gz
llvm-d536f2328ededb3aae6563c721c6134c735f1918.tar.bz2
[ConstnatFolding] Teach the folder how to fold ConstantVector
A ConstantVector can have ConstantExpr operands and vice versa. However, the folder had no ability to fold ConstantVectors which, in some cases, was an optimization barrier. Instead, rephrase the folder in terms of Constants instead of ConstantExprs and teach callers how to deal with failure. llvm-svn: 277099
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp117
1 files changed, 60 insertions, 57 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 1a6a54b..7ee3e8c 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -714,10 +714,8 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops,
return nullptr;
Constant *C = ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], NewIdxs);
- if (auto *CE = dyn_cast<ConstantExpr>(C)) {
- if (Constant *Folded = ConstantFoldConstantExpression(CE, DL, TLI))
- C = Folded;
- }
+ if (Constant *Folded = ConstantFoldConstant(C, DL, TLI))
+ C = Folded;
return C;
}
@@ -775,10 +773,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
Constant *Res = ConstantExpr::getPtrToInt(Ptr, CE->getType());
Res = ConstantExpr::getSub(Res, CE->getOperand(1));
Res = ConstantExpr::getIntToPtr(Res, ResTy);
- if (auto *ResCE = dyn_cast<ConstantExpr>(Res))
- if (auto *FoldedRes =
- ConstantFoldConstantExpression(ResCE, DL, TLI))
- Res = FoldedRes;
+ if (auto *FoldedRes = ConstantFoldConstant(Res, DL, TLI))
+ Res = FoldedRes;
return Res;
}
}
@@ -968,12 +964,59 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, Type *DestTy,
// Constant Folding public APIs
//===----------------------------------------------------------------------===//
+namespace {
+
+Constant *
+ConstantFoldConstantImpl(const Constant *C, const DataLayout &DL,
+ const TargetLibraryInfo *TLI,
+ SmallDenseMap<Constant *, Constant *> &FoldedOps) {
+ if (!isa<ConstantVector>(C) && !isa<ConstantExpr>(C))
+ return nullptr;
+
+ SmallVector<Constant *, 8> Ops;
+ for (const Use &NewU : C->operands()) {
+ auto *NewC = cast<Constant>(&NewU);
+ // Recursively fold the ConstantExpr's operands. If we have already folded
+ // a ConstantExpr, we don't have to process it again.
+ if (isa<ConstantVector>(NewC) || isa<ConstantExpr>(NewC)) {
+ auto It = FoldedOps.find(NewC);
+ if (It == FoldedOps.end()) {
+ if (auto *FoldedC =
+ ConstantFoldConstantImpl(NewC, DL, TLI, FoldedOps)) {
+ NewC = FoldedC;
+ FoldedOps.insert({NewC, FoldedC});
+ } else {
+ FoldedOps.insert({NewC, NewC});
+ }
+ } else {
+ NewC = It->second;
+ }
+ }
+ Ops.push_back(NewC);
+ }
+
+ if (auto *CE = dyn_cast<ConstantExpr>(C)) {
+ if (CE->isCompare())
+ return ConstantFoldCompareInstOperands(CE->getPredicate(), Ops[0], Ops[1],
+ DL, TLI);
+
+ return ConstantFoldInstOperandsImpl(CE, CE->getType(), CE->getOpcode(), Ops,
+ DL, TLI);
+ }
+
+ assert(isa<ConstantVector>(C));
+ return ConstantVector::get(Ops);
+}
+
+} // end anonymous namespace
+
Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
const TargetLibraryInfo *TLI) {
// Handle PHI nodes quickly here...
if (auto *PN = dyn_cast<PHINode>(I)) {
Constant *CommonValue = nullptr;
+ SmallDenseMap<Constant *, Constant *> FoldedOps;
for (Value *Incoming : PN->incoming_values()) {
// If the incoming value is undef then skip it. Note that while we could
// skip the value if it is equal to the phi node itself we choose not to
@@ -986,9 +1029,8 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
if (!C)
return nullptr;
// Fold the PHI's operands.
- if (auto *NewC = dyn_cast<ConstantExpr>(C))
- if (auto *FoldedC = ConstantFoldConstantExpression(NewC, DL, TLI))
- C = FoldedC;
+ if (auto *FoldedC = ConstantFoldConstantImpl(C, DL, TLI, FoldedOps))
+ C = FoldedC;
// If the incoming value is a different constant to
// the one we saw previously, then give up.
if (CommonValue && C != CommonValue)
@@ -996,7 +1038,6 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
CommonValue = C;
}
-
// If we reach here, all incoming values are the same constant or undef.
return CommonValue ? CommonValue : UndefValue::get(PN->getType());
}
@@ -1006,13 +1047,13 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
if (!all_of(I->operands(), [](Use &U) { return isa<Constant>(U); }))
return nullptr;
+ SmallDenseMap<Constant *, Constant *> FoldedOps;
SmallVector<Constant *, 8> Ops;
for (const Use &OpU : I->operands()) {
auto *Op = cast<Constant>(&OpU);
// Fold the Instruction's operands.
- if (auto *NewCE = dyn_cast<ConstantExpr>(Op))
- if (auto *FoldedOp = ConstantFoldConstantExpression(NewCE, DL, TLI))
- Op = FoldedOp;
+ if (auto *FoldedOp = ConstantFoldConstantImpl(Op, DL, TLI, FoldedOps))
+ Op = FoldedOp;
Ops.push_back(Op);
}
@@ -1040,48 +1081,10 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
return ConstantFoldInstOperands(I, Ops, DL, TLI);
}
-namespace {
-
-Constant *ConstantFoldConstantExpressionImpl(
- const ConstantExpr *CE, const DataLayout &DL, const TargetLibraryInfo *TLI,
- SmallDenseMap<ConstantExpr *, Constant *> &FoldedOps) {
- SmallVector<Constant *, 8> Ops;
- for (const Use &NewU : CE->operands()) {
- auto *NewC = cast<Constant>(&NewU);
- // Recursively fold the ConstantExpr's operands. If we have already folded
- // a ConstantExpr, we don't have to process it again.
- if (auto *NewCE = dyn_cast<ConstantExpr>(NewC)) {
- auto It = FoldedOps.find(NewCE);
- if (It == FoldedOps.end()) {
- if (auto *FoldedC =
- ConstantFoldConstantExpressionImpl(NewCE, DL, TLI, FoldedOps)) {
- NewC = FoldedC;
- FoldedOps.insert({NewCE, FoldedC});
- } else {
- FoldedOps.insert({NewCE, NewCE});
- }
- } else {
- NewC = It->second;
- }
- }
- Ops.push_back(NewC);
- }
-
- if (CE->isCompare())
- return ConstantFoldCompareInstOperands(CE->getPredicate(), Ops[0], Ops[1],
- DL, TLI);
-
- return ConstantFoldInstOperandsImpl(CE, CE->getType(), CE->getOpcode(), Ops,
- DL, TLI);
-}
-
-} // end anonymous namespace
-
-Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI) {
- SmallDenseMap<ConstantExpr *, Constant *> FoldedOps;
- return ConstantFoldConstantExpressionImpl(CE, DL, TLI, FoldedOps);
+Constant *llvm::ConstantFoldConstant(const Constant *C, const DataLayout &DL,
+ const TargetLibraryInfo *TLI) {
+ SmallDenseMap<Constant *, Constant *> FoldedOps;
+ return ConstantFoldConstantImpl(C, DL, TLI, FoldedOps);
}
Constant *llvm::ConstantFoldInstOperands(Instruction *I,