Propagate TargetLibraryInfo throughout ConstantFolding.cpp and

InstructionSimplify.cpp.  Other fixups as needed.
Part of rdar://10500969

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145559 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chad Rosier 2011-12-01 03:08:23 +00:00
parent 66d004ef70
commit 618c1dbd29
17 changed files with 456 additions and 279 deletions

View File

@ -25,6 +25,7 @@ namespace llvm {
class ConstantExpr; class ConstantExpr;
class Instruction; class Instruction;
class TargetData; class TargetData;
class TargetLibraryInfo;
class Function; class Function;
class Type; class Type;
template<typename T> template<typename T>
@ -35,13 +36,15 @@ namespace llvm {
/// Note that this fails if not all of the operands are constant. Otherwise, /// Note that this fails if not all of the operands are constant. Otherwise,
/// this function can only fail when attempting to fold instructions like loads /// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form. /// and stores, which have no constant expression form.
Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0); Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression /// ConstantFoldConstantExpression - Attempt to fold the constant expression
/// using the specified TargetData. If successful, the constant result is /// using the specified TargetData. If successful, the constant result is
/// result is returned, if not, null is returned. /// result is returned, if not, null is returned.
Constant *ConstantFoldConstantExpression(const ConstantExpr *CE, Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
const TargetData *TD = 0); const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
/// specified operands. If successful, the constant result is returned, if not, /// specified operands. If successful, the constant result is returned, if not,
@ -51,7 +54,8 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
/// ///
Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy, Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops, ArrayRef<Constant *> Ops,
const TargetData *TD = 0); const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare /// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
/// instruction (icmp/fcmp) with the specified operands. If it fails, it /// instruction (icmp/fcmp) with the specified operands. If it fails, it
@ -59,7 +63,8 @@ Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
/// ///
Constant *ConstantFoldCompareInstOperands(unsigned Predicate, Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *LHS, Constant *RHS, Constant *LHS, Constant *RHS,
const TargetData *TD = 0); const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue /// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
/// instruction with the specified operands and indices. The constant result is /// instruction with the specified operands and indices. The constant result is
@ -83,8 +88,8 @@ bool canConstantFoldCallTo(const Function *F);
/// ConstantFoldCall - Attempt to constant fold a call to the specified function /// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful. /// with the specified arguments, returning null if unsuccessful.
Constant * Constant *ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands); const TargetLibraryInfo *TLI = 0);
} }
#endif #endif

View File

@ -24,95 +24,117 @@ namespace llvm {
class Instruction; class Instruction;
class Value; class Value;
class TargetData; class TargetData;
class TargetLibraryInfo;
template<typename T> template<typename T>
class ArrayRef; class ArrayRef;
/// SimplifyAddInst - Given operands for an Add, see if we can /// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const TargetData *TD = 0, const DominatorTree *DT = 0); const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySubInst - Given operands for a Sub, see if we can /// SimplifySubInst - Given operands for a Sub, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const TargetData *TD = 0, const DominatorTree *DT = 0); const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyMulInst - Given operands for a Mul, see if we can /// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyMulInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifyMulInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifySDivInst - Given operands for an SDiv, see if we can /// SimplifySDivInst - Given operands for an SDiv, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifySDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifySDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyUDivInst - Given operands for a UDiv, see if we can /// SimplifyUDivInst - Given operands for a UDiv, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifyUDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyFDivInst - Given operands for an FDiv, see if we can /// SimplifyFDivInst - Given operands for an FDiv, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifySRemInst - Given operands for an SRem, see if we can /// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyURemInst - Given operands for a URem, see if we can /// SimplifyURemInst - Given operands for a URem, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyURemInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifyURemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyFRemInst - Given operands for an FRem, see if we can /// SimplifyFRemInst - Given operands for an FRem, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyFRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifyFRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyShlInst - Given operands for a Shl, see if we can /// SimplifyShlInst - Given operands for a Shl, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
const TargetData *TD = 0, const DominatorTree *DT = 0); const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyLShrInst - Given operands for a LShr, see if we can /// SimplifyLShrInst - Given operands for a LShr, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact, Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetData *TD = 0, const DominatorTree *DT=0); const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAShrInst - Given operands for a AShr, see if we can /// SimplifyAShrInst - Given operands for a AShr, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetData *TD = 0, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyAndInst - Given operands for an And, see if we can /// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyOrInst - Given operands for an Or, see if we can /// SimplifyOrInst - Given operands for an Or, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyXorInst - Given operands for a Xor, see if we can /// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyXorInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifyXorInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
@ -123,8 +145,8 @@ namespace llvm {
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyGEPInst(ArrayRef<Value *> Ops, Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const TargetData *TD = 0,
const TargetData *TD = 0, const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we /// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we
/// can fold the result. If not, this returns null. /// can fold the result. If not, this returns null.
@ -139,16 +161,21 @@ namespace llvm {
/// SimplifyCmpInst - Given operands for a CmpInst, see if we can /// SimplifyCmpInst - Given operands for a CmpInst, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0, const DominatorTree *DT = 0); const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
const TargetData *TD = 0, const DominatorTree *DT = 0); const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyInstruction - See if we can compute a simplified version of this /// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null. /// instruction. If not, this returns null.
Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0, Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
@ -160,6 +187,7 @@ namespace llvm {
/// ///
void ReplaceAndSimplifyAllUses(Instruction *From, Value *To, void ReplaceAndSimplifyAllUses(Instruction *From, Value *To,
const TargetData *TD = 0, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
} // end namespace llvm } // end namespace llvm

View File

@ -20,6 +20,7 @@
namespace llvm { namespace llvm {
class DominatorTree; class DominatorTree;
class TargetData; class TargetData;
class TargetLibraryInfo;
/// PHITransAddr - An address value which tracks and handles phi translation. /// PHITransAddr - An address value which tracks and handles phi translation.
/// As we walk "up" the CFG through predecessors, we need to ensure that the /// As we walk "up" the CFG through predecessors, we need to ensure that the
@ -38,10 +39,13 @@ class PHITransAddr {
/// TD - The target data we are playing with if known, otherwise null. /// TD - The target data we are playing with if known, otherwise null.
const TargetData *TD; const TargetData *TD;
/// TLI - The target library info if known, otherwise null.
const TargetLibraryInfo *TLI;
/// InstInputs - The inputs for our symbolic address. /// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs; SmallVector<Instruction*, 4> InstInputs;
public: public:
PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td) { PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td), TLI(0) {
// If the address is an instruction, the whole thing is considered an input. // If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr)) if (Instruction *I = dyn_cast<Instruction>(Addr))
InstInputs.push_back(I); InstInputs.push_back(I);

View File

@ -41,6 +41,7 @@ namespace llvm {
class Type; class Type;
class ScalarEvolution; class ScalarEvolution;
class TargetData; class TargetData;
class TargetLibraryInfo;
class LLVMContext; class LLVMContext;
class Loop; class Loop;
class LoopInfo; class LoopInfo;
@ -224,6 +225,10 @@ namespace llvm {
/// ///
TargetData *TD; TargetData *TD;
/// TLI - The target library information for the target we are targeting.
///
TargetLibraryInfo *TLI;
/// DT - The dominator tree. /// DT - The dominator tree.
/// ///
DominatorTree *DT; DominatorTree *DT;

View File

@ -26,6 +26,7 @@
#include "llvm/Operator.h" #include "llvm/Operator.h"
#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueTracking.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
@ -542,8 +543,8 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
/// explicitly cast them so that they aren't implicitly casted by the /// explicitly cast them so that they aren't implicitly casted by the
/// getelementptr. /// getelementptr.
static Constant *CastGEPIndices(ArrayRef<Constant *> Ops, static Constant *CastGEPIndices(ArrayRef<Constant *> Ops,
Type *ResultTy, Type *ResultTy, const TargetData *TD,
const TargetData *TD) { const TargetLibraryInfo *TLI) {
if (!TD) return 0; if (!TD) return 0;
Type *IntPtrTy = TD->getIntPtrType(ResultTy->getContext()); Type *IntPtrTy = TD->getIntPtrType(ResultTy->getContext());
@ -568,7 +569,7 @@ static Constant *CastGEPIndices(ArrayRef<Constant *> Ops,
Constant *C = Constant *C =
ConstantExpr::getGetElementPtr(Ops[0], NewIdxs); ConstantExpr::getGetElementPtr(Ops[0], NewIdxs);
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) if (Constant *Folded = ConstantFoldConstantExpression(CE, TD, TLI))
C = Folded; C = Folded;
return C; return C;
} }
@ -576,8 +577,8 @@ static Constant *CastGEPIndices(ArrayRef<Constant *> Ops,
/// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP /// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP
/// constant expression, do so. /// constant expression, do so.
static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops, static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
Type *ResultTy, Type *ResultTy, const TargetData *TD,
const TargetData *TD) { const TargetLibraryInfo *TLI) {
Constant *Ptr = Ops[0]; Constant *Ptr = Ops[0];
if (!TD || !cast<PointerType>(Ptr->getType())->getElementType()->isSized()) if (!TD || !cast<PointerType>(Ptr->getType())->getElementType()->isSized())
return 0; return 0;
@ -602,7 +603,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
Res = ConstantExpr::getSub(Res, CE->getOperand(1)); Res = ConstantExpr::getSub(Res, CE->getOperand(1));
Res = ConstantExpr::getIntToPtr(Res, ResultTy); Res = ConstantExpr::getIntToPtr(Res, ResultTy);
if (ConstantExpr *ResCE = dyn_cast<ConstantExpr>(Res)) if (ConstantExpr *ResCE = dyn_cast<ConstantExpr>(Res))
Res = ConstantFoldConstantExpression(ResCE, TD); Res = ConstantFoldConstantExpression(ResCE, TD, TLI);
return Res; return Res;
} }
} }
@ -729,7 +730,9 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
/// Note that this fails if not all of the operands are constant. Otherwise, /// Note that this fails if not all of the operands are constant. Otherwise,
/// this function can only fail when attempting to fold instructions like loads /// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form. /// and stores, which have no constant expression form.
Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) { Constant *llvm::ConstantFoldInstruction(Instruction *I,
const TargetData *TD,
const TargetLibraryInfo *TLI) {
// Handle PHI nodes quickly here... // Handle PHI nodes quickly here...
if (PHINode *PN = dyn_cast<PHINode>(I)) { if (PHINode *PN = dyn_cast<PHINode>(I)) {
Constant *CommonValue = 0; Constant *CommonValue = 0;
@ -765,7 +768,7 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
if (const CmpInst *CI = dyn_cast<CmpInst>(I)) if (const CmpInst *CI = dyn_cast<CmpInst>(I))
return ConstantFoldCompareInstOperands(CI->getPredicate(), Ops[0], Ops[1], return ConstantFoldCompareInstOperands(CI->getPredicate(), Ops[0], Ops[1],
TD); TD, TLI);
if (const LoadInst *LI = dyn_cast<LoadInst>(I)) if (const LoadInst *LI = dyn_cast<LoadInst>(I))
return ConstantFoldLoadInst(LI, TD); return ConstantFoldLoadInst(LI, TD);
@ -781,28 +784,29 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
cast<Constant>(EVI->getAggregateOperand()), cast<Constant>(EVI->getAggregateOperand()),
EVI->getIndices()); EVI->getIndices());
return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops, TD); return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops, TD, TLI);
} }
/// ConstantFoldConstantExpression - Attempt to fold the constant expression /// ConstantFoldConstantExpression - Attempt to fold the constant expression
/// using the specified TargetData. If successful, the constant result is /// using the specified TargetData. If successful, the constant result is
/// result is returned, if not, null is returned. /// result is returned, if not, null is returned.
Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE, Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE,
const TargetData *TD) { const TargetData *TD,
const TargetLibraryInfo *TLI) {
SmallVector<Constant*, 8> Ops; SmallVector<Constant*, 8> Ops;
for (User::const_op_iterator i = CE->op_begin(), e = CE->op_end(); for (User::const_op_iterator i = CE->op_begin(), e = CE->op_end();
i != e; ++i) { i != e; ++i) {
Constant *NewC = cast<Constant>(*i); Constant *NewC = cast<Constant>(*i);
// Recursively fold the ConstantExpr's operands. // Recursively fold the ConstantExpr's operands.
if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC)) if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC))
NewC = ConstantFoldConstantExpression(NewCE, TD); NewC = ConstantFoldConstantExpression(NewCE, TD, TLI);
Ops.push_back(NewC); Ops.push_back(NewC);
} }
if (CE->isCompare()) if (CE->isCompare())
return ConstantFoldCompareInstOperands(CE->getPredicate(), Ops[0], Ops[1], return ConstantFoldCompareInstOperands(CE->getPredicate(), Ops[0], Ops[1],
TD); TD, TLI);
return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(), Ops, TD); return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(), Ops, TD, TLI);
} }
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
@ -817,7 +821,8 @@ Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE,
/// ///
Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy, Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops, ArrayRef<Constant *> Ops,
const TargetData *TD) { const TargetData *TD,
const TargetLibraryInfo *TLI) {
// Handle easy binops first. // Handle easy binops first.
if (Instruction::isBinaryOp(Opcode)) { if (Instruction::isBinaryOp(Opcode)) {
if (isa<ConstantExpr>(Ops[0]) || isa<ConstantExpr>(Ops[1])) if (isa<ConstantExpr>(Ops[0]) || isa<ConstantExpr>(Ops[1]))
@ -834,7 +839,7 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
case Instruction::Call: case Instruction::Call:
if (Function *F = dyn_cast<Function>(Ops.back())) if (Function *F = dyn_cast<Function>(Ops.back()))
if (canConstantFoldCallTo(F)) if (canConstantFoldCallTo(F))
return ConstantFoldCall(F, Ops.slice(0, Ops.size() - 1)); return ConstantFoldCall(F, Ops.slice(0, Ops.size() - 1), TLI);
return 0; return 0;
case Instruction::PtrToInt: case Instruction::PtrToInt:
// If the input is a inttoptr, eliminate the pair. This requires knowing // If the input is a inttoptr, eliminate the pair. This requires knowing
@ -888,9 +893,9 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
case Instruction::ShuffleVector: case Instruction::ShuffleVector:
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
case Instruction::GetElementPtr: case Instruction::GetElementPtr:
if (Constant *C = CastGEPIndices(Ops, DestTy, TD)) if (Constant *C = CastGEPIndices(Ops, DestTy, TD, TLI))
return C; return C;
if (Constant *C = SymbolicallyEvaluateGEP(Ops, DestTy, TD)) if (Constant *C = SymbolicallyEvaluateGEP(Ops, DestTy, TD, TLI))
return C; return C;
return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1)); return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1));
@ -903,7 +908,8 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
/// ///
Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate, Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *Ops0, Constant *Ops1, Constant *Ops0, Constant *Ops1,
const TargetData *TD) { const TargetData *TD,
const TargetLibraryInfo *TLI) {
// fold: icmp (inttoptr x), null -> icmp x, 0 // fold: icmp (inttoptr x), null -> icmp x, 0
// fold: icmp (ptrtoint x), 0 -> icmp x, null // fold: icmp (ptrtoint x), 0 -> icmp x, null
// fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y // fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y
@ -920,7 +926,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *C = ConstantExpr::getIntegerCast(CE0->getOperand(0), Constant *C = ConstantExpr::getIntegerCast(CE0->getOperand(0),
IntPtrTy, false); IntPtrTy, false);
Constant *Null = Constant::getNullValue(C->getType()); Constant *Null = Constant::getNullValue(C->getType());
return ConstantFoldCompareInstOperands(Predicate, C, Null, TD); return ConstantFoldCompareInstOperands(Predicate, C, Null, TD, TLI);
} }
// Only do this transformation if the int is intptrty in size, otherwise // Only do this transformation if the int is intptrty in size, otherwise
@ -929,7 +935,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
CE0->getType() == IntPtrTy) { CE0->getType() == IntPtrTy) {
Constant *C = CE0->getOperand(0); Constant *C = CE0->getOperand(0);
Constant *Null = Constant::getNullValue(C->getType()); Constant *Null = Constant::getNullValue(C->getType());
return ConstantFoldCompareInstOperands(Predicate, C, Null, TD); return ConstantFoldCompareInstOperands(Predicate, C, Null, TD, TLI);
} }
} }
@ -944,7 +950,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
IntPtrTy, false); IntPtrTy, false);
Constant *C1 = ConstantExpr::getIntegerCast(CE1->getOperand(0), Constant *C1 = ConstantExpr::getIntegerCast(CE1->getOperand(0),
IntPtrTy, false); IntPtrTy, false);
return ConstantFoldCompareInstOperands(Predicate, C0, C1, TD); return ConstantFoldCompareInstOperands(Predicate, C0, C1, TD, TLI);
} }
// Only do this transformation if the int is intptrty in size, otherwise // Only do this transformation if the int is intptrty in size, otherwise
@ -953,7 +959,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
CE0->getType() == IntPtrTy && CE0->getType() == IntPtrTy &&
CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType())) CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType()))
return ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(0), return ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(0),
CE1->getOperand(0), TD); CE1->getOperand(0), TD, TLI);
} }
} }
@ -962,13 +968,15 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
if ((Predicate == ICmpInst::ICMP_EQ || Predicate == ICmpInst::ICMP_NE) && if ((Predicate == ICmpInst::ICMP_EQ || Predicate == ICmpInst::ICMP_NE) &&
CE0->getOpcode() == Instruction::Or && Ops1->isNullValue()) { CE0->getOpcode() == Instruction::Or && Ops1->isNullValue()) {
Constant *LHS = Constant *LHS =
ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(0), Ops1,TD); ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(0), Ops1,
TD, TLI);
Constant *RHS = Constant *RHS =
ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(1), Ops1,TD); ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(1), Ops1,
TD, TLI);
unsigned OpC = unsigned OpC =
Predicate == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or; Predicate == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;
Constant *Ops[] = { LHS, RHS }; Constant *Ops[] = { LHS, RHS };
return ConstantFoldInstOperands(OpC, LHS->getType(), Ops, TD); return ConstantFoldInstOperands(OpC, LHS->getType(), Ops, TD, TLI);
} }
} }
@ -1168,7 +1176,8 @@ static Constant *ConstantFoldConvertToInt(ConstantFP *Op, bool roundTowardZero,
/// ConstantFoldCall - Attempt to constant fold a call to the specified function /// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful. /// with the specified arguments, returning null if unsuccessful.
Constant * Constant *
llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands) { llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI) {
if (!F->hasName()) return 0; if (!F->hasName()) return 0;
StringRef Name = F->getName(); StringRef Name = F->getName();

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,7 @@
#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueTracking.h"
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/PassManager.h" #include "llvm/PassManager.h"
#include "llvm/IntrinsicInst.h" #include "llvm/IntrinsicInst.h"
@ -103,6 +104,7 @@ namespace {
AliasAnalysis *AA; AliasAnalysis *AA;
DominatorTree *DT; DominatorTree *DT;
TargetData *TD; TargetData *TD;
TargetLibraryInfo *TLI;
std::string Messages; std::string Messages;
raw_string_ostream MessagesStr; raw_string_ostream MessagesStr;
@ -117,6 +119,7 @@ namespace {
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll(); AU.setPreservesAll();
AU.addRequired<AliasAnalysis>(); AU.addRequired<AliasAnalysis>();
AU.addRequired<TargetLibraryInfo>();
AU.addRequired<DominatorTree>(); AU.addRequired<DominatorTree>();
} }
virtual void print(raw_ostream &O, const Module *M) const {} virtual void print(raw_ostream &O, const Module *M) const {}
@ -149,6 +152,7 @@ namespace {
char Lint::ID = 0; char Lint::ID = 0;
INITIALIZE_PASS_BEGIN(Lint, "lint", "Statically lint-checks LLVM IR", INITIALIZE_PASS_BEGIN(Lint, "lint", "Statically lint-checks LLVM IR",
false, true) false, true)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
INITIALIZE_PASS_END(Lint, "lint", "Statically lint-checks LLVM IR", INITIALIZE_PASS_END(Lint, "lint", "Statically lint-checks LLVM IR",
@ -174,6 +178,7 @@ bool Lint::runOnFunction(Function &F) {
AA = &getAnalysis<AliasAnalysis>(); AA = &getAnalysis<AliasAnalysis>();
DT = &getAnalysis<DominatorTree>(); DT = &getAnalysis<DominatorTree>();
TD = getAnalysisIfAvailable<TargetData>(); TD = getAnalysisIfAvailable<TargetData>();
TLI = &getAnalysis<TargetLibraryInfo>();
visit(F); visit(F);
dbgs() << MessagesStr.str(); dbgs() << MessagesStr.str();
Messages.clear(); Messages.clear();
@ -614,7 +619,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
// As a last resort, try SimplifyInstruction or constant folding. // As a last resort, try SimplifyInstruction or constant folding.
if (Instruction *Inst = dyn_cast<Instruction>(V)) { if (Instruction *Inst = dyn_cast<Instruction>(V)) {
if (Value *W = SimplifyInstruction(Inst, TD, DT)) if (Value *W = SimplifyInstruction(Inst, TD, TLI, DT))
return findValueImpl(W, OffsetOk, Visited); return findValueImpl(W, OffsetOk, Visited);
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
if (Value *W = ConstantFoldConstantExpression(CE, TD)) if (Value *W = ConstantFoldConstantExpression(CE, TD))

View File

@ -284,7 +284,7 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
} }
// See if the add simplifies away. // See if the add simplifies away.
if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD, DT)) { if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD, TLI, DT)) {
// If we simplified the operands, the LHS is no longer an input, but Res // If we simplified the operands, the LHS is no longer an input, but Res
// is. // is.
RemoveInstInputs(LHS, InstInputs); RemoveInstInputs(LHS, InstInputs);

View File

@ -74,6 +74,7 @@
#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueTracking.h"
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/ConstantRange.h" #include "llvm/Support/ConstantRange.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
@ -108,6 +109,7 @@ INITIALIZE_PASS_BEGIN(ScalarEvolution, "scalar-evolution",
"Scalar Evolution Analysis", false, true) "Scalar Evolution Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(LoopInfo) INITIALIZE_PASS_DEPENDENCY(LoopInfo)
INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
INITIALIZE_PASS_END(ScalarEvolution, "scalar-evolution", INITIALIZE_PASS_END(ScalarEvolution, "scalar-evolution",
"Scalar Evolution Analysis", false, true) "Scalar Evolution Analysis", false, true)
char ScalarEvolution::ID = 0; char ScalarEvolution::ID = 0;
@ -3116,7 +3118,7 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
// PHI's incoming blocks are in a different loop, in which case doing so // PHI's incoming blocks are in a different loop, in which case doing so
// risks breaking LCSSA form. Instcombine would normally zap these, but // risks breaking LCSSA form. Instcombine would normally zap these, but
// it doesn't have DominatorTree information, so it may miss cases. // it doesn't have DominatorTree information, so it may miss cases.
if (Value *V = SimplifyInstruction(PN, TD, DT)) if (Value *V = SimplifyInstruction(PN, TD, TLI, DT))
if (LI->replacementPreservesLCSSAForm(PN, V)) if (LI->replacementPreservesLCSSAForm(PN, V))
return getSCEV(V); return getSCEV(V);
@ -6560,6 +6562,7 @@ bool ScalarEvolution::runOnFunction(Function &F) {
this->F = &F; this->F = &F;
LI = &getAnalysis<LoopInfo>(); LI = &getAnalysis<LoopInfo>();
TD = getAnalysisIfAvailable<TargetData>(); TD = getAnalysisIfAvailable<TargetData>();
TLI = &getAnalysis<TargetLibraryInfo>();
DT = &getAnalysis<DominatorTree>(); DT = &getAnalysis<DominatorTree>();
return false; return false;
} }
@ -6596,6 +6599,7 @@ void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll(); AU.setPreservesAll();
AU.addRequiredTransitive<LoopInfo>(); AU.addRequiredTransitive<LoopInfo>();
AU.addRequiredTransitive<DominatorTree>(); AU.addRequiredTransitive<DominatorTree>();
AU.addRequired<TargetLibraryInfo>();
} }
bool ScalarEvolution::hasLoopInvariantBackedgeTakenCount(const Loop *L) { bool ScalarEvolution::hasLoopInvariantBackedgeTakenCount(const Loop *L) {

View File

@ -26,6 +26,7 @@
#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ProfileInfo.h" #include "llvm/Analysis/ProfileInfo.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLowering.h"
#include "llvm/Transforms/Utils/AddrModeMatcher.h" #include "llvm/Transforms/Utils/AddrModeMatcher.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h"
@ -69,6 +70,7 @@ namespace {
/// TLI - Keep a pointer of a TargetLowering to consult for determining /// TLI - Keep a pointer of a TargetLowering to consult for determining
/// transformation profitability. /// transformation profitability.
const TargetLowering *TLI; const TargetLowering *TLI;
const TargetLibraryInfo *TLInfo;
DominatorTree *DT; DominatorTree *DT;
ProfileInfo *PFI; ProfileInfo *PFI;
@ -97,6 +99,7 @@ namespace {
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<DominatorTree>(); AU.addPreserved<DominatorTree>();
AU.addPreserved<ProfileInfo>(); AU.addPreserved<ProfileInfo>();
AU.addRequired<TargetLibraryInfo>();
} }
private: private:
@ -116,7 +119,10 @@ namespace {
} }
char CodeGenPrepare::ID = 0; char CodeGenPrepare::ID = 0;
INITIALIZE_PASS(CodeGenPrepare, "codegenprepare", INITIALIZE_PASS_BEGIN(CodeGenPrepare, "codegenprepare",
"Optimize for code generation", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
INITIALIZE_PASS_END(CodeGenPrepare, "codegenprepare",
"Optimize for code generation", false, false) "Optimize for code generation", false, false)
FunctionPass *llvm::createCodeGenPreparePass(const TargetLowering *TLI) { FunctionPass *llvm::createCodeGenPreparePass(const TargetLowering *TLI) {
@ -127,6 +133,7 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
bool EverMadeChange = false; bool EverMadeChange = false;
ModifiedDT = false; ModifiedDT = false;
TLInfo = &getAnalysis<TargetLibraryInfo>();
DT = getAnalysisIfAvailable<DominatorTree>(); DT = getAnalysisIfAvailable<DominatorTree>();
PFI = getAnalysisIfAvailable<ProfileInfo>(); PFI = getAnalysisIfAvailable<ProfileInfo>();
@ -542,7 +549,7 @@ bool CodeGenPrepare::OptimizeCallInst(CallInst *CI) {
WeakVH IterHandle(CurInstIterator); WeakVH IterHandle(CurInstIterator);
ReplaceAndSimplifyAllUses(CI, RetVal, TLI ? TLI->getTargetData() : 0, ReplaceAndSimplifyAllUses(CI, RetVal, TLI ? TLI->getTargetData() : 0,
ModifiedDT ? 0 : DT); TLInfo, ModifiedDT ? 0 : DT);
// If the iterator instruction was recursively deleted, start over at the // If the iterator instruction was recursively deleted, start over at the
// start of the block. // start of the block.

View File

@ -19,6 +19,7 @@
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/RecyclingAllocator.h" #include "llvm/Support/RecyclingAllocator.h"
@ -215,6 +216,7 @@ namespace {
class EarlyCSE : public FunctionPass { class EarlyCSE : public FunctionPass {
public: public:
const TargetData *TD; const TargetData *TD;
const TargetLibraryInfo *TLI;
DominatorTree *DT; DominatorTree *DT;
typedef RecyclingAllocator<BumpPtrAllocator, typedef RecyclingAllocator<BumpPtrAllocator,
ScopedHashTableVal<SimpleValue, Value*> > AllocatorTy; ScopedHashTableVal<SimpleValue, Value*> > AllocatorTy;
@ -263,6 +265,7 @@ private:
// This transformation requires dominator postdominator info // This transformation requires dominator postdominator info
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<DominatorTree>(); AU.addRequired<DominatorTree>();
AU.addRequired<TargetLibraryInfo>();
AU.setPreservesCFG(); AU.setPreservesCFG();
} }
}; };
@ -277,6 +280,7 @@ FunctionPass *llvm::createEarlyCSEPass() {
INITIALIZE_PASS_BEGIN(EarlyCSE, "early-cse", "Early CSE", false, false) INITIALIZE_PASS_BEGIN(EarlyCSE, "early-cse", "Early CSE", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
INITIALIZE_PASS_END(EarlyCSE, "early-cse", "Early CSE", false, false) INITIALIZE_PASS_END(EarlyCSE, "early-cse", "Early CSE", false, false)
bool EarlyCSE::processNode(DomTreeNode *Node) { bool EarlyCSE::processNode(DomTreeNode *Node) {
@ -328,7 +332,7 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
// If the instruction can be simplified (e.g. X+0 = X) then replace it with // If the instruction can be simplified (e.g. X+0 = X) then replace it with
// its simpler value. // its simpler value.
if (Value *V = SimplifyInstruction(Inst, TD, DT)) { if (Value *V = SimplifyInstruction(Inst, TD, TLI, DT)) {
DEBUG(dbgs() << "EarlyCSE Simplify: " << *Inst << " to: " << *V << '\n'); DEBUG(dbgs() << "EarlyCSE Simplify: " << *Inst << " to: " << *V << '\n');
Inst->replaceAllUsesWith(V); Inst->replaceAllUsesWith(V);
Inst->eraseFromParent(); Inst->eraseFromParent();
@ -455,6 +459,7 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
bool EarlyCSE::runOnFunction(Function &F) { bool EarlyCSE::runOnFunction(Function &F) {
TD = getAnalysisIfAvailable<TargetData>(); TD = getAnalysisIfAvailable<TargetData>();
TLI = &getAnalysis<TargetLibraryInfo>();
DT = &getAnalysis<DominatorTree>(); DT = &getAnalysis<DominatorTree>();
// Tables that the pass uses when walking the domtree. // Tables that the pass uses when walking the domtree.

View File

@ -31,6 +31,7 @@
#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueTracking.h"
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
@ -446,6 +447,7 @@ namespace {
MemoryDependenceAnalysis *MD; MemoryDependenceAnalysis *MD;
DominatorTree *DT; DominatorTree *DT;
const TargetData *TD; const TargetData *TD;
const TargetLibraryInfo *TLI;
ValueTable VN; ValueTable VN;
@ -530,6 +532,7 @@ namespace {
// This transformation requires dominator postdominator info // This transformation requires dominator postdominator info
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<DominatorTree>(); AU.addRequired<DominatorTree>();
AU.addRequired<TargetLibraryInfo>();
if (!NoLoads) if (!NoLoads)
AU.addRequired<MemoryDependenceAnalysis>(); AU.addRequired<MemoryDependenceAnalysis>();
AU.addRequired<AliasAnalysis>(); AU.addRequired<AliasAnalysis>();
@ -568,6 +571,7 @@ FunctionPass *llvm::createGVNPass(bool NoLoads) {
INITIALIZE_PASS_BEGIN(GVN, "gvn", "Global Value Numbering", false, false) INITIALIZE_PASS_BEGIN(GVN, "gvn", "Global Value Numbering", false, false)
INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis) INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis)
INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
INITIALIZE_PASS_END(GVN, "gvn", "Global Value Numbering", false, false) INITIALIZE_PASS_END(GVN, "gvn", "Global Value Numbering", false, false)
@ -2032,7 +2036,7 @@ bool GVN::processInstruction(Instruction *I) {
// to value numbering it. Value numbering often exposes redundancies, for // to value numbering it. Value numbering often exposes redundancies, for
// example if it determines that %y is equal to %x then the instruction // example if it determines that %y is equal to %x then the instruction
// "%z = and i32 %x, %y" becomes "%z = and i32 %x, %x" which we now simplify. // "%z = and i32 %x, %y" becomes "%z = and i32 %x, %x" which we now simplify.
if (Value *V = SimplifyInstruction(I, TD, DT)) { if (Value *V = SimplifyInstruction(I, TD, TLI, DT)) {
I->replaceAllUsesWith(V); I->replaceAllUsesWith(V);
if (MD && V->getType()->isPointerTy()) if (MD && V->getType()->isPointerTy())
MD->invalidateCachedPointerInfo(V); MD->invalidateCachedPointerInfo(V);
@ -2134,6 +2138,7 @@ bool GVN::runOnFunction(Function& F) {
MD = &getAnalysis<MemoryDependenceAnalysis>(); MD = &getAnalysis<MemoryDependenceAnalysis>();
DT = &getAnalysis<DominatorTree>(); DT = &getAnalysis<DominatorTree>();
TD = getAnalysisIfAvailable<TargetData>(); TD = getAnalysisIfAvailable<TargetData>();
TLI = &getAnalysis<TargetLibraryInfo>();
VN.setAliasAnalysis(&getAnalysis<AliasAnalysis>()); VN.setAliasAnalysis(&getAnalysis<AliasAnalysis>());
VN.setMemDep(MD); VN.setMemDep(MD);
VN.setDomTree(DT); VN.setDomTree(DT);

View File

@ -19,6 +19,7 @@
#include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
@ -43,6 +44,7 @@ namespace {
AU.addPreservedID(LoopSimplifyID); AU.addPreservedID(LoopSimplifyID);
AU.addPreservedID(LCSSAID); AU.addPreservedID(LCSSAID);
AU.addPreserved("scalar-evolution"); AU.addPreserved("scalar-evolution");
AU.addRequired<TargetLibraryInfo>();
} }
}; };
} }
@ -50,6 +52,7 @@ namespace {
char LoopInstSimplify::ID = 0; char LoopInstSimplify::ID = 0;
INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify", INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify",
"Simplify instructions in loops", false, false) "Simplify instructions in loops", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_DEPENDENCY(LoopInfo) INITIALIZE_PASS_DEPENDENCY(LoopInfo)
INITIALIZE_PASS_DEPENDENCY(LCSSA) INITIALIZE_PASS_DEPENDENCY(LCSSA)
@ -64,6 +67,7 @@ bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>(); DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
LoopInfo *LI = &getAnalysis<LoopInfo>(); LoopInfo *LI = &getAnalysis<LoopInfo>();
const TargetData *TD = getAnalysisIfAvailable<TargetData>(); const TargetData *TD = getAnalysisIfAvailable<TargetData>();
const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
SmallVector<BasicBlock*, 8> ExitBlocks; SmallVector<BasicBlock*, 8> ExitBlocks;
L->getUniqueExitBlocks(ExitBlocks); L->getUniqueExitBlocks(ExitBlocks);
@ -104,7 +108,7 @@ bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
// Don't bother simplifying unused instructions. // Don't bother simplifying unused instructions.
if (!I->use_empty()) { if (!I->use_empty()) {
Value *V = SimplifyInstruction(I, TD, DT); Value *V = SimplifyInstruction(I, TD, TLI, DT);
if (V && LI->replacementPreservesLCSSAForm(I, V)) { if (V && LI->replacementPreservesLCSSAForm(I, V)) {
// Mark all uses for resimplification next time round the loop. // Mark all uses for resimplification next time round the loop.
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();

View File

@ -1021,7 +1021,7 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
// See if instruction simplification can hack this up. This is common for // See if instruction simplification can hack this up. This is common for
// things like "select false, X, Y" after unswitching made the condition be // things like "select false, X, Y" after unswitching made the condition be
// 'false'. // 'false'.
if (Value *V = SimplifyInstruction(I, 0, DT)) if (Value *V = SimplifyInstruction(I, 0, 0, DT))
if (LI->replacementPreservesLCSSAForm(I, V)) { if (LI->replacementPreservesLCSSAForm(I, V)) {
ReplaceUsesOfWith(I, V, Worklist, L, LPM); ReplaceUsesOfWith(I, V, Worklist, L, LPM);
continue; continue;

View File

@ -265,7 +265,7 @@ ReprocessLoop:
PHINode *PN; PHINode *PN;
for (BasicBlock::iterator I = L->getHeader()->begin(); for (BasicBlock::iterator I = L->getHeader()->begin();
(PN = dyn_cast<PHINode>(I++)); ) (PN = dyn_cast<PHINode>(I++)); )
if (Value *V = SimplifyInstruction(PN, 0, DT)) { if (Value *V = SimplifyInstruction(PN, 0, 0, DT)) {
if (AA) AA->deleteValue(PN); if (AA) AA->deleteValue(PN);
if (SE) SE->forgetValue(PN); if (SE) SE->forgetValue(PN);
PN->replaceAllUsesWith(V); PN->replaceAllUsesWith(V);
@ -456,7 +456,7 @@ static PHINode *FindPHIToPartitionLoops(Loop *L, DominatorTree *DT,
for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ) { for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ) {
PHINode *PN = cast<PHINode>(I); PHINode *PN = cast<PHINode>(I);
++I; ++I;
if (Value *V = SimplifyInstruction(PN, 0, DT)) { if (Value *V = SimplifyInstruction(PN, 0, 0, DT)) {
// This is a degenerate PHI already, don't modify it! // This is a degenerate PHI already, don't modify it!
PN->replaceAllUsesWith(V); PN->replaceAllUsesWith(V);
if (AA) AA->deleteValue(PN); if (AA) AA->deleteValue(PN);

View File

@ -590,7 +590,7 @@ void PromoteMem2Reg::run() {
PHINode *PN = I->second; PHINode *PN = I->second;
// If this PHI node merges one value and/or undefs, get the value. // If this PHI node merges one value and/or undefs, get the value.
if (Value *V = SimplifyInstruction(PN, 0, &DT)) { if (Value *V = SimplifyInstruction(PN, 0, 0, &DT)) {
if (AST && PN->getType()->isPointerTy()) if (AST && PN->getType()->isPointerTy())
AST->deleteValue(PN); AST->deleteValue(PN);
PN->replaceAllUsesWith(V); PN->replaceAllUsesWith(V);

View File

@ -24,6 +24,7 @@
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
using namespace llvm; using namespace llvm;
@ -39,12 +40,14 @@ namespace {
void getAnalysisUsage(AnalysisUsage &AU) const { void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG(); AU.setPreservesCFG();
AU.addRequired<TargetLibraryInfo>();
} }
/// runOnFunction - Remove instructions that simplify. /// runOnFunction - Remove instructions that simplify.
bool runOnFunction(Function &F) { bool runOnFunction(Function &F) {
const DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>(); const DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
const TargetData *TD = getAnalysisIfAvailable<TargetData>(); const TargetData *TD = getAnalysisIfAvailable<TargetData>();
const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2; SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
bool Changed = false; bool Changed = false;
@ -60,7 +63,7 @@ namespace {
continue; continue;
// Don't waste time simplifying unused instructions. // Don't waste time simplifying unused instructions.
if (!I->use_empty()) if (!I->use_empty())
if (Value *V = SimplifyInstruction(I, TD, DT)) { if (Value *V = SimplifyInstruction(I, TD, TLI, DT)) {
// Mark all uses for resimplification next time round the loop. // Mark all uses for resimplification next time round the loop.
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
UI != UE; ++UI) UI != UE; ++UI)
@ -84,8 +87,11 @@ namespace {
} }
char InstSimplifier::ID = 0; char InstSimplifier::ID = 0;
INITIALIZE_PASS(InstSimplifier, "instsimplify", "Remove redundant instructions", INITIALIZE_PASS_BEGIN(InstSimplifier, "instsimplify",
false, false) "Remove redundant instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
INITIALIZE_PASS_END(InstSimplifier, "instsimplify",
"Remove redundant instructions", false, false)
char &llvm::InstructionSimplifierID = InstSimplifier::ID; char &llvm::InstructionSimplifierID = InstSimplifier::ID;
// Public interface to the simplify instructions pass. // Public interface to the simplify instructions pass.