[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:
Nikita Popov 2022-06-30 11:14:01 +02:00
parent bb0896e96f
commit 54fcde42c0
2 changed files with 13 additions and 39 deletions

View File

@ -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.

View File

@ -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)**