diff options
author | Hari Limaye <hari.limaye@arm.com> | 2024-11-06 13:25:15 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-06 13:25:15 +0000 |
commit | 88e9b373c0d7184b08c755024cce0778d18f0306 (patch) | |
tree | 07fd99e1e320227199b146b4aa1752abbb5048e6 /llvm/lib/Transforms/IPO/FunctionSpecialization.cpp | |
parent | 28452acac05de8dc64aa7ba76af70ac541667cdd (diff) | |
download | llvm-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.cpp | 42 |
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; |