Add auto inline of functions that trivially compute to a constat with constant arguments

This commit is contained in:
drmortalwombat 2022-01-10 20:05:51 +01:00
parent 1be469aa9b
commit 55affa4de9
7 changed files with 133 additions and 34 deletions

View File

@ -216,35 +216,24 @@ float sqrt(float f)
bool isinf(float f)
{
__asm
{
lda #$00
sta accu + 1
asl f + 2
lda f + 3
rol
eor #$ff
beq W1
lda #$01
W1:
eor #$01
sta accu
}
union {
float f;
int i[2];
} x;
x.f = f;
return ((x.i[0] >> 7) & 0xff) == 0xff;
}
bool isfinite(float f)
{
__asm
{
lda #$00
sta accu + 1
asl f + 2
lda f + 3
rol
eor #$ff
beq W1
lda #$01
W1:
sta accu
}
union {
float f;
int i[2];
} x;
x.f = f;
return ((x.i[0] >> 7) & 0xff) != 0xff;
}

View File

@ -71,8 +71,9 @@ static const uint32 DTF_FUNC_VARIABLE = 0x00040000;
static const uint32 DTF_FUNC_ASSEMBLER = 0x00080000;
static const uint32 DTF_FUNC_RECURSIVE = 0x00100000;
static const uint32 DTF_FUNC_ANALYZING = 0x00200000;
static const uint32 DTF_FUNC_CONSTEXPR = 0x00400000;
static const uint32 DTF_VAR_ALIASING = 0x00400000;
static const uint32 DTF_VAR_ALIASING = 0x00800000;
class Declaration;

View File

@ -39,12 +39,15 @@ void GlobalAnalyzer::DumpCallGraph(void)
{
for (int j = 0; j < decs.Size(); j++)
{
printf("CALL %s[%d] -> %d -> %s[%d]\n", from->mIdent->mString, from->mComplexity, calls[j], decs[j]->mIdent->mString, decs[j]->mComplexity);
if (decs[j]->mType == DT_CONST_FUNCTION)
printf("CALL %s[%d, %08x] -> %d -> %s[%d, %08x]\n", from->mIdent->mString, from->mComplexity, from->mFlags, calls[j], decs[j]->mIdent->mString, decs[j]->mComplexity, decs[j]->mFlags);
else
printf("CALL %s[%d, %08x] -> %d\n", from->mIdent->mString, from->mComplexity, from->mFlags, calls[j]);
}
}
else
{
printf("LEAF %d -> %s[%d]\n", from->mCallers.Size(), from->mIdent->mString, from->mComplexity );
printf("LEAF %d -> %s[%d, %08x]\n", from->mCallers.Size(), from->mIdent->mString, from->mComplexity, from->mFlags );
}
}
}
@ -144,7 +147,10 @@ void GlobalAnalyzer::AutoInline(void)
void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
{
if (dec->mFlags & DTF_FUNC_ANALYZING)
{
dec->mFlags |= DTF_FUNC_RECURSIVE;
dec->mFlags &= ~DTF_FUNC_CONSTEXPR;
}
if (!(dec->mFlags & DTF_ANALYZED))
{
@ -154,9 +160,12 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
dec->mFlags |= DTF_ANALYZED;
if (dec->mFlags & DTF_INTRINSIC)
;
dec->mFlags |= DTF_FUNC_CONSTEXPR;
else if (dec->mFlags & DTF_DEFINED)
{
dec->mFlags |= DTF_FUNC_CONSTEXPR;
Analyze(exp, dec);
}
else
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mIdent->mString);
@ -257,7 +266,11 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
return exp->mDecValue;
case EX_VARIABLE:
if (!(exp->mDecValue->mFlags & DTF_STATIC) && !(exp->mDecValue->mFlags & DTF_GLOBAL))
if ((exp->mDecValue->mFlags & DTF_STATIC) || (exp->mDecValue->mFlags & DTF_GLOBAL))
{
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
}
else
{
if (!(exp->mDecValue->mFlags & DTF_ANALYZED))
{
@ -326,6 +339,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
} while (exp);
break;
case EX_WHILE:
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
break;
@ -338,6 +353,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
case EX_ELSE:
break;
case EX_FOR:
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (exp->mLeft->mRight)
ldec = Analyze(exp->mLeft->mRight, procDec);
if (exp->mLeft->mLeft->mLeft)
@ -372,6 +389,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
break;
case EX_ASSEMBLER:
procDec->mFlags |= DTF_FUNC_ASSEMBLER;
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
AnalyzeAssembler(exp, procDec);
break;
case EX_UNDEFINED:
@ -406,6 +424,9 @@ void GlobalAnalyzer::RegisterCall(Declaration* from, Declaration* to)
{
if (to->mType == DT_CONST_FUNCTION)
{
if (!(to->mFlags & DTF_FUNC_CONSTEXPR))
from->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (to->mCallers.Size() == 0)
mCalledFunctions.Push(to);
to->mCallers.Push(from);
@ -415,12 +436,14 @@ void GlobalAnalyzer::RegisterCall(Declaration* from, Declaration* to)
}
else if (to->mType == DT_TYPE_FUNCTION)
{
from->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (from->mCalled.Size() == 0)
mCallingFunctions.Push(from);
from->mCalled.Push(to);
}
else if (to->mType == DT_TYPE_POINTER && to->mBase->mType == DT_TYPE_FUNCTION)
{
from->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (from->mCalled.Size() == 0)
mCallingFunctions.Push(from);
from->mCalled.Push(to->mBase);

View File

@ -1897,8 +1897,40 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
return ExValue(TheVoidTypeDeclaration);
}
}
if (exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION && (exp->mLeft->mDecValue->mFlags & DTF_INLINE) && !(inlineMapper && inlineMapper->mDepth > 10))
bool canInline = exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION && !(inlineMapper && inlineMapper->mDepth > 10);
bool doInline = false, inlineConstexpr = false;
if (canInline)
{
if (inlineMapper && inlineMapper->mConstExpr)
inlineConstexpr = true;
else if (exp->mLeft->mDecValue->mFlags & DTF_FUNC_CONSTEXPR)
{
Expression* pex = exp->mRight;
inlineConstexpr = true;
while (inlineConstexpr && pex)
{
if (pex->mType == EX_LIST)
{
if (pex->mLeft->mType != EX_CONSTANT)
inlineConstexpr = false;
pex = pex->mRight;
}
else
{
if (pex->mType != EX_CONSTANT)
inlineConstexpr = false;
pex = nullptr;
}
}
}
if (inlineConstexpr || (exp->mLeft->mDecValue->mFlags & DTF_INLINE))
doInline = true;
}
if (doInline)
{
Declaration* fdec = exp->mLeft->mDecValue;
Expression* fexp = fdec->mValue;
@ -1907,6 +1939,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InlineMapper nmapper;
nmapper.mReturn = new InterCodeBasicBlock();
nmapper.mVarIndex = proc->mNumLocals;
nmapper.mConstExpr = inlineConstexpr;
proc->mNumLocals += fdec->mNumVars;
if (inlineMapper)
nmapper.mDepth = inlineMapper->mDepth + 1;

View File

@ -36,6 +36,7 @@ protected:
GrowingArray<int> mParams;
InterCodeBasicBlock * mReturn;
int mResult, mDepth, mVarIndex;
bool mConstExpr;
InlineMapper(void)
: mParams(-1), mResult(-1), mDepth(0)

View File

@ -9646,6 +9646,43 @@ bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& bre
return false;
}
bool NativeCodeBasicBlock::MoveIndirectLoadStoreDown(int at)
{
int j = at + 2;
while (j < mIns.Size())
{
if (mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at + 1].mAddress)
{
if (!(mIns[j].mLive & LIVE_MEM) && HasAsmInstructionMode(mIns[j].mType, ASMIM_INDIRECT_Y))
{
mIns[j].mMode = ASMIM_INDIRECT_Y;
mIns[j].mAddress = mIns[at].mAddress;
mIns[at + 0].mType = ASMIT_NOP; mIns[at + 0].mMode = ASMIM_IMPLIED;
mIns[at + 1].mType = ASMIT_NOP; mIns[at + 1].mMode = ASMIM_IMPLIED;
for (int k = at; k < j; k++)
mIns[k].mLive |= LIVE_CPU_REG_Y;
return true;
}
return false;
}
if (mIns[j].ChangesYReg())
return false;
if (mIns[j].ChangesZeroPage(mIns[at].mAddress) || mIns[j].ChangesZeroPage(mIns[at].mAddress + 1))
return false;
if (mIns[j].ChangesGlobalMemory())
return false;
j++;
}
return false;
}
bool NativeCodeBasicBlock::MoveIndirectLoadStoreUp(int at)
{
int j = at - 1;
@ -11552,6 +11589,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
}
#endif
#if 1
// move load (),y store zp down to potential user
for (int i = 2; i + 2 < mIns.Size(); i++)
{
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
{
if (MoveIndirectLoadStoreDown(i))
changed = true;
}
}
#endif
#if 1
// move load - store abs up to initial store
//

View File

@ -201,6 +201,8 @@ public:
bool MoveLoadStoreXUp(int at);
bool MoveLoadImmStoreAbsoluteUp(int at);
bool MoveIndirectLoadStoreDown(int at);
bool MoveIndirectLoadStoreUp(int at);
bool MoveAbsoluteLoadStoreUp(int at);
bool MoveLoadStoreOutOfXYRangeUp(int at);