mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
Refactor instruction simplification code in visitors. NFC.
Several visitors check if operands to the instruction are constants, either as it is or after looking up SimplifiedValues, check if the result is a constant and update the SimplifiedValues map. This refactoring splits it into a common function that does the checking of whether the operands are constants and updating of the SimplifiedValues table, and an instruction specific part that is implemented by each instruction visitor as a lambda and passed to the common function. Differential revision: https://reviews.llvm.org/D30104 llvm-svn: 295552
This commit is contained in:
parent
76f60358d0
commit
2a5da52fb7
@ -146,6 +146,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
|
|||||||
bool isGEPFree(GetElementPtrInst &GEP);
|
bool isGEPFree(GetElementPtrInst &GEP);
|
||||||
bool accumulateGEPOffset(GEPOperator &GEP, APInt &Offset);
|
bool accumulateGEPOffset(GEPOperator &GEP, APInt &Offset);
|
||||||
bool simplifyCallSite(Function *F, CallSite CS);
|
bool simplifyCallSite(Function *F, CallSite CS);
|
||||||
|
template <typename Callable>
|
||||||
|
bool simplifyInstruction(Instruction &I, Callable Evaluate);
|
||||||
ConstantInt *stripAndComputeInBoundsConstantOffsets(Value *&V);
|
ConstantInt *stripAndComputeInBoundsConstantOffsets(Value *&V);
|
||||||
|
|
||||||
/// Return true if the given argument to the function being considered for
|
/// Return true if the given argument to the function being considered for
|
||||||
@ -452,16 +454,33 @@ bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &I) {
|
|||||||
return isGEPFree(I);
|
return isGEPFree(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;
|
||||||
|
for (Value *Op : I.operands()) {
|
||||||
|
Constant *COp = dyn_cast<Constant>(Op);
|
||||||
|
if (!COp)
|
||||||
|
COp = SimplifiedValues.lookup(Op);
|
||||||
|
if (!COp)
|
||||||
|
return false;
|
||||||
|
COps.push_back(COp);
|
||||||
|
}
|
||||||
|
auto *C = Evaluate(COps);
|
||||||
|
if (!C)
|
||||||
|
return false;
|
||||||
|
SimplifiedValues[&I] = C;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CallAnalyzer::visitBitCast(BitCastInst &I) {
|
bool CallAnalyzer::visitBitCast(BitCastInst &I) {
|
||||||
// Propagate constants through bitcasts.
|
// Propagate constants through bitcasts.
|
||||||
Constant *COp = dyn_cast<Constant>(I.getOperand(0));
|
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||||
if (!COp)
|
return ConstantExpr::getBitCast(COps[0], I.getType());
|
||||||
COp = SimplifiedValues.lookup(I.getOperand(0));
|
}))
|
||||||
if (COp)
|
return true;
|
||||||
if (Constant *C = ConstantExpr::getBitCast(COp, I.getType())) {
|
|
||||||
SimplifiedValues[&I] = C;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track base/offsets through casts
|
// Track base/offsets through casts
|
||||||
std::pair<Value *, APInt> BaseAndOffset =
|
std::pair<Value *, APInt> BaseAndOffset =
|
||||||
@ -482,14 +501,10 @@ bool CallAnalyzer::visitBitCast(BitCastInst &I) {
|
|||||||
|
|
||||||
bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
|
bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
|
||||||
// Propagate constants through ptrtoint.
|
// Propagate constants through ptrtoint.
|
||||||
Constant *COp = dyn_cast<Constant>(I.getOperand(0));
|
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||||
if (!COp)
|
return ConstantExpr::getPtrToInt(COps[0], I.getType());
|
||||||
COp = SimplifiedValues.lookup(I.getOperand(0));
|
}))
|
||||||
if (COp)
|
return true;
|
||||||
if (Constant *C = ConstantExpr::getPtrToInt(COp, I.getType())) {
|
|
||||||
SimplifiedValues[&I] = C;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track base/offset pairs when converted to a plain integer provided the
|
// Track base/offset pairs when converted to a plain integer provided the
|
||||||
// integer is large enough to represent the pointer.
|
// integer is large enough to represent the pointer.
|
||||||
@ -519,14 +534,10 @@ bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
|
|||||||
|
|
||||||
bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) {
|
bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) {
|
||||||
// Propagate constants through ptrtoint.
|
// Propagate constants through ptrtoint.
|
||||||
Constant *COp = dyn_cast<Constant>(I.getOperand(0));
|
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||||
if (!COp)
|
return ConstantExpr::getIntToPtr(COps[0], I.getType());
|
||||||
COp = SimplifiedValues.lookup(I.getOperand(0));
|
}))
|
||||||
if (COp)
|
return true;
|
||||||
if (Constant *C = ConstantExpr::getIntToPtr(COp, I.getType())) {
|
|
||||||
SimplifiedValues[&I] = C;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track base/offset pairs when round-tripped through a pointer without
|
// Track base/offset pairs when round-tripped through a pointer without
|
||||||
// modifications provided the integer is not too large.
|
// modifications provided the integer is not too large.
|
||||||
@ -550,14 +561,10 @@ bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) {
|
|||||||
|
|
||||||
bool CallAnalyzer::visitCastInst(CastInst &I) {
|
bool CallAnalyzer::visitCastInst(CastInst &I) {
|
||||||
// Propagate constants through ptrtoint.
|
// Propagate constants through ptrtoint.
|
||||||
Constant *COp = dyn_cast<Constant>(I.getOperand(0));
|
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||||
if (!COp)
|
return ConstantExpr::getCast(I.getOpcode(), COps[0], I.getType());
|
||||||
COp = SimplifiedValues.lookup(I.getOperand(0));
|
}))
|
||||||
if (COp)
|
return true;
|
||||||
if (Constant *C = ConstantExpr::getCast(I.getOpcode(), COp, I.getType())) {
|
|
||||||
SimplifiedValues[&I] = C;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable SROA in the face of arbitrary casts we don't whitelist elsewhere.
|
// Disable SROA in the face of arbitrary casts we don't whitelist elsewhere.
|
||||||
disableSROA(I.getOperand(0));
|
disableSROA(I.getOperand(0));
|
||||||
@ -567,16 +574,11 @@ bool CallAnalyzer::visitCastInst(CastInst &I) {
|
|||||||
|
|
||||||
bool CallAnalyzer::visitUnaryInstruction(UnaryInstruction &I) {
|
bool CallAnalyzer::visitUnaryInstruction(UnaryInstruction &I) {
|
||||||
Value *Operand = I.getOperand(0);
|
Value *Operand = I.getOperand(0);
|
||||||
Constant *COp = dyn_cast<Constant>(Operand);
|
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||||
if (!COp)
|
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||||
COp = SimplifiedValues.lookup(Operand);
|
return ConstantFoldInstOperands(&I, COps[0], DL);
|
||||||
if (COp) {
|
}))
|
||||||
const DataLayout &DL = F.getParent()->getDataLayout();
|
return true;
|
||||||
if (Constant *C = ConstantFoldInstOperands(&I, COp, DL)) {
|
|
||||||
SimplifiedValues[&I] = C;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable any SROA on the argument to arbitrary unary operators.
|
// Disable any SROA on the argument to arbitrary unary operators.
|
||||||
disableSROA(Operand);
|
disableSROA(Operand);
|
||||||
@ -697,20 +699,10 @@ void CallAnalyzer::updateThreshold(CallSite CS, Function &Callee) {
|
|||||||
bool CallAnalyzer::visitCmpInst(CmpInst &I) {
|
bool CallAnalyzer::visitCmpInst(CmpInst &I) {
|
||||||
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
||||||
// First try to handle simplified comparisons.
|
// First try to handle simplified comparisons.
|
||||||
if (!isa<Constant>(LHS))
|
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||||
if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS))
|
return ConstantExpr::getCompare(I.getPredicate(), COps[0], COps[1]);
|
||||||
LHS = SimpleLHS;
|
}))
|
||||||
if (!isa<Constant>(RHS))
|
return true;
|
||||||
if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS))
|
|
||||||
RHS = SimpleRHS;
|
|
||||||
if (Constant *CLHS = dyn_cast<Constant>(LHS)) {
|
|
||||||
if (Constant *CRHS = dyn_cast<Constant>(RHS))
|
|
||||||
if (Constant *C =
|
|
||||||
ConstantExpr::getCompare(I.getPredicate(), CLHS, CRHS)) {
|
|
||||||
SimplifiedValues[&I] = C;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (I.getOpcode() == Instruction::FCmp)
|
if (I.getOpcode() == Instruction::FCmp)
|
||||||
return false;
|
return false;
|
||||||
@ -788,24 +780,19 @@ bool CallAnalyzer::visitSub(BinaryOperator &I) {
|
|||||||
|
|
||||||
bool CallAnalyzer::visitBinaryOperator(BinaryOperator &I) {
|
bool CallAnalyzer::visitBinaryOperator(BinaryOperator &I) {
|
||||||
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
||||||
const DataLayout &DL = F.getParent()->getDataLayout();
|
auto Evaluate = [&](SmallVectorImpl<Constant *> &COps) {
|
||||||
if (!isa<Constant>(LHS))
|
Value *SimpleV = nullptr;
|
||||||
if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS))
|
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||||
LHS = SimpleLHS;
|
if (auto FI = dyn_cast<FPMathOperator>(&I))
|
||||||
if (!isa<Constant>(RHS))
|
SimpleV = SimplifyFPBinOp(I.getOpcode(), COps[0], COps[1],
|
||||||
if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS))
|
FI->getFastMathFlags(), DL);
|
||||||
RHS = SimpleRHS;
|
else
|
||||||
Value *SimpleV = nullptr;
|
SimpleV = SimplifyBinOp(I.getOpcode(), COps[0], COps[1], DL);
|
||||||
if (auto FI = dyn_cast<FPMathOperator>(&I))
|
return dyn_cast_or_null<Constant>(SimpleV);
|
||||||
SimpleV =
|
};
|
||||||
SimplifyFPBinOp(I.getOpcode(), LHS, RHS, FI->getFastMathFlags(), DL);
|
|
||||||
else
|
|
||||||
SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS, DL);
|
|
||||||
|
|
||||||
if (Constant *C = dyn_cast_or_null<Constant>(SimpleV)) {
|
if (simplifyInstruction(I, Evaluate))
|
||||||
SimplifiedValues[&I] = C;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// Disable any SROA on arguments to arbitrary, unsimplified binary operators.
|
// Disable any SROA on arguments to arbitrary, unsimplified binary operators.
|
||||||
disableSROA(LHS);
|
disableSROA(LHS);
|
||||||
@ -846,13 +833,10 @@ bool CallAnalyzer::visitStore(StoreInst &I) {
|
|||||||
|
|
||||||
bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) {
|
bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) {
|
||||||
// Constant folding for extract value is trivial.
|
// Constant folding for extract value is trivial.
|
||||||
Constant *C = dyn_cast<Constant>(I.getAggregateOperand());
|
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||||
if (!C)
|
return ConstantExpr::getExtractValue(COps[0], I.getIndices());
|
||||||
C = SimplifiedValues.lookup(I.getAggregateOperand());
|
}))
|
||||||
if (C) {
|
|
||||||
SimplifiedValues[&I] = ConstantExpr::getExtractValue(C, I.getIndices());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// SROA can look through these but give them a cost.
|
// SROA can look through these but give them a cost.
|
||||||
return false;
|
return false;
|
||||||
@ -860,17 +844,12 @@ bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) {
|
|||||||
|
|
||||||
bool CallAnalyzer::visitInsertValue(InsertValueInst &I) {
|
bool CallAnalyzer::visitInsertValue(InsertValueInst &I) {
|
||||||
// Constant folding for insert value is trivial.
|
// Constant folding for insert value is trivial.
|
||||||
Constant *AggC = dyn_cast<Constant>(I.getAggregateOperand());
|
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||||
if (!AggC)
|
return ConstantExpr::getInsertValue(/*AggregateOperand*/ COps[0],
|
||||||
AggC = SimplifiedValues.lookup(I.getAggregateOperand());
|
/*InsertedValueOperand*/ COps[1],
|
||||||
Constant *InsertedC = dyn_cast<Constant>(I.getInsertedValueOperand());
|
I.getIndices());
|
||||||
if (!InsertedC)
|
}))
|
||||||
InsertedC = SimplifiedValues.lookup(I.getInsertedValueOperand());
|
|
||||||
if (AggC && InsertedC) {
|
|
||||||
SimplifiedValues[&I] =
|
|
||||||
ConstantExpr::getInsertValue(AggC, InsertedC, I.getIndices());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// SROA can look through these but give them a cost.
|
// SROA can look through these but give them a cost.
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user