Direct parameter forwarding

This commit is contained in:
drmortalwombat 2023-12-02 10:58:20 +01:00
parent 003306f961
commit 8ab46e29dd
9 changed files with 310 additions and 51 deletions

View File

@ -1,5 +1,6 @@
#include "Declaration.h"
#include "Constexpr.h"
#include "Linker.h"
#include <math.h>
DeclarationScope::DeclarationScope(DeclarationScope* parent, ScopeLevel level, const Ident* name)
@ -451,10 +452,33 @@ Expression* Expression::LogicInvertExpression(void)
}
}
Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSection)
Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSection, Linker* linker)
{
if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT)
if (mType == EX_PREFIX && mToken == TK_BANKOF && linker)
{
LinkerRegion* rgn;
if (mLeft->mDecValue->mSection && (rgn = linker->FindRegionOfSection(mLeft->mDecValue->mSection)))
{
uint64 i = 0;
while (i < 64 && rgn->mCartridgeBanks != (1ULL << i))
i++;
if (i < 64)
{
Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
dec->mBase = TheUnsignedCharTypeDeclaration;
dec->mInteger = i;
ex->mDecValue = dec;
ex->mDecType = dec->mBase;
return ex;
}
}
return this;
}
else if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT)
{
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
{
switch (mToken)
@ -944,7 +968,7 @@ Declaration::Declaration(const Location& loc, DecType type)
mConst(nullptr), mMutable(nullptr),
mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mMoveConstructor(nullptr), mMoveAssignment(nullptr),
mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr),
mVTable(nullptr), mTemplate(nullptr),
mVTable(nullptr), mTemplate(nullptr), mForwardParam(nullptr), mForwardCall(nullptr),
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mFriends(nullptr),
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr),

View File

@ -8,6 +8,7 @@
class LinkerObject;
class LinkerSection;
class Linker;
class Parser;
enum DecType
@ -244,7 +245,7 @@ public:
bool mConst;
Expression* LogicInvertExpression(void);
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection);
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
bool HasSideEffects(void) const;
bool IsSame(const Expression* exp) const;
@ -268,6 +269,7 @@ public:
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment;
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
Declaration * mVTable, * mClass, * mTemplate;
Declaration * mForwardParam, * mForwardCall;
Expression* mValue, * mReturn;
DeclarationScope* mScope;

View File

@ -305,7 +305,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
{
CheckFastcall(vf, false);
int n = vf->mBase->mFastCallBase + vf->mBase->mFastCallSize;
int n = vf->mBase->mFastCallSize;
if (n > nbase)
nbase = n;
}
@ -323,7 +323,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
// procDec->mBase->mFlags |= DTF_STACKCALL;
cf = cf->mBase;
int n = cf->mFastCallBase + cf->mFastCallSize;
int n = cf->mFastCallSize;
if (n > nbase)
nbase = n;
}
@ -359,7 +359,16 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
if (cf != maxf)
{
cf->mParams = maxf->mParams;
Declaration* fp = cf->mBase->mParams, * mp = maxf->mBase->mParams;
while (fp)
{
fp->mVarIndex = mp->mVarIndex;
fp = fp->mNext;
mp = mp->mNext;
}
assert(!mp);
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
cf->mBase->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize;
}
@ -373,9 +382,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
}
procDec->mFastCallBase = nbase;
procDec->mFastCallSize = 0;
procDec->mFastCallSize = nbase;
procDec->mBase->mFastCallBase = nbase;
procDec->mBase->mFastCallSize = 0;
procDec->mBase->mFastCallSize = nbase;
procDec->mFlags &= ~DTF_FUNC_ANALYZING;
@ -390,7 +399,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
}
else if (!(procDec->mBase->mFlags & DTF_VARIADIC) && !(procDec->mFlags & DTF_FUNC_VARIABLE) && !(procDec->mFlags & DTF_DYNSTACK))
{
int nparams = 0, npalign = 0;
int nparams = nbase, npalign = 0;
int numfpzero = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
int fplimit = numfpzero;
@ -407,49 +416,67 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
nparams += 2;
}
int cnparams = nparams;
Declaration* dec = procDec->mBase->mParams;
while (dec)
{
// Check for parameter crossing boundary
if (nbase + nparams < numfpzero && nbase + nparams + dec->mBase->mSize > numfpzero)
if (cnparams < numfpzero && cnparams + dec->mBase->mSize > numfpzero)
{
npalign = numfpzero - (nbase + nparams);
nparams += npalign;
npalign = numfpzero - nparams;
cnparams += npalign;
}
nparams += dec->mBase->mSize;
cnparams += dec->mBase->mSize;
dec = dec->mNext;
}
if (nbase + nparams <= fplimit)
if (cnparams <= fplimit)
{
npalign = 0;
dec = procDec->mBase->mParams;
while (dec)
{
if (dec->mForwardParam && (dec->mForwardCall->mBase->mFlags & DTF_FASTCALL) && !(dec->mForwardCall->mFlags & DTF_INLINE))
{
dec->mVarIndex = dec->mForwardParam->mVarIndex;
}
else
{
dec->mForwardParam = nullptr;
// Check for parameter crossing boundary
if (nparams < numfpzero && nparams + dec->mBase->mSize > numfpzero)
{
npalign = numfpzero - nparams;
nparams += npalign;
}
dec->mVarIndex = nparams;
nparams += dec->mBase->mSize;
}
dec = dec->mNext;
}
procDec->mFastCallBase = nbase;
procDec->mFastCallSize = nparams;
procDec->mBase->mFastCallBase = nbase;
procDec->mBase->mFastCallSize = nparams;
// Align fast call parameters to avoid crossing the zero page boundary
if (npalign)
{
Declaration* dec = procDec->mBase->mParams;
while (dec)
{
if (nbase + dec->mVarIndex + dec->mBase->mSize > numfpzero)
dec->mVarIndex += npalign;
dec = dec->mNext;
}
}
procDec->mBase->mFlags |= DTF_FASTCALL;
#if 0
printf("FASTCALL %s\n", f->mIdent->mString);
#endif
}
else
{
// printf("STACKCALL %s, %d %d\n", procDec->mIdent->mString, cnparams, fplimit);
procDec->mBase->mFlags |= DTF_STACKCALL;
}
}
else
{
// printf("STACKCALL %s, F%d\n", procDec->mIdent->mString, !!(procDec->mFlags& DTF_FUNC_VARIABLE));
procDec->mBase->mFlags |= DTF_STACKCALL;
}
}
}
void GlobalAnalyzer::CheckInterrupt(void)
@ -759,6 +786,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
return exp->mDecType;
}
else if (exp->mToken == TK_BANKOF)
{
return TheUnsignedCharTypeDeclaration;
}
else
{
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;

View File

@ -18,7 +18,9 @@ static const uint64 OPTF_VAR_CONST = (1ULL << 9);
static const uint64 OPTF_VAR_NOCONST = (1ULL << 10);
static const uint64 OPTF_SINGLE_RETURN = (1ULL << 11);
static const uint64 OPTF_MULTI_RETURN = (1ULL << 12);
static const uint64 OPTF_VAR_NO_FORWARD = (1UL << 13);
static const uint64 OPTF_SINGLE_CALL = (1ULL << 14);
static const uint64 OPTF_MULTI_CALL = (1ULL << 15);
GlobalOptimizer::GlobalOptimizer(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker)
@ -45,6 +47,7 @@ void GlobalOptimizer::Reset(void)
while (pdec)
{
pdec->mOptFlags = 0;
pdec->mForwardParam = nullptr;
pdec = pdec->mNext;
}
}
@ -278,6 +281,17 @@ bool GlobalOptimizer::Optimize(void)
if (CheckConstReturns(func->mValue))
changed = true;
if (func->mOptFlags & OPTF_MULTI_CALL)
{
Declaration* pdata = ftype->mParams;
while (pdata)
{
pdata->mForwardCall = nullptr;
pdata->mForwardParam = nullptr;
pdata = pdata->mNext;
}
}
if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL))
{
if (!(func->mOptFlags & OPTF_VAR_USED) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
@ -601,6 +615,12 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
if (flags & ANAFL_LHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
}
if (exp->mDecValue->mType == DT_ARGUMENT)
{
exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD;
exp->mDecValue->mForwardParam = nullptr;
exp->mDecValue->mForwardCall = nullptr;
}
return exp->mDecValue;
case EX_INITIALIZATION:
case EX_ASSIGNMENT:
@ -679,6 +699,10 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
}
else
{
if (procDec->mOptFlags & OPTF_SINGLE_CALL)
procDec->mOptFlags |= OPTF_MULTI_CALL;
else
procDec->mOptFlags |= OPTF_SINGLE_CALL;
RegisterCall(procDec, ldec);
}
@ -771,7 +795,22 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
if (pdec && (pdec->mFlags & DTF_FPARAM_UNUSED))
RegisterProc(Analyze(pex, procDec, 0));
else if (pdec && pdec->mBase->IsReference())
{
if (!(procDec->mBase->mFlags & DTF_VIRTUAL) && pdec && pex && pex->mType == EX_VARIABLE && pex->mDecValue->mType == DT_ARGUMENT && pex->mDecValue->mBase->IsReference() && !pex->mDecValue->mForwardParam && !(pex->mDecValue->mOptFlags & OPTF_VAR_NO_FORWARD))
{
pex->mDecValue->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
pex->mDecValue->mForwardParam = pdec;
pex->mDecValue->mForwardCall = ldec;
}
else
RegisterProc(Analyze(pex, procDec, ANAFL_LHS | ANAFL_RHS));
}
else if (!(procDec->mBase->mFlags & DTF_VIRTUAL) && pdec && pex && pex->mType == EX_VARIABLE && pex->mDecValue->mType == DT_ARGUMENT && !pex->mDecValue->mForwardParam && !(pex->mDecValue->mOptFlags & OPTF_VAR_NO_FORWARD))
{
pex->mDecValue->mOptFlags |= OPTF_VAR_USED;
pex->mDecValue->mForwardParam = pdec;
pex->mDecValue->mForwardCall = ldec;
}
else
RegisterProc(Analyze(pex, procDec, ANAFL_RHS));

View File

@ -3314,7 +3314,7 @@ void InterInstruction::FilterStaticVarsByteUsage(const GrowingVariableArray& sta
{
for (int i = 0; i < staticVars.Size(); i++)
{
if (staticVars[i]->mAliased && !providedVars[i])
if (staticVars[i]->mAliased && !providedVars.RangeFilled(staticVars[i]->mByteIndex, staticVars[i]->mSize))
requiredVars.AddRange(staticVars[i]->mByteIndex, staticVars[i]->mSize);
}
}

View File

@ -2032,7 +2032,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else if (procType->mFlags & DTF_FASTCALL)
{
ins->mConst.mMemory = IM_FPARAM;
ins->mConst.mVarIndex += procType->mFastCallBase;
// ins->mConst.mVarIndex += procType->mFastCallBase;
InitParameter(proc, dec, ins->mConst.mVarIndex);
}
else
@ -3505,7 +3505,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{
ains->mConst.mMemory = IM_FFRAME;
ains->mConst.mIntConst = 0;
ains->mConst.mVarIndex += ftype->mFastCallBase;
// ains->mConst.mVarIndex += ftype->mFastCallBase;
}
else
ains->mConst.mMemory = IM_FRAME;
@ -3787,7 +3787,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else if (procType->mFlags & DTF_FASTCALL)
{
vins->mConst.mMemory = IM_FPARAM;
vins->mConst.mVarIndex += procType->mFastCallBase;
// vins->mConst.mVarIndex += procType->mFastCallBase;
}
else
vins->mConst.mMemory = IM_PARAM;
@ -5181,15 +5181,48 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
{
proc->mFastCallProcedure = true;
if (dec->mFastCallSize > 0 && dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS)
if (dec->mFastCallSize > 0)
{
proc->mFastCallBase = dec->mFastCallBase;
if (dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS && dec->mFastCallSize > dec->mFastCallBase)
{
dec->mLinkerObject->mNumTemporaries = 1;
dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS + dec->mFastCallBase;
if (dec->mFastCallBase + dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS)
dec->mLinkerObject->mTempSizes[0] = dec->mFastCallSize;
if (dec->mFastCallSize < BC_REG_FPARAMS_END - BC_REG_FPARAMS)
dec->mLinkerObject->mTempSizes[0] = dec->mFastCallSize - dec->mFastCallBase;
else
dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - BC_REG_FPARAMS - dec->mFastCallBase;
dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - dec->mFastCallBase;
}
Declaration* pdec = dec->mBase->mParams;
while (pdec)
{
int start = pdec->mVarIndex + BC_REG_FPARAMS, end = start + pdec->mSize;
if (start < BC_REG_FPARAMS_END)
{
if (end > BC_REG_FPARAMS_END)
end = BC_REG_FPARAMS_END;
int i = 0;
while (i < dec->mLinkerObject->mNumTemporaries && (dec->mLinkerObject->mTemporaries[i] > end || dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < start))
i++;
if (i < dec->mLinkerObject->mNumTemporaries)
{
if (dec->mLinkerObject->mTemporaries[i] > start)
dec->mLinkerObject->mTemporaries[i] = start;
if (dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < end)
dec->mLinkerObject->mTempSizes[i] = end - dec->mLinkerObject->mTemporaries[i];
}
else
{
dec->mLinkerObject->mTemporaries[i] = start;
dec->mLinkerObject->mTempSizes[i] = end - start;
dec->mLinkerObject->mNumTemporaries++;
}
}
pdec = pdec->mNext;
}
}
else
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;

View File

@ -34,7 +34,7 @@ bool LinkerReference::operator==(const LinkerReference& ref)
mFlags == ref.mFlags &&
mOffset == ref.mOffset &&
mRefOffset == ref.mRefOffset &&
mObject->mMapID == ref.mObject->mMapID &&
// mObject->mMapID == ref.mObject->mMapID &&
mRefObject->mMapID == ref.mRefObject->mMapID;
}
@ -355,7 +355,7 @@ void Linker::CombineSameConst(void)
if (i == sobj->mSize)
{
i = 0;
while (i < sobj->mReferences.Size() && sobj->mReferences[i] == dobj->mReferences[i])
while (i < sobj->mReferences.Size() && *sobj->mReferences[i] == *dobj->mReferences[i])
i++;
if (i == sobj->mReferences.Size())
{
@ -1246,6 +1246,8 @@ bool Linker::WriteCrtFile(const char* filename, uint16 id)
bool Linker::WriteMapFile(const char* filename)
{
bool banked = mCartridgeBankUsed[0];
FILE* file;
fopen_s(&file, filename, "wb");
if (file)
@ -1275,6 +1277,17 @@ bool Linker::WriteMapFile(const char* filename)
if (obj->mFlags & LOBJF_REFERENCED)
{
if (banked)
{
int k = 0;
while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k)))
k++;
if (k < 64)
fprintf(file, "%02x:", k);
else
fprintf(file, "--:");
}
if (obj->mIdent)
fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString);
else
@ -1282,7 +1295,7 @@ bool Linker::WriteMapFile(const char* filename)
}
}
if (mCartridgeBankUsed[0])
if (banked)
{
fprintf(file, "\nbanks\n");
@ -1315,6 +1328,18 @@ bool Linker::WriteMapFile(const char* filename)
for (int i = 0; i < so.Size(); i++)
{
const LinkerObject* obj = so[i];
if (banked)
{
int k = 0;
while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k)))
k++;
if (k < 64)
fprintf(file, "%02x:", k);
else
fprintf(file, "--:");
}
fprintf(file, "%04x (%04x) : %s, %s:%s\n", obj->mAddress, obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString);
}

View File

@ -6377,6 +6377,66 @@ bool NativeCodeBasicBlock::LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc
return true;
}
#if 1
else if (rins1->mSrc[0].mMemory == IM_INDIRECT && wins->mSrc[1].mMemory == IM_INDIRECT && rins0->mSrc[0].mMemory == IM_FPARAM)
{
if (rins1->mSrc[0].mTemp == wins->mSrc[1].mTemp && rins1->mSrc[0].mIntConst == wins->mSrc[1].mIntConst && rins1->mSrc[0].mStride == wins->mSrc[1].mStride &&
wins->mSrc[0].mFinal && wins->mSrc[1].mFinal)
{
int size = InterTypeSize[oins->mDst.mType];
AsmInsType aop;
switch (oins->mOperator)
{
case IA_ADD:
mIns.Push(NativeCodeInstruction(oins, ASMIT_CLC));
aop = ASMIT_ADC;
break;
case IA_OR:
aop = ASMIT_ORA;
break;
case IA_XOR:
aop = ASMIT_EOR;
break;
case IA_AND:
aop = ASMIT_AND;
break;
default:
return false;
}
int offset = int(wins->mSrc[1].mIntConst);
for (int i = 0; i < size; i++)
{
while (offset >= 256)
{
mIns.Push(NativeCodeInstruction(rins1, ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp] + 1));
offset -= 256;
}
mIns.Push(NativeCodeInstruction(rins1, ASMIT_LDY, ASMIM_IMMEDIATE, offset));
mIns.Push(NativeCodeInstruction(rins1, ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(oins, ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + rins0->mSrc[0].mVarIndex + int(rins0->mSrc[0].mIntConst) + i));
mIns.Push(NativeCodeInstruction(wins, ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp]));
offset += wins->mSrc[1].mStride;
}
return true;
}
return false;
}
else if (rins0->mSrc[0].mMemory == IM_INDIRECT && wins->mSrc[1].mMemory == IM_INDIRECT && rins1->mSrc[0].mMemory == IM_FPARAM)
{
printf("OOpsie0\n");
return false;
}
#endif
else
return false;
}
@ -19561,6 +19621,8 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void)
mTempRegs += ins.mAddress;
mTempRegs += ins.mAddress + 1;
}
else if (ins.mType == ASMIT_JSR)
break;
}
}
#endif
@ -26794,11 +26856,12 @@ bool NativeCodeBasicBlock::MoveLDXUp(int at)
{
if (ins.mLive & LIVE_CPU_REG_Z)
return false;
ins.mLive |= LIVE_CPU_REG_A;
mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAX));
mIns.Remove(at + 1);
while (i < at)
while (i <= at)
{
mIns[i].mLive |= LIVE_CPU_REG_X;
i++;
@ -26825,11 +26888,12 @@ bool NativeCodeBasicBlock::MoveLDYUp(int at)
{
if (ins.mLive & LIVE_CPU_REG_Z)
return false;
ins.mLive |= LIVE_CPU_REG_A;
mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAY));
mIns.Remove(at + 1);
while (i < at)
while (i <= at)
{
mIns[i].mLive |= LIVE_CPU_REG_Y;
i++;
@ -32931,6 +32995,9 @@ bool NativeCodeBasicBlock::OptimizeXYSimpleLoop(void)
mIns.Insert(sz - 2, NativeCodeInstruction(mIns[i - 3].mIns, ASMIT_INX));
sz++;
changed = true;
mEntryRequiredRegs += CPU_REG_X;
mExitRequiredRegs += CPU_REG_X;
pblock->mExitRequiredRegs += CPU_REG_X;
}
}
}
@ -38371,7 +38438,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
else if (
mIns[i + 0].mType == ASMIT_STA &&
mIns[i + 1].IsShiftOrInc() &&
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) && !mIns[i + 2].SameEffectiveAddress(mIns[i + 1]) && !(mIns[i + 2].mLive & LIVE_CPU_REG_Z))
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) &&
!mIns[i + 2].SameEffectiveAddress(mIns[i + 1]) &&
!(mIns[i + 2].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && (mIns[i + 1].mAddress == mIns[i + 2].mAddress || mIns[i + 1].mAddress == mIns[i + 2].mAddress + 1)) &&
!(mIns[i + 2].mLive & LIVE_CPU_REG_Z))
{
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mLive |= LIVE_CPU_REG_A;
@ -39451,6 +39521,32 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDX && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS) && !(mIns[i + 0].mFlags & NCIF_VOLATILE) &&
mIns[i + 1].mType == ASMIT_STX && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 1].mFlags & NCIF_VOLATILE) &&
mIns[i + 2].mType == ASMIT_STA && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 2].mFlags & NCIF_VOLATILE) &&
!mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) && !mIns[i + 1].SameEffectiveAddress(mIns[i + 2]))
{
NativeCodeInstruction ins(mIns[i + 2]);
mIns.Remove(i + 2);
mIns.Insert(i, ins);
mIns[i + 1].mLive |= ins.mLive & LIVE_CPU_REG_A;
mIns[i + 2].mLive |= ins.mLive & LIVE_CPU_REG_A;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDY && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS) && !(mIns[i + 0].mFlags & NCIF_VOLATILE) &&
mIns[i + 1].mType == ASMIT_STY && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 1].mFlags & NCIF_VOLATILE) &&
mIns[i + 2].mType == ASMIT_STA && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 2].mFlags & NCIF_VOLATILE) &&
!mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) && !mIns[i + 1].SameEffectiveAddress(mIns[i + 2]))
{
NativeCodeInstruction ins(mIns[i + 2]);
mIns.Remove(i + 2);
mIns.Insert(i, ins);
mIns[i + 1].mLive |= ins.mLive & LIVE_CPU_REG_A;
mIns[i + 2].mLive |= ins.mLive & LIVE_CPU_REG_A;
progress = true;
}
else if (
mIns[i + 0].ChangesAccuAndFlag() &&
(mIns[i + 1].mType == ASMIT_INC || mIns[i + 1].mType == ASMIT_DEC) &&
@ -43527,7 +43623,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "interpret_expression");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "valinc");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -44325,8 +44421,8 @@ void NativeCodeProcedure::Optimize(void)
ResetVisited();
if (mEntryBlock->PeepHoleOptimizer(this, step))
changed = true;
#endif
if (step == 2)
{
ResetVisited();
@ -44546,6 +44642,11 @@ void NativeCodeProcedure::Optimize(void)
#endif
}
#endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
if (step > 4 && !changed)
{
@ -44561,6 +44662,10 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
#if 1
if (step == 5 || step == 6)
@ -44921,7 +45026,7 @@ void NativeCodeProcedure::Optimize(void)
if (step == 11)
{
if (changed)
if (changed && cnt < 20)
swappedXY = false;
else if (!swappedXY)
{

View File

@ -7233,7 +7233,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
nexp->mDecType = nexp->mLeft->mDecType;
}
nexp = CheckOperatorOverload(nexp);
return nexp->ConstantFold(mErrors, mDataSection);
return nexp->ConstantFold(mErrors, mDataSection, mCompilationUnits->mLinker);
}
else
return ParsePostfixExpression(lhs);