aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
diff options
context:
space:
mode:
authorHari Limaye <hari.limaye@arm.com>2024-11-06 13:25:15 +0000
committerGitHub <noreply@github.com>2024-11-06 13:25:15 +0000
commit88e9b373c0d7184b08c755024cce0778d18f0306 (patch)
tree07fd99e1e320227199b146b4aa1752abbb5048e6 /llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
parent28452acac05de8dc64aa7ba76af70ac541667cdd (diff)
downloadllvm-88e9b373c0d7184b08c755024cce0778d18f0306.zip
llvm-88e9b373c0d7184b08c755024cce0778d18f0306.tar.gz
llvm-88e9b373c0d7184b08c755024cce0778d18f0306.tar.bz2
[FuncSpec] Query SCCPSolver in more places (#114964)
When traversing the use-def chain of an Argument in a candidate specialization, also query the SCCPSolver to see if a Value is constant. This allows us to better estimate the codesize savings of a candidate in the presence of instructions that are a user of the argument we are estimating savings for which also use arguments that have been found constant by IPSCCP. Similarly when estimating the dead basic blocks from branch and switch instructions which become constant, also query the SCCPSolver to see if a predecessor is unreachable.
Diffstat (limited to 'llvm/lib/Transforms/IPO/FunctionSpecialization.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/FunctionSpecialization.cpp42
1 files changed, 21 insertions, 21 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
index 17d8283..96956481 100644
--- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
@@ -90,13 +90,12 @@ static cl::opt<bool> SpecializeLiteralConstant(
"Enable specialization of functions that take a literal constant as an "
"argument"));
-bool InstCostVisitor::canEliminateSuccessor(BasicBlock *BB, BasicBlock *Succ,
- DenseSet<BasicBlock *> &DeadBlocks) {
+bool InstCostVisitor::canEliminateSuccessor(BasicBlock *BB,
+ BasicBlock *Succ) const {
unsigned I = 0;
- return all_of(predecessors(Succ),
- [&I, BB, Succ, &DeadBlocks] (BasicBlock *Pred) {
+ return all_of(predecessors(Succ), [&I, BB, Succ, this](BasicBlock *Pred) {
return I++ < MaxBlockPredecessors &&
- (Pred == BB || Pred == Succ || DeadBlocks.contains(Pred));
+ (Pred == BB || Pred == Succ || !isBlockExecutable(Pred));
});
}
@@ -116,6 +115,7 @@ Cost InstCostVisitor::estimateBasicBlocks(
// These blocks are considered dead as far as the InstCostVisitor
// is concerned. They haven't been proven dead yet by the Solver,
// but may become if we propagate the specialization arguments.
+ assert(Solver.isBlockExecutable(BB) && "BB already found dead by IPSCCP!");
if (!DeadBlocks.insert(BB).second)
continue;
@@ -134,16 +134,17 @@ Cost InstCostVisitor::estimateBasicBlocks(
// Keep adding dead successors to the list as long as they are
// executable and only reachable from dead blocks.
for (BasicBlock *SuccBB : successors(BB))
- if (isBlockExecutable(SuccBB) &&
- canEliminateSuccessor(BB, SuccBB, DeadBlocks))
+ if (isBlockExecutable(SuccBB) && canEliminateSuccessor(BB, SuccBB))
WorkList.push_back(SuccBB);
}
return CodeSize;
}
-static Constant *findConstantFor(Value *V, ConstMap &KnownConstants) {
+Constant *InstCostVisitor::findConstantFor(Value *V) const {
if (auto *C = dyn_cast<Constant>(V))
return C;
+ if (auto *C = Solver.getConstantOrNull(V))
+ return C;
return KnownConstants.lookup(V);
}
@@ -266,7 +267,7 @@ Cost InstCostVisitor::estimateSwitchInst(SwitchInst &I) {
for (const auto &Case : I.cases()) {
BasicBlock *BB = Case.getCaseSuccessor();
if (BB != Succ && isBlockExecutable(BB) &&
- canEliminateSuccessor(I.getParent(), BB, DeadBlocks))
+ canEliminateSuccessor(I.getParent(), BB))
WorkList.push_back(BB);
}
@@ -283,8 +284,7 @@ Cost InstCostVisitor::estimateBranchInst(BranchInst &I) {
// Initialize the worklist with the dead successor as long as
// it is executable and has a unique predecessor.
SmallVector<BasicBlock *> WorkList;
- if (isBlockExecutable(Succ) &&
- canEliminateSuccessor(I.getParent(), Succ, DeadBlocks))
+ if (isBlockExecutable(Succ) && canEliminateSuccessor(I.getParent(), Succ))
WorkList.push_back(Succ);
return estimateBasicBlocks(WorkList);
@@ -312,10 +312,10 @@ bool InstCostVisitor::discoverTransitivelyIncomingValues(
// Disregard self-references and dead incoming values.
if (auto *Inst = dyn_cast<Instruction>(V))
- if (Inst == PN || DeadBlocks.contains(PN->getIncomingBlock(I)))
+ if (Inst == PN || !isBlockExecutable(PN->getIncomingBlock(I)))
continue;
- if (Constant *C = findConstantFor(V, KnownConstants)) {
+ if (Constant *C = findConstantFor(V)) {
// Not all incoming values are the same constant. Bail immediately.
if (C != Const)
return false;
@@ -347,10 +347,10 @@ Constant *InstCostVisitor::visitPHINode(PHINode &I) {
// Disregard self-references and dead incoming values.
if (auto *Inst = dyn_cast<Instruction>(V))
- if (Inst == &I || DeadBlocks.contains(I.getIncomingBlock(Idx)))
+ if (Inst == &I || !isBlockExecutable(I.getIncomingBlock(Idx)))
continue;
- if (Constant *C = findConstantFor(V, KnownConstants)) {
+ if (Constant *C = findConstantFor(V)) {
if (!Const)
Const = C;
// Not all incoming values are the same constant. Bail immediately.
@@ -415,7 +415,7 @@ Constant *InstCostVisitor::visitCallBase(CallBase &I) {
for (unsigned Idx = 0, E = I.getNumOperands() - 1; Idx != E; ++Idx) {
Value *V = I.getOperand(Idx);
- Constant *C = findConstantFor(V, KnownConstants);
+ Constant *C = findConstantFor(V);
if (!C)
return nullptr;
Operands.push_back(C);
@@ -439,7 +439,7 @@ Constant *InstCostVisitor::visitGetElementPtrInst(GetElementPtrInst &I) {
for (unsigned Idx = 0, E = I.getNumOperands(); Idx != E; ++Idx) {
Value *V = I.getOperand(Idx);
- Constant *C = findConstantFor(V, KnownConstants);
+ Constant *C = findConstantFor(V);
if (!C)
return nullptr;
Operands.push_back(C);
@@ -455,9 +455,9 @@ Constant *InstCostVisitor::visitSelectInst(SelectInst &I) {
if (I.getCondition() == LastVisited->first) {
Value *V = LastVisited->second->isZeroValue() ? I.getFalseValue()
: I.getTrueValue();
- return findConstantFor(V, KnownConstants);
+ return findConstantFor(V);
}
- if (Constant *Condition = findConstantFor(I.getCondition(), KnownConstants))
+ if (Constant *Condition = findConstantFor(I.getCondition()))
if ((I.getTrueValue() == LastVisited->first && Condition->isOneValue()) ||
(I.getFalseValue() == LastVisited->first && Condition->isZeroValue()))
return LastVisited->second;
@@ -475,7 +475,7 @@ Constant *InstCostVisitor::visitCmpInst(CmpInst &I) {
Constant *Const = LastVisited->second;
bool ConstOnRHS = I.getOperand(1) == LastVisited->first;
Value *V = ConstOnRHS ? I.getOperand(0) : I.getOperand(1);
- Constant *Other = findConstantFor(V, KnownConstants);
+ Constant *Other = findConstantFor(V);
if (Other) {
if (ConstOnRHS)
@@ -503,7 +503,7 @@ Constant *InstCostVisitor::visitBinaryOperator(BinaryOperator &I) {
bool ConstOnRHS = I.getOperand(1) == LastVisited->first;
Value *V = ConstOnRHS ? I.getOperand(0) : I.getOperand(1);
- Constant *Other = findConstantFor(V, KnownConstants);
+ Constant *Other = findConstantFor(V);
Value *OtherVal = Other ? Other : V;
Value *ConstVal = LastVisited->second;