diff options
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 117 |
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, |