Skip to content

Commit 99463ca

Browse files
committed
Start separating out code metrics into code size metrics and code performance metrics. Partial Specialization will apply the former to function specializations, and the latter to all callsites that can use a specialization, in order to decide whether to create a specialization
llvm-svn: 116057
1 parent a07b5c2 commit 99463ca

File tree

3 files changed

+63
-13
lines changed

3 files changed

+63
-13
lines changed

llvm/include/llvm/Analysis/CodeMetrics.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ namespace llvm {
7777
/// many instructions will be constant folded if the specified value is
7878
/// constant.
7979
unsigned CountCodeReductionForConstant(Value *V);
80-
80+
81+
/// CountBonusForConstant - Figure out an approximation for how much
82+
/// per-call performance boost we can expect if the specified value is
83+
/// constant.
84+
unsigned CountBonusForConstant(Value *V);
85+
8186
/// CountCodeReductionForAlloca - Figure out an approximation of how much
8287
/// smaller the function will be if it is inlined into a context where an
8388
/// argument becomes an alloca.

llvm/include/llvm/Analysis/InlineCost.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ namespace llvm {
9696
public:
9797
unsigned ConstantWeight;
9898
unsigned AllocaWeight;
99+
unsigned ConstantBonus;
99100

100-
ArgInfo(unsigned CWeight, unsigned AWeight)
101-
: ConstantWeight(CWeight), AllocaWeight(AWeight) {}
101+
ArgInfo(unsigned CWeight, unsigned AWeight, unsigned CBonus)
102+
: ConstantWeight(CWeight), AllocaWeight(AWeight), ConstantBonus(CBonus)
103+
{}
102104
};
103105

104106
struct FunctionInfo {

llvm/lib/Analysis/InlineCost.cpp

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,55 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
142142
NumBBInsts[BB] = NumInsts - NumInstsBeforeThisBB;
143143
}
144144

145+
// CountBonusForConstant - Figure out an approximation for how much per-call
146+
// performance boost we can expect if the specified value is constant.
147+
unsigned CodeMetrics::CountBonusForConstant(Value *V) {
148+
unsigned Bonus = 0;
149+
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){
150+
User *U = *UI;
151+
if (CallInst *CI = dyn_cast<CallInst>(U)) {
152+
// Turning an indirect call into a direct call is a BIG win
153+
if (CI->getCalledValue() == V)
154+
Bonus += InlineConstants::IndirectCallBonus;
155+
}
156+
else if (InvokeInst *II = dyn_cast<InvokeInst>(U)) {
157+
// Turning an indirect call into a direct call is a BIG win
158+
if (II->getCalledValue() == V)
159+
Bonus += InlineConstants::IndirectCallBonus;
160+
}
161+
// FIXME: Eliminating conditional branches and switches should
162+
// also yield a per-call performance boost.
163+
else {
164+
// Figure out the bonuses that wll accrue due to simple constant
165+
// propagation.
166+
Instruction &Inst = cast<Instruction>(*U);
167+
168+
// We can't constant propagate instructions which have effects or
169+
// read memory.
170+
//
171+
// FIXME: It would be nice to capture the fact that a load from a
172+
// pointer-to-constant-global is actually a *really* good thing to zap.
173+
// Unfortunately, we don't know the pointer that may get propagated here,
174+
// so we can't make this decision.
175+
if (Inst.mayReadFromMemory() || Inst.mayHaveSideEffects() ||
176+
isa<AllocaInst>(Inst))
177+
continue;
178+
179+
bool AllOperandsConstant = true;
180+
for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i)
181+
if (!isa<Constant>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
182+
AllOperandsConstant = false;
183+
break;
184+
}
185+
186+
if (AllOperandsConstant)
187+
Bonus += CountBonusForConstant(&Inst);
188+
}
189+
}
190+
return Bonus;
191+
}
192+
193+
145194
// CountCodeReductionForConstant - Figure out an approximation for how many
146195
// instructions will be constant folded if the specified value is constant.
147196
//
@@ -158,14 +207,6 @@ unsigned CodeMetrics::CountCodeReductionForConstant(Value *V) {
158207
Instrs += NumBBInsts[TI.getSuccessor(I)];
159208
// We don't know which blocks will be eliminated, so use the average size.
160209
Reduction += InlineConstants::InstrCost*Instrs*(NumSucc-1)/NumSucc;
161-
} else if (CallInst *CI = dyn_cast<CallInst>(U)) {
162-
// Turning an indirect call into a direct call is a BIG win
163-
if (CI->getCalledValue() == V)
164-
Reduction += InlineConstants::IndirectCallBonus;
165-
} else if (InvokeInst *II = dyn_cast<InvokeInst>(U)) {
166-
// Turning an indirect call into a direct call is a BIG win
167-
if (II->getCalledValue() == V)
168-
Reduction += InlineConstants::IndirectCallBonus;
169210
} else {
170211
// Figure out if this instruction will be removed due to simple constant
171212
// propagation.
@@ -259,7 +300,8 @@ void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) {
259300
ArgumentWeights.reserve(F->arg_size());
260301
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
261302
ArgumentWeights.push_back(ArgInfo(Metrics.CountCodeReductionForConstant(I),
262-
Metrics.CountCodeReductionForAlloca(I)));
303+
Metrics.CountCodeReductionForAlloca(I),
304+
Metrics.CountBonusForConstant(I)));
263305
}
264306

265307
/// NeverInline - returns true if the function should never be inlined into
@@ -383,7 +425,8 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
383425
// away with this information.
384426
} else if (isa<Constant>(I)) {
385427
if (ArgNo < CalleeFI->ArgumentWeights.size())
386-
InlineCost -= CalleeFI->ArgumentWeights[ArgNo].ConstantWeight;
428+
InlineCost -= (CalleeFI->ArgumentWeights[ArgNo].ConstantWeight +
429+
CalleeFI->ArgumentWeights[ArgNo].ConstantBonus);
387430
}
388431
}
389432

0 commit comments

Comments
 (0)