mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +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 accumulateGEPOffset(GEPOperator &GEP, APInt &Offset);
|
||||
bool simplifyCallSite(Function *F, CallSite CS);
|
||||
template <typename Callable>
|
||||
bool simplifyInstruction(Instruction &I, Callable Evaluate);
|
||||
ConstantInt *stripAndComputeInBoundsConstantOffsets(Value *&V);
|
||||
|
||||
/// Return true if the given argument to the function being considered for
|
||||
@ -452,16 +454,33 @@ bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &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) {
|
||||
// Propagate constants through bitcasts.
|
||||
Constant *COp = dyn_cast<Constant>(I.getOperand(0));
|
||||
if (!COp)
|
||||
COp = SimplifiedValues.lookup(I.getOperand(0));
|
||||
if (COp)
|
||||
if (Constant *C = ConstantExpr::getBitCast(COp, I.getType())) {
|
||||
SimplifiedValues[&I] = C;
|
||||
return true;
|
||||
}
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getBitCast(COps[0], I.getType());
|
||||
}))
|
||||
return true;
|
||||
|
||||
// Track base/offsets through casts
|
||||
std::pair<Value *, APInt> BaseAndOffset =
|
||||
@ -482,14 +501,10 @@ bool CallAnalyzer::visitBitCast(BitCastInst &I) {
|
||||
|
||||
bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
|
||||
// Propagate constants through ptrtoint.
|
||||
Constant *COp = dyn_cast<Constant>(I.getOperand(0));
|
||||
if (!COp)
|
||||
COp = SimplifiedValues.lookup(I.getOperand(0));
|
||||
if (COp)
|
||||
if (Constant *C = ConstantExpr::getPtrToInt(COp, I.getType())) {
|
||||
SimplifiedValues[&I] = C;
|
||||
return true;
|
||||
}
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getPtrToInt(COps[0], I.getType());
|
||||
}))
|
||||
return true;
|
||||
|
||||
// Track base/offset pairs when converted to a plain integer provided the
|
||||
// integer is large enough to represent the pointer.
|
||||
@ -519,14 +534,10 @@ bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
|
||||
|
||||
bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) {
|
||||
// Propagate constants through ptrtoint.
|
||||
Constant *COp = dyn_cast<Constant>(I.getOperand(0));
|
||||
if (!COp)
|
||||
COp = SimplifiedValues.lookup(I.getOperand(0));
|
||||
if (COp)
|
||||
if (Constant *C = ConstantExpr::getIntToPtr(COp, I.getType())) {
|
||||
SimplifiedValues[&I] = C;
|
||||
return true;
|
||||
}
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getIntToPtr(COps[0], I.getType());
|
||||
}))
|
||||
return true;
|
||||
|
||||
// Track base/offset pairs when round-tripped through a pointer without
|
||||
// modifications provided the integer is not too large.
|
||||
@ -550,14 +561,10 @@ bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) {
|
||||
|
||||
bool CallAnalyzer::visitCastInst(CastInst &I) {
|
||||
// Propagate constants through ptrtoint.
|
||||
Constant *COp = dyn_cast<Constant>(I.getOperand(0));
|
||||
if (!COp)
|
||||
COp = SimplifiedValues.lookup(I.getOperand(0));
|
||||
if (COp)
|
||||
if (Constant *C = ConstantExpr::getCast(I.getOpcode(), COp, I.getType())) {
|
||||
SimplifiedValues[&I] = C;
|
||||
return true;
|
||||
}
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getCast(I.getOpcode(), COps[0], I.getType());
|
||||
}))
|
||||
return true;
|
||||
|
||||
// Disable SROA in the face of arbitrary casts we don't whitelist elsewhere.
|
||||
disableSROA(I.getOperand(0));
|
||||
@ -567,16 +574,11 @@ bool CallAnalyzer::visitCastInst(CastInst &I) {
|
||||
|
||||
bool CallAnalyzer::visitUnaryInstruction(UnaryInstruction &I) {
|
||||
Value *Operand = I.getOperand(0);
|
||||
Constant *COp = dyn_cast<Constant>(Operand);
|
||||
if (!COp)
|
||||
COp = SimplifiedValues.lookup(Operand);
|
||||
if (COp) {
|
||||
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||
if (Constant *C = ConstantFoldInstOperands(&I, COp, DL)) {
|
||||
SimplifiedValues[&I] = C;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||
return ConstantFoldInstOperands(&I, COps[0], DL);
|
||||
}))
|
||||
return true;
|
||||
|
||||
// Disable any SROA on the argument to arbitrary unary operators.
|
||||
disableSROA(Operand);
|
||||
@ -697,20 +699,10 @@ void CallAnalyzer::updateThreshold(CallSite CS, Function &Callee) {
|
||||
bool CallAnalyzer::visitCmpInst(CmpInst &I) {
|
||||
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
||||
// First try to handle simplified comparisons.
|
||||
if (!isa<Constant>(LHS))
|
||||
if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS))
|
||||
LHS = SimpleLHS;
|
||||
if (!isa<Constant>(RHS))
|
||||
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 (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getCompare(I.getPredicate(), COps[0], COps[1]);
|
||||
}))
|
||||
return true;
|
||||
|
||||
if (I.getOpcode() == Instruction::FCmp)
|
||||
return false;
|
||||
@ -788,24 +780,19 @@ bool CallAnalyzer::visitSub(BinaryOperator &I) {
|
||||
|
||||
bool CallAnalyzer::visitBinaryOperator(BinaryOperator &I) {
|
||||
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
||||
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||
if (!isa<Constant>(LHS))
|
||||
if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS))
|
||||
LHS = SimpleLHS;
|
||||
if (!isa<Constant>(RHS))
|
||||
if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS))
|
||||
RHS = SimpleRHS;
|
||||
Value *SimpleV = nullptr;
|
||||
if (auto FI = dyn_cast<FPMathOperator>(&I))
|
||||
SimpleV =
|
||||
SimplifyFPBinOp(I.getOpcode(), LHS, RHS, FI->getFastMathFlags(), DL);
|
||||
else
|
||||
SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS, DL);
|
||||
auto Evaluate = [&](SmallVectorImpl<Constant *> &COps) {
|
||||
Value *SimpleV = nullptr;
|
||||
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||
if (auto FI = dyn_cast<FPMathOperator>(&I))
|
||||
SimpleV = SimplifyFPBinOp(I.getOpcode(), COps[0], COps[1],
|
||||
FI->getFastMathFlags(), DL);
|
||||
else
|
||||
SimpleV = SimplifyBinOp(I.getOpcode(), COps[0], COps[1], DL);
|
||||
return dyn_cast_or_null<Constant>(SimpleV);
|
||||
};
|
||||
|
||||
if (Constant *C = dyn_cast_or_null<Constant>(SimpleV)) {
|
||||
SimplifiedValues[&I] = C;
|
||||
if (simplifyInstruction(I, Evaluate))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Disable any SROA on arguments to arbitrary, unsimplified binary operators.
|
||||
disableSROA(LHS);
|
||||
@ -846,13 +833,10 @@ bool CallAnalyzer::visitStore(StoreInst &I) {
|
||||
|
||||
bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) {
|
||||
// Constant folding for extract value is trivial.
|
||||
Constant *C = dyn_cast<Constant>(I.getAggregateOperand());
|
||||
if (!C)
|
||||
C = SimplifiedValues.lookup(I.getAggregateOperand());
|
||||
if (C) {
|
||||
SimplifiedValues[&I] = ConstantExpr::getExtractValue(C, I.getIndices());
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getExtractValue(COps[0], I.getIndices());
|
||||
}))
|
||||
return true;
|
||||
}
|
||||
|
||||
// SROA can look through these but give them a cost.
|
||||
return false;
|
||||
@ -860,17 +844,12 @@ bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) {
|
||||
|
||||
bool CallAnalyzer::visitInsertValue(InsertValueInst &I) {
|
||||
// Constant folding for insert value is trivial.
|
||||
Constant *AggC = dyn_cast<Constant>(I.getAggregateOperand());
|
||||
if (!AggC)
|
||||
AggC = SimplifiedValues.lookup(I.getAggregateOperand());
|
||||
Constant *InsertedC = dyn_cast<Constant>(I.getInsertedValueOperand());
|
||||
if (!InsertedC)
|
||||
InsertedC = SimplifiedValues.lookup(I.getInsertedValueOperand());
|
||||
if (AggC && InsertedC) {
|
||||
SimplifiedValues[&I] =
|
||||
ConstantExpr::getInsertValue(AggC, InsertedC, I.getIndices());
|
||||
if (simplifyInstruction(I, [&](SmallVectorImpl<Constant *> &COps) {
|
||||
return ConstantExpr::getInsertValue(/*AggregateOperand*/ COps[0],
|
||||
/*InsertedValueOperand*/ COps[1],
|
||||
I.getIndices());
|
||||
}))
|
||||
return true;
|
||||
}
|
||||
|
||||
// SROA can look through these but give them a cost.
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user