Improve auto inlining decision with O2

This commit is contained in:
drmortalwombat 2024-02-18 14:35:41 +01:00
parent 2698595302
commit 6b98a44fc0
3 changed files with 57 additions and 10 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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;