mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 22:04:55 +00:00
Reapply 124275 since the Dragonegg failure was unreproducible.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124641 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4d98ee5234
commit
8e2da0ce9d
@ -96,10 +96,9 @@ namespace llvm {
|
|||||||
public:
|
public:
|
||||||
unsigned ConstantWeight;
|
unsigned ConstantWeight;
|
||||||
unsigned AllocaWeight;
|
unsigned AllocaWeight;
|
||||||
unsigned ConstantBonus;
|
|
||||||
|
|
||||||
ArgInfo(unsigned CWeight, unsigned AWeight, unsigned CBonus)
|
ArgInfo(unsigned CWeight, unsigned AWeight)
|
||||||
: ConstantWeight(CWeight), AllocaWeight(AWeight), ConstantBonus(CBonus)
|
: ConstantWeight(CWeight), AllocaWeight(AWeight)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,6 +124,7 @@ namespace llvm {
|
|||||||
// the ValueMap will update itself when this happens.
|
// the ValueMap will update itself when this happens.
|
||||||
ValueMap<const Function *, FunctionInfo> CachedFunctionInfo;
|
ValueMap<const Function *, FunctionInfo> CachedFunctionInfo;
|
||||||
|
|
||||||
|
unsigned CountBonusForConstant(Value *V);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// getInlineCost - The heuristic used to determine if we should inline the
|
/// getInlineCost - The heuristic used to determine if we should inline the
|
||||||
|
@ -142,64 +142,6 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
|
|||||||
NumBBInsts[BB] = NumInsts - NumInstsBeforeThisBB;
|
NumBBInsts[BB] = NumInsts - NumInstsBeforeThisBB;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CountBonusForConstant - Figure out an approximation for how much per-call
|
|
||||||
// performance boost we can expect if the specified value is constant.
|
|
||||||
unsigned CodeMetrics::CountBonusForConstant(Value *V) {
|
|
||||||
unsigned Bonus = 0;
|
|
||||||
bool indirectCallBonus = false;
|
|
||||||
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){
|
|
||||||
User *U = *UI;
|
|
||||||
if (CallInst *CI = dyn_cast<CallInst>(U)) {
|
|
||||||
// Turning an indirect call into a direct call is a BIG win
|
|
||||||
if (CI->getCalledValue() == V)
|
|
||||||
indirectCallBonus = true;
|
|
||||||
}
|
|
||||||
else if (InvokeInst *II = dyn_cast<InvokeInst>(U)) {
|
|
||||||
// Turning an indirect call into a direct call is a BIG win
|
|
||||||
if (II->getCalledValue() == V)
|
|
||||||
indirectCallBonus = true;
|
|
||||||
}
|
|
||||||
// FIXME: Eliminating conditional branches and switches should
|
|
||||||
// also yield a per-call performance boost.
|
|
||||||
else {
|
|
||||||
// Figure out the bonuses that wll accrue due to simple constant
|
|
||||||
// propagation.
|
|
||||||
Instruction &Inst = cast<Instruction>(*U);
|
|
||||||
|
|
||||||
// We can't constant propagate instructions which have effects or
|
|
||||||
// read memory.
|
|
||||||
//
|
|
||||||
// FIXME: It would be nice to capture the fact that a load from a
|
|
||||||
// pointer-to-constant-global is actually a *really* good thing to zap.
|
|
||||||
// Unfortunately, we don't know the pointer that may get propagated here,
|
|
||||||
// so we can't make this decision.
|
|
||||||
if (Inst.mayReadFromMemory() || Inst.mayHaveSideEffects() ||
|
|
||||||
isa<AllocaInst>(Inst))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
bool AllOperandsConstant = true;
|
|
||||||
for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i)
|
|
||||||
if (!isa<Constant>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
|
|
||||||
AllOperandsConstant = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AllOperandsConstant)
|
|
||||||
Bonus += CountBonusForConstant(&Inst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: The only reason we're applying the bonus once is while it's great
|
|
||||||
// to devirtualize calls the magnitude of the bonus x number of call sites
|
|
||||||
// can lead to a huge code explosion when we prefer to inline 1000 instruction
|
|
||||||
// functions that have 10 call sites. This should be made a function of the
|
|
||||||
// estimated inline penalty/benefit + the indirect call bonus.
|
|
||||||
if (indirectCallBonus) Bonus += InlineConstants::IndirectCallBonus;
|
|
||||||
|
|
||||||
return Bonus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// CountCodeReductionForConstant - Figure out an approximation for how many
|
// CountCodeReductionForConstant - Figure out an approximation for how many
|
||||||
// instructions will be constant folded if the specified value is constant.
|
// instructions will be constant folded if the specified value is constant.
|
||||||
//
|
//
|
||||||
@ -309,17 +251,14 @@ void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) {
|
|||||||
ArgumentWeights.reserve(F->arg_size());
|
ArgumentWeights.reserve(F->arg_size());
|
||||||
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
|
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
|
||||||
ArgumentWeights.push_back(ArgInfo(Metrics.CountCodeReductionForConstant(I),
|
ArgumentWeights.push_back(ArgInfo(Metrics.CountCodeReductionForConstant(I),
|
||||||
Metrics.CountCodeReductionForAlloca(I),
|
Metrics.CountCodeReductionForAlloca(I)));
|
||||||
Metrics.CountBonusForConstant(I)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NeverInline - returns true if the function should never be inlined into
|
/// NeverInline - returns true if the function should never be inlined into
|
||||||
/// any caller
|
/// any caller
|
||||||
bool InlineCostAnalyzer::FunctionInfo::NeverInline()
|
bool InlineCostAnalyzer::FunctionInfo::NeverInline() {
|
||||||
{
|
|
||||||
return (Metrics.callsSetJmp || Metrics.isRecursive ||
|
return (Metrics.callsSetJmp || Metrics.isRecursive ||
|
||||||
Metrics.containsIndirectBr);
|
Metrics.containsIndirectBr);
|
||||||
|
|
||||||
}
|
}
|
||||||
// getSpecializationBonus - The heuristic used to determine the per-call
|
// getSpecializationBonus - The heuristic used to determine the per-call
|
||||||
// performance boost for using a specialization of Callee with argument
|
// performance boost for using a specialization of Callee with argument
|
||||||
@ -343,8 +282,14 @@ int InlineCostAnalyzer::getSpecializationBonus(Function *Callee,
|
|||||||
if (CalleeFI->Metrics.NumBlocks == 0)
|
if (CalleeFI->Metrics.NumBlocks == 0)
|
||||||
CalleeFI->analyzeFunction(Callee);
|
CalleeFI->analyzeFunction(Callee);
|
||||||
|
|
||||||
for (unsigned i = 0, s = SpecializedArgNos.size(); i < s; ++i )
|
unsigned ArgNo = 0;
|
||||||
Bonus += CalleeFI->ArgumentWeights[SpecializedArgNos[i]].ConstantBonus;
|
unsigned i = 0;
|
||||||
|
for (Function::arg_iterator I = Callee->arg_begin(), E = Callee->arg_end();
|
||||||
|
I != E; ++I, ++ArgNo)
|
||||||
|
if (ArgNo == SpecializedArgNos[i]) {
|
||||||
|
++i;
|
||||||
|
Bonus += CountBonusForConstant(I);
|
||||||
|
}
|
||||||
|
|
||||||
// Calls usually take a long time, so they make the specialization gain
|
// Calls usually take a long time, so they make the specialization gain
|
||||||
// smaller.
|
// smaller.
|
||||||
@ -353,6 +298,62 @@ int InlineCostAnalyzer::getSpecializationBonus(Function *Callee,
|
|||||||
return Bonus;
|
return Bonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountBonusForConstant - Figure out an approximation for how much per-call
|
||||||
|
// performance boost we can expect if the specified value is constant.
|
||||||
|
unsigned InlineCostAnalyzer::CountBonusForConstant(Value *V) {
|
||||||
|
unsigned Bonus = 0;
|
||||||
|
bool indirectCallBonus = false;
|
||||||
|
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){
|
||||||
|
User *U = *UI;
|
||||||
|
if (CallInst *CI = dyn_cast<CallInst>(U)) {
|
||||||
|
// Turning an indirect call into a direct call is a BIG win
|
||||||
|
if (CI->getCalledValue() == V)
|
||||||
|
indirectCallBonus = true;
|
||||||
|
}
|
||||||
|
else if (InvokeInst *II = dyn_cast<InvokeInst>(U)) {
|
||||||
|
// Turning an indirect call into a direct call is a BIG win
|
||||||
|
if (II->getCalledValue() == V)
|
||||||
|
indirectCallBonus = true;
|
||||||
|
}
|
||||||
|
// FIXME: Eliminating conditional branches and switches should
|
||||||
|
// also yield a per-call performance boost.
|
||||||
|
else {
|
||||||
|
// Figure out the bonuses that wll accrue due to simple constant
|
||||||
|
// propagation.
|
||||||
|
Instruction &Inst = cast<Instruction>(*U);
|
||||||
|
|
||||||
|
// We can't constant propagate instructions which have effects or
|
||||||
|
// read memory.
|
||||||
|
//
|
||||||
|
// FIXME: It would be nice to capture the fact that a load from a
|
||||||
|
// pointer-to-constant-global is actually a *really* good thing to zap.
|
||||||
|
// Unfortunately, we don't know the pointer that may get propagated here,
|
||||||
|
// so we can't make this decision.
|
||||||
|
if (Inst.mayReadFromMemory() || Inst.mayHaveSideEffects() ||
|
||||||
|
isa<AllocaInst>(Inst))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool AllOperandsConstant = true;
|
||||||
|
for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i)
|
||||||
|
if (!isa<Constant>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
|
||||||
|
AllOperandsConstant = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AllOperandsConstant)
|
||||||
|
Bonus += CountBonusForConstant(&Inst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: The only reason we're applying the bonus once is while it's great
|
||||||
|
// to devirtualize calls the magnitude of the bonus x number of call sites
|
||||||
|
// can lead to a huge code explosion when we prefer to inline 1000 instruction
|
||||||
|
// functions that have 10 call sites. This should be made a function of the
|
||||||
|
// estimated inline penalty/benefit + the indirect call bonus.
|
||||||
|
if (indirectCallBonus) Bonus += InlineConstants::IndirectCallBonus;
|
||||||
|
|
||||||
|
return Bonus;
|
||||||
|
}
|
||||||
|
|
||||||
// getInlineCost - The heuristic used to determine if we should inline the
|
// getInlineCost - The heuristic used to determine if we should inline the
|
||||||
// function call or not.
|
// function call or not.
|
||||||
@ -427,31 +428,33 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
|
|||||||
// passed into the function.
|
// passed into the function.
|
||||||
//
|
//
|
||||||
unsigned ArgNo = 0;
|
unsigned ArgNo = 0;
|
||||||
for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
|
CallSite::arg_iterator I = CS.arg_begin();
|
||||||
I != E; ++I, ++ArgNo) {
|
for (Function::arg_iterator FI = Callee->arg_begin(), FE = Callee->arg_end();
|
||||||
// Each argument passed in has a cost at both the caller and the callee
|
FI != FE; ++I, ++FI, ++ArgNo) {
|
||||||
// sides. Measurements show that each argument costs about the same as an
|
|
||||||
// instruction.
|
|
||||||
InlineCost -= InlineConstants::InstrCost;
|
|
||||||
|
|
||||||
// If an alloca is passed in, inlining this function is likely to allow
|
// If an alloca is passed in, inlining this function is likely to allow
|
||||||
// significant future optimization possibilities (like scalar promotion, and
|
// significant future optimization possibilities (like scalar promotion, and
|
||||||
// scalarization), so encourage the inlining of the function.
|
// scalarization), so encourage the inlining of the function.
|
||||||
//
|
//
|
||||||
if (isa<AllocaInst>(I)) {
|
if (isa<AllocaInst>(I))
|
||||||
if (ArgNo < CalleeFI->ArgumentWeights.size())
|
InlineCost -= CalleeFI->ArgumentWeights[ArgNo].AllocaWeight;
|
||||||
InlineCost -= CalleeFI->ArgumentWeights[ArgNo].AllocaWeight;
|
|
||||||
|
|
||||||
// If this is a constant being passed into the function, use the argument
|
// If this is a constant being passed into the function, use the argument
|
||||||
// weights calculated for the callee to determine how much will be folded
|
// weights calculated for the callee to determine how much will be folded
|
||||||
// away with this information.
|
// away with this information.
|
||||||
} else if (isa<Constant>(I)) {
|
else if (isa<Constant>(I)) {
|
||||||
if (ArgNo < CalleeFI->ArgumentWeights.size())
|
InlineCost -= CalleeFI->ArgumentWeights[ArgNo].ConstantWeight;
|
||||||
InlineCost -= (CalleeFI->ArgumentWeights[ArgNo].ConstantWeight +
|
|
||||||
CalleeFI->ArgumentWeights[ArgNo].ConstantBonus);
|
// Compute any constant bonus due to inlining we want to give here.
|
||||||
|
InlineCost -= CountBonusForConstant(FI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Each argument passed in has a cost at both the caller and the callee
|
||||||
|
// sides. Measurements show that each argument costs about the same as an
|
||||||
|
// instruction.
|
||||||
|
InlineCost -= (CS.arg_size() * InlineConstants::InstrCost);
|
||||||
|
|
||||||
// If there is only one call of the function, and it has internal linkage,
|
// If there is only one call of the function, and it has internal linkage,
|
||||||
// make it almost guaranteed to be inlined.
|
// make it almost guaranteed to be inlined.
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user