forked from OSchip/llvm-project
[InlineCost] Simplify constant folding
Use a common ConstantFoldInstOperands-based constant folding implementation, instead of specifying the folding function for each function individually. Going through the generic handling doesn't appear to have any significant compile-time impact. As the test change shows, this is not NFC, because we now use DataLayout-aware constant folding, which can do slightly better in some cases (e.g. those involving GEPs).
This commit is contained in:
parent
bb0896e96f
commit
54fcde42c0
|
@ -384,8 +384,7 @@ protected:
|
|||
bool canFoldInboundsGEP(GetElementPtrInst &I);
|
||||
bool accumulateGEPOffset(GEPOperator &GEP, APInt &Offset);
|
||||
bool simplifyCallSite(Function *F, CallBase &Call);
|
||||
template <typename Callable>
|
||||
bool simplifyInstruction(Instruction &I, Callable Evaluate);
|
||||
bool simplifyInstruction(Instruction &I);
|
||||
bool simplifyIntrinsicCallIsConstant(CallBase &CB);
|
||||
ConstantInt *stripAndComputeInBoundsConstantOffsets(Value *&V);
|
||||
|
||||
|
@ -1511,13 +1510,7 @@ bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &I) {
|
|||
};
|
||||
|
||||
if (!DisableGEPConstOperand)
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
SmallVector<Constant *, 2> Indices;
|
||||
for (unsigned int Index = 1; Index < COps.size(); ++Index)
|
||||
Indices.push_back(COps[Index]);
|
||||
return ConstantExpr::getGetElementPtr(
|
||||
I.getSourceElementType(), COps[0], Indices, I.isInBounds());
|
||||
}))
|
||||
if (simplifyInstruction(I))
|
||||
return true;
|
||||
|
||||
if ((I.isInBounds() && canFoldInboundsGEP(I)) || IsGEPOffsetConstant(I)) {
|
||||
|
@ -1535,11 +1528,8 @@ bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &I) {
|
|||
}
|
||||
|
||||
/// Simplify \p I if its operands are constants and update SimplifiedValues.
|
||||
/// \p Evaluate is a callable specific to instruction type that evaluates the
|
||||
/// instruction when all the operands are constants.
|
||||
template <typename Callable>
|
||||
bool CallAnalyzer::simplifyInstruction(Instruction &I, Callable Evaluate) {
|
||||
SmallVector<Constant *, 2> COps;
|
||||
bool CallAnalyzer::simplifyInstruction(Instruction &I) {
|
||||
SmallVector<Constant *> COps;
|
||||
for (Value *Op : I.operands()) {
|
||||
Constant *COp = dyn_cast<Constant>(Op);
|
||||
if (!COp)
|
||||
|
@ -1548,7 +1538,7 @@ bool CallAnalyzer::simplifyInstruction(Instruction &I, Callable Evaluate) {
|
|||
return false;
|
||||
COps.push_back(COp);
|
||||
}
|
||||
auto *C = Evaluate(COps);
|
||||
auto *C = ConstantFoldInstOperands(&I, COps, DL);
|
||||
if (!C)
|
||||
return false;
|
||||
SimplifiedValues[&I] = C;
|
||||
|
@ -1578,9 +1568,7 @@ bool CallAnalyzer::simplifyIntrinsicCallIsConstant(CallBase &CB) {
|
|||
|
||||
bool CallAnalyzer::visitBitCast(BitCastInst &I) {
|
||||
// Propagate constants through bitcasts.
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getBitCast(COps[0], I.getType());
|
||||
}))
|
||||
if (simplifyInstruction(I))
|
||||
return true;
|
||||
|
||||
// Track base/offsets through casts
|
||||
|
@ -1600,9 +1588,7 @@ bool CallAnalyzer::visitBitCast(BitCastInst &I) {
|
|||
|
||||
bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
|
||||
// Propagate constants through ptrtoint.
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getPtrToInt(COps[0], I.getType());
|
||||
}))
|
||||
if (simplifyInstruction(I))
|
||||
return true;
|
||||
|
||||
// Track base/offset pairs when converted to a plain integer provided the
|
||||
|
@ -1632,9 +1618,7 @@ bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
|
|||
|
||||
bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) {
|
||||
// Propagate constants through ptrtoint.
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getIntToPtr(COps[0], I.getType());
|
||||
}))
|
||||
if (simplifyInstruction(I))
|
||||
return true;
|
||||
|
||||
// Track base/offset pairs when round-tripped through a pointer without
|
||||
|
@ -1657,9 +1641,7 @@ bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) {
|
|||
|
||||
bool CallAnalyzer::visitCastInst(CastInst &I) {
|
||||
// Propagate constants through casts.
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getCast(I.getOpcode(), COps[0], I.getType());
|
||||
}))
|
||||
if (simplifyInstruction(I))
|
||||
return true;
|
||||
|
||||
// Disable SROA in the face of arbitrary casts we don't explicitly list
|
||||
|
@ -1916,9 +1898,7 @@ void InlineCostCallAnalyzer::updateThreshold(CallBase &Call, Function &Callee) {
|
|||
bool CallAnalyzer::visitCmpInst(CmpInst &I) {
|
||||
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
||||
// First try to handle simplified comparisons.
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getCompare(I.getPredicate(), COps[0], COps[1]);
|
||||
}))
|
||||
if (simplifyInstruction(I))
|
||||
return true;
|
||||
|
||||
if (I.getOpcode() == Instruction::FCmp)
|
||||
|
@ -2077,9 +2057,7 @@ bool CallAnalyzer::visitStore(StoreInst &I) {
|
|||
|
||||
bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) {
|
||||
// Constant folding for extract value is trivial.
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantFoldExtractValueInstruction(COps[0], I.getIndices());
|
||||
}))
|
||||
if (simplifyInstruction(I))
|
||||
return true;
|
||||
|
||||
// SROA can't look through these, but they may be free.
|
||||
|
@ -2088,11 +2066,7 @@ bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) {
|
|||
|
||||
bool CallAnalyzer::visitInsertValue(InsertValueInst &I) {
|
||||
// Constant folding for insert value is trivial.
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getInsertValue(/*AggregateOperand*/ COps[0],
|
||||
/*InsertedValueOperand*/ COps[1],
|
||||
I.getIndices());
|
||||
}))
|
||||
if (simplifyInstruction(I))
|
||||
return true;
|
||||
|
||||
// SROA can't look through these, but they may be free.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
; RUN: opt < %s -passes="print<inline-cost>" 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @foo
|
||||
; CHECK: cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = {{.*}}, simplified to i8 addrspace(1)** getelementptr (i8 addrspace(1)*, i8 addrspace(1)** inttoptr (i64 754974720 to i8 addrspace(1)**), i64 5)
|
||||
; CHECK: cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = {{.*}}, simplified to i8 addrspace(1)** inttoptr (i64 754974760 to i8 addrspace(1)**)
|
||||
|
||||
define i8 addrspace(1)** @foo(i64 %0) {
|
||||
%2 = inttoptr i64 754974720 to i8 addrspace(1)**
|
||||
|
|
Loading…
Reference in New Issue