Improve auto inlining decision with O2
This commit is contained in:
parent
2698595302
commit
6b98a44fc0
|
@ -1,7 +1,7 @@
|
||||||
#include "GlobalAnalyzer.h"
|
#include "GlobalAnalyzer.h"
|
||||||
|
|
||||||
GlobalAnalyzer::GlobalAnalyzer(Errors* errors, Linker* linker)
|
GlobalAnalyzer::GlobalAnalyzer(Errors* errors, Linker* linker)
|
||||||
: mErrors(errors), mLinker(linker), mCalledFunctions(nullptr), mCallingFunctions(nullptr), mVariableFunctions(nullptr), mFunctions(nullptr), mGlobalVariables(nullptr), mCompilerOptions(COPT_DEFAULT)
|
: mErrors(errors), mLinker(linker), mCalledFunctions(nullptr), mCallingFunctions(nullptr), mVariableFunctions(nullptr), mFunctions(nullptr), mGlobalVariables(nullptr), mTopoFunctions(nullptr), mCompilerOptions(COPT_DEFAULT)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -132,16 +132,36 @@ void GlobalAnalyzer::AutoZeroPage(LinkerSection* lszp, int zpsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GlobalAnalyzer::TopoSort(Declaration* procDec)
|
||||||
|
{
|
||||||
|
if (!(procDec->mFlags & DTF_FUNC_ANALYZING))
|
||||||
|
{
|
||||||
|
procDec->mFlags |= DTF_FUNC_ANALYZING;
|
||||||
|
if (!mTopoFunctions.Contains(procDec))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < procDec->mCalled.Size(); i++)
|
||||||
|
TopoSort(procDec->mCalled[i]);
|
||||||
|
mTopoFunctions.Push(procDec);
|
||||||
|
}
|
||||||
|
procDec->mFlags &= ~DTF_FUNC_ANALYZING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GlobalAnalyzer::AutoInline(void)
|
void GlobalAnalyzer::AutoInline(void)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < mFunctions.Size(); i++)
|
||||||
|
TopoSort(mFunctions[i]);
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
changed = false;
|
changed = false;
|
||||||
|
|
||||||
for (int i = 0; i < mFunctions.Size(); i++)
|
// Reverse order, to check inline from bottom to top of call graph
|
||||||
|
for (int i = 0; i< mTopoFunctions.Size(); i++)
|
||||||
{
|
{
|
||||||
Declaration* f = mFunctions[i];
|
Declaration* f = mTopoFunctions[i];
|
||||||
|
|
||||||
if (!(f->mFlags & DTF_INLINE) &&
|
if (!(f->mFlags & DTF_INLINE) &&
|
||||||
!(f->mFlags & DTF_EXPORT) &&
|
!(f->mFlags & DTF_EXPORT) &&
|
||||||
!(f->mFlags & DTF_PREVENT_INLINE) &&
|
!(f->mFlags & DTF_PREVENT_INLINE) &&
|
||||||
|
@ -159,15 +179,23 @@ void GlobalAnalyzer::AutoInline(void)
|
||||||
dec = dec->mNext;
|
dec = dec->mNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cost = (f->mComplexity - 20 * nparams - 20);
|
int cost = (f->mComplexity - 20 * nparams - 10);
|
||||||
|
|
||||||
// printf("CHEK INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size());
|
// printf("CHECK INLINING %s (%d) %d * (%d - 1)\n", f->mIdent->mString, f->mComplexity, cost, f->mCallers.Size());
|
||||||
|
|
||||||
bool doinline = false;
|
bool doinline = false;
|
||||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE))
|
if ((f->mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE))
|
||||||
doinline = true;
|
doinline = true;
|
||||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && (cost * (f->mCallers.Size() - 1) <= 0))
|
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && ((cost - 20) * (f->mCallers.Size() - 1) <= 20))
|
||||||
doinline = true;
|
{
|
||||||
|
if (f->mCallers.Size() == 1 && f->mComplexity > 100)
|
||||||
|
{
|
||||||
|
if (f->mCallers[0]->mCalled.Size() == 1)
|
||||||
|
doinline = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
doinline = true;
|
||||||
|
}
|
||||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE_ALL) && (cost * (f->mCallers.Size() - 1) <= 10000))
|
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE_ALL) && (cost * (f->mCallers.Size() - 1) <= 10000))
|
||||||
doinline = true;
|
doinline = true;
|
||||||
|
|
||||||
|
@ -734,6 +762,11 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
|
|
||||||
return exp->mDecValue;
|
return exp->mDecValue;
|
||||||
case EX_VARIABLE:
|
case EX_VARIABLE:
|
||||||
|
if (exp->mDecType->IsSimpleType())
|
||||||
|
procDec->mComplexity += 5 * exp->mDecType->mSize;
|
||||||
|
else
|
||||||
|
procDec->mComplexity += 10;
|
||||||
|
|
||||||
if (mCompilerOptions & COPT_DEBUGINFO)
|
if (mCompilerOptions & COPT_DEBUGINFO)
|
||||||
exp->mDecValue->mReferences.Push(exp);
|
exp->mDecValue->mReferences.Push(exp);
|
||||||
|
|
||||||
|
@ -765,7 +798,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
return exp->mDecValue;
|
return exp->mDecValue;
|
||||||
case EX_INITIALIZATION:
|
case EX_INITIALIZATION:
|
||||||
case EX_ASSIGNMENT:
|
case EX_ASSIGNMENT:
|
||||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
procDec->mComplexity += 5 * exp->mLeft->mDecType->mSize;
|
||||||
|
|
||||||
ldec = Analyze(exp->mLeft, procDec, true);
|
ldec = Analyze(exp->mLeft, procDec, true);
|
||||||
rdec = Analyze(exp->mRight, procDec, false);
|
rdec = Analyze(exp->mRight, procDec, false);
|
||||||
|
@ -826,7 +859,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
|
|
||||||
return Analyze(exp->mLeft, procDec, true);
|
return Analyze(exp->mLeft, procDec, true);
|
||||||
case EX_INDEX:
|
case EX_INDEX:
|
||||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
procDec->mComplexity += 10 * exp->mRight->mDecType->mSize;
|
||||||
|
|
||||||
ldec = Analyze(exp->mLeft, procDec, lhs);
|
ldec = Analyze(exp->mLeft, procDec, lhs);
|
||||||
if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
|
if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
|
||||||
|
|
|
@ -11,6 +11,7 @@ public:
|
||||||
~GlobalAnalyzer(void);
|
~GlobalAnalyzer(void);
|
||||||
|
|
||||||
void DumpCallGraph(void);
|
void DumpCallGraph(void);
|
||||||
|
void TopoSort(Declaration * procDec);
|
||||||
void AutoInline(void);
|
void AutoInline(void);
|
||||||
void CheckFastcall(Declaration* procDec, bool head);
|
void CheckFastcall(Declaration* procDec, bool head);
|
||||||
void CheckInterrupt(void);
|
void CheckInterrupt(void);
|
||||||
|
@ -27,7 +28,7 @@ protected:
|
||||||
Errors* mErrors;
|
Errors* mErrors;
|
||||||
Linker* mLinker;
|
Linker* mLinker;
|
||||||
|
|
||||||
GrowingArray<Declaration*> mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions;
|
GrowingArray<Declaration*> mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions, mTopoFunctions;
|
||||||
GrowingArray<Declaration*> mGlobalVariables;
|
GrowingArray<Declaration*> mGlobalVariables;
|
||||||
|
|
||||||
void AnalyzeInit(Declaration* mdec);
|
void AnalyzeInit(Declaration* mdec);
|
||||||
|
|
|
@ -32344,6 +32344,19 @@ bool NativeCodeBasicBlock::OptimizeSingleEntryLoop(NativeCodeProcedure* proc)
|
||||||
aimm = true;
|
aimm = true;
|
||||||
ains = mIns[i];
|
ains = mIns[i];
|
||||||
}
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && !this->ChangesZeroPage(mIns[i].mAddress))
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
while (j < lblocks.Size() && !lblocks[j]->ChangesZeroPage(mIns[i].mAddress))
|
||||||
|
j++;
|
||||||
|
if (j == lblocks.Size())
|
||||||
|
{
|
||||||
|
aimm = true;
|
||||||
|
ains = mIns[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
aimm = false;
|
||||||
|
}
|
||||||
else if (mIns[i].mType == ASMIT_STA && mIns[i].mMode == ASMIM_ZERO_PAGE && aimm)
|
else if (mIns[i].mType == ASMIT_STA && mIns[i].mMode == ASMIM_ZERO_PAGE && aimm)
|
||||||
{
|
{
|
||||||
int reg = mIns[i].mAddress;
|
int reg = mIns[i].mAddress;
|
||||||
|
|
Loading…
Reference in New Issue