Add auto inline of functions that trivially compute to a constat with constant arguments
This commit is contained in:
parent
1be469aa9b
commit
55affa4de9
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1898,7 +1898,39 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -36,6 +36,7 @@ protected:
|
|||
GrowingArray<int> mParams;
|
||||
InterCodeBasicBlock * mReturn;
|
||||
int mResult, mDepth, mVarIndex;
|
||||
bool mConstExpr;
|
||||
|
||||
InlineMapper(void)
|
||||
: mParams(-1), mResult(-1), mDepth(0)
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue