1
0
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:
Easwaran Raman 2017-02-18 17:22:52 +00:00
parent 76f60358d0
commit 2a5da52fb7

View File

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