Unify instruction dependency check in optimizer

This commit is contained in:
drmortalwombat 2023-05-06 18:28:59 +02:00
parent 7d12fd4c02
commit 0639fdc008
17 changed files with 400 additions and 211 deletions

View File

@ -1,5 +1,56 @@
#include "setjmp.h"
int setjmpsp(jmp_buf env, void * sp)
{
__asm
{
ldy #0
lda sp + 0
sta (env), y
iny
lda sp + 1
sta (env), y
iny
lda __ip + 0
sta (env), y
iny
lda __ip + 1
sta (env), y
iny
lda __fp + 0
sta (env), y
iny
lda __fp + 1
sta (env), y
iny
ldx #0
l1:
lda __sregs, x
sta (env), y
iny
inx
cpx #32
bne l1
tsx
txa
sta (env), y
inx
l2:
iny
lda $0100, x
sta (env), y
inx
bne l2
}
return 0;
}
int setjmp(jmp_buf env)
{
__asm
@ -27,29 +78,28 @@ int setjmp(jmp_buf env)
iny
ldx #0
loop:
l1:
lda __sregs, x
sta (env), y
iny
inx
cpx #32
bne loop
bne l1
tsx
txa
sta (env), y
inx
l2:
iny
lda $0101, x
lda $0100, x
sta (env), y
iny
lda $0102, x
sta (env), y
iny
inx
bne l2
}
return 0
return 0;
}
#pragma native(setjmp)
@ -81,26 +131,25 @@ void longjmp(jmp_buf env, int value)
iny
ldx #0
loop:
l1:
lda (env), y
sta __sregs, x
iny
inx
cpx #32
bne loop
bne l1
lda (env), y
tax
txs
iny
lda (env), y
sta $0101, x
inx
l2:
iny
lda (env), y
sta $0102, x
iny
sta $0100, x
inx
bne l2
lda value
sta __accu

View File

@ -5,14 +5,17 @@ struct _jmp_buf
{
void * sp, * ip, * fp;
char tmps[32];
char cpup, cpul, cpuh;
char cpup;
char stack[48];
};
typedef struct _jmp_buf jmp_buf[1];
int setjmp(jmp_buf env);
__dynstack int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int value);
__dynstack int setjmpsp(jmp_buf env, void * sp);
__dynstack void longjmp(jmp_buf env, int value);
#pragma compile("setjmp.c")

View File

@ -972,7 +972,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
return true;
}
int Compiler::ExecuteCode(bool profile)
int Compiler::ExecuteCode(bool profile, bool trace)
{
Location loc;
@ -985,12 +985,12 @@ int Compiler::ExecuteCode(bool profile)
memcpy(emu->mMemory + mLinker->mProgramStart, mLinker->mMemory + mLinker->mProgramStart, mLinker->mProgramEnd - mLinker->mProgramStart);
emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff;
emu->mMemory[0x2e] = mLinker->mProgramEnd >> 8;
ecode = emu->Emulate(2061);
ecode = emu->Emulate(2061, trace ? 2 : 0);
}
else if (mCompilerOptions & COPT_TARGET_CRT)
{
memcpy(emu->mMemory + 0x8000, mLinker->mMemory + 0x0800, 0x4000);
ecode = emu->Emulate(0x8009);
ecode = emu->Emulate(0x8009, trace ? 2 : 0);
}
printf("Emulation result %d\n", ecode);

View File

@ -44,7 +44,7 @@ public:
bool ParseSource(void);
bool GenerateCode(void);
bool WriteOutputFile(const char* targetPath, DiskImage * d64);
int ExecuteCode(bool profile);
int ExecuteCode(bool profile, bool trace);
void AddDefine(const Ident* ident, const char* value);

View File

@ -75,6 +75,7 @@ static const uint64 DTF_STACKCALL = (1ULL << 21);
static const uint64 DTF_ZEROPAGE = (1ULL << 22);
static const uint64 DTF_PREVENT_INLINE = (1ULL << 23);
static const uint64 DTF_STRIPED = (1ULL << 24);
static const uint64 DTF_DYNSTACK = (1ULL << 25);
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 32);
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33);

View File

@ -321,10 +321,10 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mIP = addr;
break;
case ASMIT_JSR:
mRegS--;
mMemory[0x100 + mRegS] = (mIP - 1) >> 8;
mRegS--;
mMemory[0x100 + mRegS] = (mIP - 1) & 0xff;
mRegS--;
mIP = addr;
cycles += 2;
break;
@ -372,23 +372,23 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
UpdateStatus(mRegA);
break;
case ASMIT_PHA:
mRegS--;
mMemory[0x100 + mRegS] = mRegA;
mRegS--;
cycles ++;
break;
case ASMIT_PHP:
mRegS--;
mMemory[0x100 + mRegS] = mRegP;
mRegS--;
cycles++;
break;
case ASMIT_PLA:
mRegA = mMemory[0x100 + mRegS];
mRegS++;
mRegA = mMemory[0x100 + mRegS];
cycles++;
break;
case ASMIT_PLP:
mRegP = mMemory[0x100 + mRegS];
mRegS++;
mRegP = mMemory[0x100 + mRegS];
cycles++;
break;
case ASMIT_ROL:
@ -426,7 +426,7 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
case ASMIT_RTI:
break;
case ASMIT_RTS:
mIP = (mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1) & 0xffff;
mIP = (mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1) & 0xffff;
mRegS += 2;
cycles += 4;
break;
@ -496,10 +496,8 @@ void Emulator::DumpProfile(void)
DumpCycles();
}
int Emulator::Emulate(int startIP)
int Emulator::Emulate(int startIP, int trace)
{
int trace = 0;
for (int i = 0; i < 0x10000; i++)
mCycles[i] = 0;
@ -508,7 +506,7 @@ int Emulator::Emulate(int startIP)
mRegX = 0;
mRegY = 0;
mRegP = 0;
mRegS = 0xfe;
mRegS = 0xfd;
mMemory[0x1fe] = 0xff;
mMemory[0x1ff] = 0xff;
@ -537,14 +535,14 @@ int Emulator::Emulate(int startIP)
putchar('\n');
else
putchar(mRegA);
mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1;
mIP = mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1;
mRegS += 2;
}
else if (mIP == 0xffcf)
{
int ch = getchar();
mRegA = ch;
mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1;
mIP = mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1;
mRegS += 2;
}
@ -681,7 +679,7 @@ int Emulator::Emulate(int startIP)
return -1;
}
if (mRegS == 0)
if (mRegS == 0xff)
{
#if 0
for (int i = 0; i < 256; i++)

View File

@ -19,7 +19,7 @@ public:
Linker* mLinker;
int Emulate(int startIP);
int Emulate(int startIP, int trace);
void DumpProfile(void);
bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles);
protected:

View File

@ -216,7 +216,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec)
{
if (!(procDec->mBase->mFlags & DTF_FASTCALL) && !(procDec->mBase->mFlags & DTF_STACKCALL) && (procDec->mType == DT_CONST_FUNCTION))
{
if (!(procDec->mBase->mFlags & DTF_VARIADIC) && !(procDec->mFlags & DTF_FUNC_VARIABLE) && !(procDec->mFlags & DTF_FUNC_RECURSIVE))
if (!(procDec->mBase->mFlags & DTF_VARIADIC) && !(procDec->mFlags & DTF_FUNC_VARIABLE) && !(procDec->mFlags & DTF_FUNC_RECURSIVE) && !(procDec->mFlags & DTF_DYNSTACK))
{
int nbase = 0;
for (int i = 0; i < procDec->mCalled.Size(); i++)
@ -451,7 +451,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
}
else if (exp->mDecValue->mType == DT_CONST_POINTER)
{
RegisterProc(Analyze(exp->mDecValue->mValue, procDec, true));
ldec = Analyze(exp->mDecValue->mValue, procDec, true);
if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING;
RegisterProc(ldec);
}
else if (exp->mDecValue->mType == DT_CONST_ADDRESS)
{
@ -703,6 +706,9 @@ void GlobalAnalyzer::RegisterCall(Declaration* from, Declaration* to)
{
if (to->mType == DT_CONST_FUNCTION)
{
if (to->mFlags & DTF_DYNSTACK)
from->mFlags |= DTF_DYNSTACK;
if (!(to->mFlags & DTF_FUNC_CONSTEXPR))
from->mFlags &= ~DTF_FUNC_CONSTEXPR;

View File

@ -619,6 +619,95 @@ static bool SameInstruction(const InterInstruction* ins1, const InterInstruction
return false;
}
bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const
{
// Cannot swap branches
if (ins1->mCode == IC_JUMP || ins1->mCode == IC_BRANCH)
return false;
// Check function call
if (ins1->mCode == IC_CALL || ins1->mCode == IC_CALL_NATIVE || ins1->mCode == IC_ASSEMBLER)
{
if (ins0->mCode == IC_CALL || ins0->mCode == IC_CALL_NATIVE || ins0->mCode == IC_ASSEMBLER ||
ins0->mCode == IC_RETURN || ins0->mCode == IC_RETURN_STRUCT || ins0->mCode == IC_RETURN_VALUE ||
ins0->mCode == IC_PUSH_FRAME || ins0->mCode == IC_POP_FRAME)
return false;
if (ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY)
return false;
}
if (ins0->mCode == IC_CALL || ins0->mCode == IC_CALL_NATIVE || ins0->mCode == IC_ASSEMBLER)
{
if (ins1->mCode == IC_RETURN || ins1->mCode == IC_RETURN_STRUCT || ins1->mCode == IC_RETURN_VALUE ||
ins1->mCode == IC_PUSH_FRAME || ins1->mCode == IC_POP_FRAME)
return false;
if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)
return false;
}
// Check frame pointer
if (ins0->mCode == IC_PUSH_FRAME || ins0->mCode == IC_POP_FRAME)
{
if (ins1->mCode == IC_PUSH_FRAME || ins1->mCode == IC_POP_FRAME)
return false;
if (ins1->mCode == IC_CONSTANT && ins1->mDst.mType == IT_POINTER && ins1->mConst.mMemory == IM_FRAME)
return false;
if (ins1->mCode == IC_STORE && ins1->mSrc[1].mMemory == IM_FRAME)
return false;
}
if (ins1->mCode == IC_PUSH_FRAME || ins1->mCode == IC_POP_FRAME)
{
if (ins0->mCode == IC_CONSTANT && ins0->mDst.mType == IT_POINTER && ins0->mConst.mMemory == IM_FRAME)
return false;
if (ins0->mCode == IC_STORE && ins0->mSrc[1].mMemory == IM_FRAME)
return false;
}
// False data dependency
if (ins1->mDst.mTemp >= 0)
{
if (ins1->mDst.mTemp == ins0->mDst.mTemp)
return false;
for (int i = 0; i < ins0->mNumOperands; i++)
if (ins1->mDst.mTemp == ins0->mSrc[i].mTemp)
return false;
}
// True data dependency
if (ins0->mDst.mTemp >= 0)
{
for (int i = 0; i < ins1->mNumOperands; i++)
if (ins0->mDst.mTemp == ins1->mSrc[i].mTemp)
return false;
}
if ((ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) &&
(ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY))
{
if (ins0->mVolatile || ins1->mVolatile)
return false;
if (ins0->mCode == IC_LOAD)
{
if (DestroyingMem(ins0, ins1, mProc->mModule->mGlobalVars))
return false;
}
else if (ins1->mCode == IC_LOAD)
{
if (DestroyingMem(ins1, ins0, mProc->mModule->mGlobalVars))
return false;
}
else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY)
{
if (CollidingMem(ins0, ins1, mProc->mModule->mGlobalVars))
return false;
}
}
return true;
}
static int64 ConstantFolding(InterOperator oper, InterType type, int64 val1, int64 val2 = 0)
{
@ -1271,6 +1360,12 @@ static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bi
if (bins->mDst.mTemp == lins->mSrc[i].mTemp)
return false;
}
if (lins->mCode == IC_STORE || lins->mCode == IC_COPY)
{
if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD || bins->mCode == IC_COPY || bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE)
return false;
}
if (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME)
{
if (lins->mCode == IC_CONSTANT && lins->mDst.mType == IT_POINTER && lins->mConst.mMemory == IM_FRAME)
@ -4138,8 +4233,9 @@ void InterInstruction::Disassemble(FILE* file)
}
}
InterCodeBasicBlock::InterCodeBasicBlock(void)
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mMergeAValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr),
InterCodeBasicBlock::InterCodeBasicBlock(InterCodeProcedure * proc)
: mProc(proc),
mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mMergeAValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr),
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()),
mEntryParamValueRange(IntegerValueRange()), mTrueParamValueRange(IntegerValueRange()), mFalseParamValueRange(IntegerValueRange()), mLocalParamValueRange(IntegerValueRange()),
mReverseValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr), mLoopPathBlocks(nullptr), mMemoryValueSize(0), mEntryMemoryValueSize(0)
@ -4150,6 +4246,9 @@ InterCodeBasicBlock::InterCodeBasicBlock(void)
mChecked = false;
mTraceIndex = -1;
mUnreachable = false;
mIndex = proc->mBlocks.Size();
proc->mBlocks.Push(this);
}
InterCodeBasicBlock::~InterCodeBasicBlock(void)
@ -5554,7 +5653,7 @@ bool InterCodeBasicBlock::CombineIndirectAddressing(void)
if (j < tvalue.Size())
{
int offset = lins->mSrc[1].mIntConst - tvalue[j]->mSrc[1].mIntConst;
int64 offset = lins->mSrc[1].mIntConst - tvalue[j]->mSrc[1].mIntConst;
lins->mSrc[1] = tvalue[j]->mDst;
lins->mSrc[0].mTemp = -1;
lins->mSrc[0].mIntConst = offset;
@ -7206,7 +7305,7 @@ bool InterCodeBasicBlock::PropagateConstOperationsUp(void)
int di = eb->mInstructions.Size() - 1;
if (eb->mInstructions[di]->mCode == IC_BRANCH && di > 0 && eb->mInstructions[di - 1]->mDst.mTemp == eb->mInstructions[di]->mSrc[0].mTemp &&
CanBypassUp(ins, eb->mInstructions[di - 1]))
CanSwapInstructions(eb->mInstructions[di - 1], ins))
{
di--;
}
@ -8033,7 +8132,7 @@ bool InterCodeBasicBlock::MergeIndexedLoadStore(const GrowingInstructionPtrArra
if (ins->mCode == IC_LEA)
{
int j = i;
while (j > 0 && CanBypassUp(ins, mInstructions[j - 1]))
while (j > 0 && CanSwapInstructions(mInstructions[j - 1], ins))
{
mInstructions[j] = mInstructions[j - 1];
j--;
@ -9679,6 +9778,18 @@ bool InterCodeBasicBlock::CanMoveInstructionDown(int si, int ti) const
{
InterInstruction* ins = mInstructions[si];
#if 1
if (ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME ||
ins->mCode == IC_RETURN || ins->mCode == IC_RETURN_STRUCT || ins->mCode == IC_RETURN_VALUE)
return false;
for (int i = si + 1; i < ti; i++)
if (!CanSwapInstructions(ins, mInstructions[i]))
return false;
return true;
#else
if (ins->mCode == IC_LOAD)
{
for (int i = si + 1; i < ti; i++)
@ -9702,6 +9813,7 @@ bool InterCodeBasicBlock::CanMoveInstructionDown(int si, int ti) const
}
return true;
#endif
}
int InterCodeBasicBlock::FindSameInstruction(const InterInstruction* ins) const
@ -9719,6 +9831,17 @@ bool InterCodeBasicBlock::CanMoveInstructionBehindBlock(int ii) const
bool InterCodeBasicBlock::CanMoveInstructionBeforeBlock(int ii, const InterInstruction* ins) const
{
#if 1
if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE || ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME ||
ins->mCode == IC_RETURN || ins->mCode == IC_RETURN_STRUCT || ins->mCode == IC_RETURN_VALUE)
return false;
for (int i = 0; i < ii; i++)
if (!CanSwapInstructions(mInstructions[i], ins))
return false;
return true;
#else
if (ins->mCode == IC_LOAD)
{
for (int i = 0; i < ii; i++)
@ -9740,7 +9863,7 @@ bool InterCodeBasicBlock::CanMoveInstructionBeforeBlock(int ii, const InterInstr
if (!CanBypassUp(ins, mInstructions[i]))
return false;
}
#endif
return true;
}
@ -9781,7 +9904,9 @@ bool InterCodeBasicBlock::MergeCommonPathInstructions(void)
if (mTrueJump->CanMoveInstructionBeforeBlock(ti) && mFalseJump->CanMoveInstructionBeforeBlock(fi))
{
int tindex = mInstructions.Size() - 1;
if (mInstructions.Size() >= 2 && mInstructions[tindex - 1]->mDst.mTemp == mInstructions[tindex]->mSrc[0].mTemp && CanBypassUp(tins, mInstructions[tindex - 1]))
if (mInstructions.Size() >= 2 && mInstructions[tindex - 1]->mDst.mTemp == mInstructions[tindex]->mSrc[0].mTemp &&
CanSwapInstructions(mInstructions[tindex - 1], tins))
// CanBypassUp(tins, mInstructions[tindex - 1]))
tindex--;
mInstructions.Insert(tindex, tins);
@ -10334,7 +10459,7 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
if (ins->mCode == IC_LOAD)
{
j = 0;
while (j < mTrueJump->mInstructions.Size() && CanBypassLoad(ins, mTrueJump->mInstructions[j]))
while (j < mTrueJump->mInstructions.Size() && CanSwapInstructions(ins, mTrueJump->mInstructions[j]))
j++;
}
if (ins->mCode != IC_LOAD || j == mTrueJump->mInstructions.Size())
@ -10342,7 +10467,7 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
if (ins->mCode == IC_LOAD)
{
j = 0;
while (j < mFalseJump->mInstructions.Size() && CanBypassLoad(ins, mFalseJump->mInstructions[j]))
while (j < mFalseJump->mInstructions.Size() && CanSwapInstructions(ins, mFalseJump->mInstructions[j]))
j++;
}
@ -10488,7 +10613,7 @@ bool InterCodeBasicBlock::IsLeafProcedure(void)
}
void InterCodeBasicBlock::ExpandSelect(InterCodeProcedure* proc)
void InterCodeBasicBlock::ExpandSelect(void)
{
if (!mVisited)
{
@ -10502,12 +10627,9 @@ void InterCodeBasicBlock::ExpandSelect(InterCodeProcedure* proc)
{
InterInstruction* sins = mInstructions[i];
InterCodeBasicBlock* tblock = new InterCodeBasicBlock();
proc->Append(tblock);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock();
proc->Append(fblock);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
proc->Append(eblock);
InterCodeBasicBlock* tblock = new InterCodeBasicBlock(mProc);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock(mProc);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock(mProc);
for (int j = i + 1; j < mInstructions.Size(); j++)
eblock->mInstructions.Push(mInstructions[j]);
@ -10564,13 +10686,13 @@ void InterCodeBasicBlock::ExpandSelect(InterCodeProcedure* proc)
}
if (mTrueJump)
mTrueJump->ExpandSelect(proc);
mTrueJump->ExpandSelect();
if (mFalseJump)
mFalseJump->ExpandSelect(proc);
mFalseJump->ExpandSelect();
}
}
void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc)
void InterCodeBasicBlock::SplitBranches(void)
{
if (!mVisited)
{
@ -10578,10 +10700,9 @@ void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc)
if (mTrueJump && mFalseJump && (mInstructions.Size() > 2 || mInstructions.Size() == 2 && mInstructions[0]->mCode != IC_RELATIONAL_OPERATOR))
{
InterCodeBasicBlock* block = new InterCodeBasicBlock();
InterCodeBasicBlock* block = new InterCodeBasicBlock(mProc);
InterInstruction* ins = mInstructions.Last();
proc->Append(block);
if (mInstructions[mInstructions.Size() - 2]->mCode == IC_RELATIONAL_OPERATOR)
{
block->mInstructions.Push(mInstructions[mInstructions.Size() - 2]);
@ -10600,14 +10721,14 @@ void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc)
mFalseJump = nullptr;
block->mNumEntries = 1;
block->SplitBranches(proc);
block->SplitBranches();
}
else
{
if (mTrueJump)
mTrueJump->SplitBranches(proc);
mTrueJump->SplitBranches();
if (mFalseJump)
mFalseJump->SplitBranches(proc);
mFalseJump->SplitBranches();
}
}
}
@ -10948,7 +11069,7 @@ void InterCodeBasicBlock::FollowJumps(void)
}
}
void InterCodeBasicBlock::BuildLoopSuffix(InterCodeProcedure* proc)
void InterCodeBasicBlock::BuildLoopSuffix(void)
{
if (!mVisited)
{
@ -10960,8 +11081,7 @@ void InterCodeBasicBlock::BuildLoopSuffix(InterCodeProcedure* proc)
{
if (mFalseJump->mNumEntries > 1)
{
InterCodeBasicBlock* suffix = new InterCodeBasicBlock();
proc->Append(suffix);
InterCodeBasicBlock* suffix = new InterCodeBasicBlock(mProc);
InterInstruction* jins = new InterInstruction(mInstructions[0]->mLocation, IC_JUMP);
suffix->Append(jins);
suffix->Close(mFalseJump, nullptr);
@ -10973,8 +11093,7 @@ void InterCodeBasicBlock::BuildLoopSuffix(InterCodeProcedure* proc)
{
if (mTrueJump->mNumEntries > 1)
{
InterCodeBasicBlock* suffix = new InterCodeBasicBlock();
proc->Append(suffix);
InterCodeBasicBlock* suffix = new InterCodeBasicBlock(mProc);
InterInstruction* jins = new InterInstruction(mInstructions[0]->mLocation, IC_JUMP);
suffix->Append(jins);
suffix->Close(mTrueJump, nullptr);
@ -10985,27 +11104,26 @@ void InterCodeBasicBlock::BuildLoopSuffix(InterCodeProcedure* proc)
}
if (mTrueJump)
mTrueJump->BuildLoopSuffix(proc);
mTrueJump->BuildLoopSuffix();
if (mFalseJump)
mFalseJump->BuildLoopSuffix(proc);
mFalseJump->BuildLoopSuffix();
}
}
InterCodeBasicBlock* InterCodeBasicBlock::BuildLoopPrefix(InterCodeProcedure* proc)
InterCodeBasicBlock* InterCodeBasicBlock::BuildLoopPrefix(void)
{
if (!mVisited)
{
mVisited = true;
if (mTrueJump)
mTrueJump = mTrueJump->BuildLoopPrefix(proc);
mTrueJump = mTrueJump->BuildLoopPrefix();
if (mFalseJump)
mFalseJump = mFalseJump->BuildLoopPrefix(proc);
mFalseJump = mFalseJump->BuildLoopPrefix();
if (mLoopHead)
{
mLoopPrefix = new InterCodeBasicBlock();
proc->Append(mLoopPrefix);
mLoopPrefix = new InterCodeBasicBlock(mProc);
InterInstruction* jins = new InterInstruction(mInstructions[0]->mLocation, IC_JUMP);
mLoopPrefix->Append(jins);
mLoopPrefix->Close(this, nullptr);
@ -13658,6 +13776,15 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
mInstructions[i + 0]->mSrc[1].mFinal = false;
changed = true;
}
else if (
mInstructions[i + 0]->mCode == IC_STORE && mInstructions[i + 1]->mCode == IC_STORE &&
SameMemSegment(mInstructions[i + 1]->mSrc[1], mInstructions[i + 0]->mSrc[1]) &&
!mInstructions[i + 0]->mVolatile && !mInstructions[i + 1]->mVolatile)
{
mInstructions[i + 0]->mCode = IC_NONE;
mInstructions[i + 0]->mNumOperands = 0;
changed = true;
}
#if 1
if (i + 2 < mInstructions.Size() &&
@ -13878,7 +14005,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
if (ins->mSrc[0].mTemp < 0)
{
int k = i;
while (k < limit && CanBypass(ins, mInstructions[k + 1]))
while (k < limit && CanSwapInstructions(ins, mInstructions[k + 1]))
k++;
if (k == limit)
@ -13914,7 +14041,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
{
InterInstruction* ins(mInstructions[i]);
int j = i;
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1]))
{
SwapInstructions(ins, mInstructions[j + 1]);
mInstructions[j] = mInstructions[j + 1];
@ -13945,7 +14072,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
{
InterInstruction * ins(mInstructions[i]);
int j = i;
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1]))
{
SwapInstructions(ins, mInstructions[j + 1]);
mInstructions[j] = mInstructions[j + 1];
@ -13959,7 +14086,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
InterInstruction* ins(mInstructions[i]);
int k = i;
while (k < limit && CanBypass(ins, mInstructions[k + 1]))
while (k < limit && CanSwapInstructions(ins, mInstructions[k + 1]))
k++;
if (k < limit)
{
@ -13982,7 +14109,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
{
InterInstruction* ins(mInstructions[i]);
int j = i;
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1]))
{
SwapInstructions(ins, mInstructions[j + 1]);
mInstructions[j] = mInstructions[j + 1];
@ -13997,6 +14124,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
CheckFinalLocal();
#endif
#if 1
// move indirect load/store pairs up
i = 0;
@ -14011,8 +14139,8 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
int j = i;
while (j > 0 &&
CanBypassLoadUp(lins, mInstructions[j - 1]) &&
CanBypassStore(sins, mInstructions[j - 1]))
CanSwapInstructions(mInstructions[j - 1], lins) &&
CanSwapInstructions(mInstructions[j - 1], sins))
{
SwapInstructions(mInstructions[j - 1], lins);
SwapInstructions(mInstructions[j - 1], sins);
@ -14034,6 +14162,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
CheckFinalLocal();
#endif
#if 1
i = 0;
while (i < mInstructions.Size())
@ -14043,8 +14172,12 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
{
InterInstruction * ins(mInstructions[i]);
int j = i;
while (j > 0 && CanBypassStore(ins, mInstructions[j - 1]))
while (j > 0 && CanSwapInstructions(mInstructions[j - 1], ins))
{
if (mInstructions[j - 1]->mCode == IC_STORE && mInstructions[j - 1]->mSrc[1].mMemory == IM_INDIRECT)
{
CanSwapInstructions(mInstructions[j - 1], ins);
}
SwapInstructions(mInstructions[j - 1], ins);
mInstructions[j] = mInstructions[j - 1];
j--;
@ -14056,7 +14189,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
{
InterInstruction* ins(mInstructions[i]);
int j = i;
while (j > 0 && CanBypassUp(ins, mInstructions[j - 1]))
while (j > 0 && CanSwapInstructions(mInstructions[j - 1], ins))
{
SwapInstructions(mInstructions[j - 1], ins);
mInstructions[j] = mInstructions[j - 1];
@ -14069,7 +14202,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
{
InterInstruction* ins(mInstructions[i]);
int j = i;
while (j > 0 && CanBypassLoadUp(ins, mInstructions[j - 1]))
while (j > 0 && CanSwapInstructions(mInstructions[j - 1], ins))
{
SwapInstructions(mInstructions[j - 1], ins);
mInstructions[j] = mInstructions[j - 1];
@ -14094,7 +14227,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
{
InterInstruction* ins(mInstructions[i]);
int j = i;
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1]))
{
SwapInstructions(ins, mInstructions[j + 1]);
mInstructions[j] = mInstructions[j + 1];
@ -14107,7 +14240,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
{
InterInstruction* ins(mInstructions[i]);
int j = i;
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
while (j < limit && CanSwapInstructions(ins, mInstructions[j + 1]))
{
SwapInstructions(ins, mInstructions[j + 1]);
mInstructions[j] = mInstructions[j + 1];
@ -14254,7 +14387,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
}
}
void InterCodeBasicBlock::CheckValueReturn(InterCodeProcedure* proc)
void InterCodeBasicBlock::CheckValueReturn(void)
{
if (!mVisited)
{
@ -14266,16 +14399,16 @@ void InterCodeBasicBlock::CheckValueReturn(InterCodeProcedure* proc)
if (ins->mCode == IC_ASSEMBLER)
return;
else if (ins->mCode == IC_RETURN)
proc->mModule->mErrors->Error(ins->mLocation, EWARN_MISSING_RETURN_STATEMENT, "Missing return statement");
mProc->mModule->mErrors->Error(ins->mLocation, EWARN_MISSING_RETURN_STATEMENT, "Missing return statement");
}
if (mTrueJump) mTrueJump->CheckValueReturn(proc);
if (mFalseJump) mFalseJump->CheckValueReturn(proc);
if (mTrueJump) mTrueJump->CheckValueReturn();
if (mFalseJump) mFalseJump->CheckValueReturn();
}
}
void InterCodeBasicBlock::WarnUsedUndefinedVariables(InterCodeProcedure* proc)
void InterCodeBasicBlock::WarnUsedUndefinedVariables(void)
{
if (!mVisited)
{
@ -14294,22 +14427,22 @@ void InterCodeBasicBlock::WarnUsedUndefinedVariables(InterCodeProcedure* proc)
int t = ins->mSrc[j].mTemp;
int k = 0;
while (k < proc->mLocalVars.Size() && !(proc->mLocalVars[k] && proc->mLocalVars[k]->mTempIndex == t))
while (k < mProc->mLocalVars.Size() && !(mProc->mLocalVars[k] && mProc->mLocalVars[k]->mTempIndex == t))
k++;
if (potentialTemps[t])
{
if (k < proc->mLocalVars.Size() && proc->mLocalVars[k]->mIdent)
proc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of potentially uninitialized variable", proc->mLocalVars[k]->mIdent);
if (k < mProc->mLocalVars.Size() && mProc->mLocalVars[k]->mIdent)
mProc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of potentially uninitialized variable", mProc->mLocalVars[k]->mIdent);
else
proc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of potentially uninitialized expression");
mProc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of potentially uninitialized expression");
}
else
{
if (k < proc->mLocalVars.Size() && proc->mLocalVars[k]->mIdent)
proc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of uninitialized variable", proc->mLocalVars[k]->mIdent);
if (k < mProc->mLocalVars.Size() && mProc->mLocalVars[k]->mIdent)
mProc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of uninitialized variable", mProc->mLocalVars[k]->mIdent);
else
proc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of uninitialized expression");
mProc->mModule->mErrors->Error(ins->mLocation, EWARN_USE_OF_UNINITIALIZED_VARIABLE, "Use of uninitialized expression");
if (ins->mCode == IC_LOAD_TEMPORARY)
{
@ -14335,8 +14468,8 @@ void InterCodeBasicBlock::WarnUsedUndefinedVariables(InterCodeProcedure* proc)
providedTemps += ins->mDst.mTemp;
}
if (mTrueJump) mTrueJump->WarnUsedUndefinedVariables(proc);
if (mFalseJump) mFalseJump->WarnUsedUndefinedVariables(proc);
if (mTrueJump) mTrueJump->WarnUsedUndefinedVariables();
if (mFalseJump) mFalseJump->WarnUsedUndefinedVariables();
}
}
@ -14609,7 +14742,7 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod),
mIdent(ident), mLinkerObject(linkerObject),
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false),
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false),
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), mDynamicStack(false),
mSaveTempsLinkerObject(nullptr), mValueReturn(false), mFramePointer(false),
mDeclaration(nullptr)
{
@ -14667,12 +14800,6 @@ void InterCodeProcedure::ResetVisited(void)
}
}
void InterCodeProcedure::Append(InterCodeBasicBlock* block)
{
block->mIndex = mBlocks.Size();
mBlocks.Push(block);
}
int InterCodeProcedure::AddTemporary(InterType type)
{
int temp = mTemporaries.Size();
@ -14925,7 +15052,7 @@ void InterCodeProcedure::WarnUsedUndefinedVariables(void)
mEntryBlock->CollectEntryBlocks(nullptr);
ResetVisited();
mEntryBlock->WarnUsedUndefinedVariables(this);
mEntryBlock->WarnUsedUndefinedVariables();
}
@ -15327,7 +15454,7 @@ void InterCodeProcedure::ExpandSelect(void)
{
#if 1
ResetVisited();
mEntryBlock->ExpandSelect(this);
mEntryBlock->ExpandSelect();
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
@ -15428,7 +15555,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
// CheckFunc = !strcmp(mIdent->mString, "joy_poll");
CheckFunc = !strcmp(mIdent->mString, "main");
mEntryBlock = mBlocks[0];
@ -15705,6 +15832,16 @@ void InterCodeProcedure::Close(void)
ResetVisited();
mEntryBlock->CollectEntryBlocks(nullptr);
#if 1
BuildDataFlowSets();
do {
Disassemble("gcp+");
TempForwarding();
} while (GlobalConstantPropagation());
Disassemble("gcp-");
#endif
BuildDataFlowSets();
#if 1
@ -15865,8 +16002,10 @@ void InterCodeProcedure::Close(void)
BuildDataFlowSets();
do {
Disassemble("gcp+");
TempForwarding();
} while (GlobalConstantPropagation());
Disassemble("gcp-");
#endif
#if 1
@ -16050,7 +16189,7 @@ void InterCodeProcedure::Close(void)
#if 1
ResetVisited();
if (!mInterruptCalled && mNativeProcedure && mEntryBlock->CheckStaticStack())
if (!mInterruptCalled && !mDynamicStack && mNativeProcedure && mEntryBlock->CheckStaticStack())
{
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
mLinkerObject->mStackSection = mModule->mLinker->AddSection(mIdent->Mangle("@stack"), LST_STATIC_STACK);
@ -16209,7 +16348,7 @@ void InterCodeProcedure::Close(void)
if (mValueReturn)
{
ResetVisited();
mEntryBlock->CheckValueReturn(this);
mEntryBlock->CheckValueReturn();
}
if (mSaveTempsLinkerObject && mTempSize > BC_REG_TMP_SAVED - BC_REG_TMP)
@ -16381,7 +16520,7 @@ void InterCodeProcedure::MergeBasicBlocks(void)
mEntryBlock->FollowJumps();
ResetVisited();
mEntryBlock->SplitBranches(this);
mEntryBlock->SplitBranches();
DisassembleDebug("PostSplit");
@ -16483,8 +16622,7 @@ void InterCodeProcedure::MergeBasicBlocks(void)
if (!allBlocks || eblocks.Size() || mblocks.IndexOf(block) != -1)
{
nblock = new InterCodeBasicBlock();
this->Append(nblock);
nblock = new InterCodeBasicBlock(this);
for (int i = 0; i < mblocks.Size(); i++)
mblocks[i]->mTrueJump = nblock;
@ -16532,7 +16670,7 @@ void InterCodeProcedure::BuildLoopPrefix(void)
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mLoopPrefix = nullptr;
mEntryBlock = mEntryBlock->BuildLoopPrefix(this);
mEntryBlock = mEntryBlock->BuildLoopPrefix();
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
@ -16540,7 +16678,7 @@ void InterCodeProcedure::BuildLoopPrefix(void)
mEntryBlock->CollectEntries();
ResetVisited();
mEntryBlock->BuildLoopSuffix(this);
mEntryBlock->BuildLoopSuffix();
}
bool InterCodeProcedure::PropagateNonLocalUsedTemps(void)
@ -16646,7 +16784,7 @@ void InterCodeProcedure::MapCallerSavedTemps(void)
int callerSavedTemps = 0, calleeSavedTemps = BC_REG_TMP_SAVED - BC_REG_TMP, freeCallerSavedTemps = 0, freeTemps = 0;
if (mCallsFunctionPointer)
if (mCallsFunctionPointer || mDynamicStack)
freeCallerSavedTemps = BC_REG_TMP_SAVED - BC_REG_TMP;
else
{

View File

@ -117,6 +117,7 @@ class InterInstruction;
class InterCodeBasicBlock;
class InterCodeProcedure;
class InterVariable;
class InterCodeModule;
typedef InterInstruction* InterInstructionPtr;
typedef InterCodeBasicBlock* InterCodeBasicBlockPtr;
@ -343,6 +344,7 @@ public:
class InterCodeBasicBlock
{
public:
InterCodeProcedure * mProc;
int mIndex, mNumEntries, mNumEntered, mTraceIndex;
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
GrowingInstructionArray mInstructions;
@ -380,7 +382,7 @@ public:
ValueSet mMergeValues;
TempForwardingTable mMergeForwardingTable;
InterCodeBasicBlock(void);
InterCodeBasicBlock(InterCodeProcedure * proc);
~InterCodeBasicBlock(void);
void Append(InterInstruction * code);
@ -492,6 +494,8 @@ public:
bool IsTempReferencedOnPath(int temp, int at) const;
bool PushSinglePathResultInstructions(void);
bool CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const;
bool CanMoveInstructionBeforeBlock(int ii) const;
bool CanMoveInstructionBeforeBlock(int ii, const InterInstruction * ins) const;
bool CanMoveInstructionBehindBlock(int ii) const;
@ -525,12 +529,12 @@ public:
bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
InterCodeBasicBlock* BuildLoopPrefix(InterCodeProcedure * proc);
void BuildLoopSuffix(InterCodeProcedure* proc);
InterCodeBasicBlock* BuildLoopPrefix(void);
void BuildLoopSuffix(void);
void ExpandSelect(InterCodeProcedure* proc);
void ExpandSelect(void);
void SplitBranches(InterCodeProcedure* proc);
void SplitBranches(void);
void FollowJumps(void);
bool IsEqual(const InterCodeBasicBlock* block) const;
@ -546,13 +550,11 @@ public:
bool SameExitCode(const InterCodeBasicBlock* block) const;
void WarnUsedUndefinedVariables(InterCodeProcedure* proc);
void CheckValueReturn(InterCodeProcedure* proc);
void WarnUsedUndefinedVariables(void);
void CheckValueReturn(void);
};
class InterCodeModule;
class InterCodeProcedure
{
protected:
@ -570,7 +572,7 @@ public:
GrowingIntArray mTempOffset, mTempSizes;
int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps, mFastCallBase;
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure;
bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn, mFramePointer;
bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn, mFramePointer, mDynamicStack;
GrowingInterCodeProcedurePtrArray mCalledFunctions;
InterCodeModule * mModule;
@ -592,7 +594,6 @@ public:
int AddTemporary(InterType type);
void Append(InterCodeBasicBlock * block);
void Close(void);
// void Set(InterCodeIDMapper* mapper, BitVector localStructure, Scanner scanner, bool debug);

View File

@ -398,6 +398,9 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
var->mDeclaration = dec;
mod->mGlobalVars.Push(var);
if (dec->mFlags & DTF_VAR_ALIASING)
var->mAliased = true;
dec->mVarIndex = var->mIndex;
dec->mLinkerObject = var->mLinkerObject;
@ -745,8 +748,7 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e
{
for (int i = left; i < right; i++)
{
InterCodeBasicBlock* cblock = new InterCodeBasicBlock();
proc->Append(cblock);
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT);
vins->mConst.mType = IT_INT16;
@ -785,14 +787,9 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e
{
int center = (left + right + 1) >> 1;
InterCodeBasicBlock* cblock = new InterCodeBasicBlock();
proc->Append(cblock);
InterCodeBasicBlock* rblock = new InterCodeBasicBlock();
proc->Append(rblock);
InterCodeBasicBlock* lblock = new InterCodeBasicBlock();
proc->Append(lblock);
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* rblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* lblock = new InterCodeBasicBlock(proc);
InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT);
vins->mConst.mType = IT_INT16;
@ -851,13 +848,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
Declaration* ftype = fdec->mBase;
InlineMapper nmapper;
nmapper.mReturn = new InterCodeBasicBlock();
nmapper.mReturn = new InterCodeBasicBlock(proc);
nmapper.mVarIndex = proc->mNumLocals;
nmapper.mConstExpr = inlineConstexpr;
proc->mNumLocals += fdec->mNumVars;
if (inlineMapper)
nmapper.mDepth = inlineMapper->mDepth + 1;
proc->Append(nmapper.mReturn);
Declaration* pdec = ftype->mParams;
Expression* pex = exp->mRight;
@ -1205,6 +1201,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterVariable * var = new InterVariable();
var->mOffset = 0;
var->mSize = dec->mSize;
if (dec->mFlags & DTF_VAR_ALIASING)
var->mAliased = true;
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment);
dec->mLinkerObject = var->mLinkerObject;
var->mIdent = dec->mIdent;
@ -2932,8 +2930,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
}
else
block->Close(nullptr, nullptr);
block = new InterCodeBasicBlock();
proc->Append(block);
block = new InterCodeBasicBlock(proc);
return ExValue(TheVoidTypeDeclaration);
}
@ -2946,8 +2943,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block->Append(jins);
block->Close(breakBlock, nullptr);
block = new InterCodeBasicBlock();
proc->Append(block);
block = new InterCodeBasicBlock(proc);
}
else
mErrors->Error(exp->mLocation, EERR_INVALID_BREAK, "No break target");
@ -2963,8 +2959,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block->Append(jins);
block->Close(continueBlock, nullptr);
block = new InterCodeBasicBlock();
proc->Append(block);
block = new InterCodeBasicBlock(proc);
}
else
mErrors->Error(exp->mLocation, EERR_INVALID_CONTINUE, "No continue target");
@ -2975,10 +2970,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_ASSUME:
{
#if 1
InterCodeBasicBlock* tblock = new InterCodeBasicBlock();
proc->Append(tblock);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock();
proc->Append(fblock);
InterCodeBasicBlock* tblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc);
TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper);
@ -3110,12 +3103,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction* jins0 = new InterInstruction(exp->mLocation, IC_JUMP);
InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP);
InterCodeBasicBlock* tblock = new InterCodeBasicBlock();
proc->Append(tblock);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock();
proc->Append(fblock);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
proc->Append(eblock);
InterCodeBasicBlock* tblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc);
TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper);
@ -3320,13 +3310,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction* jins0 = new InterInstruction(exp->mLocation, IC_JUMP);
InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP);
InterCodeBasicBlock* tblock = new InterCodeBasicBlock();
proc->Append(tblock);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock();
proc->Append(fblock);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
proc->Append(eblock);
InterCodeBasicBlock* tblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc);
TranslateLogic(procType, proc, block, tblock, fblock, exp, inlineMapper);
int ttemp = proc->AddTemporary(IT_BOOL);
@ -3360,13 +3347,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction * jins0 = new InterInstruction(exp->mLocation, IC_JUMP);
InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP);
InterCodeBasicBlock* cblock = new InterCodeBasicBlock();
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* lblock = cblock;
proc->Append(cblock);
InterCodeBasicBlock* bblock = new InterCodeBasicBlock();
proc->Append(bblock);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
proc->Append(eblock);
InterCodeBasicBlock* bblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc);
block->Append(jins0);
block->Close(cblock, nullptr);
@ -3387,12 +3371,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction * jins0 = new InterInstruction(exp->mLocation, IC_JUMP);
InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP);
InterCodeBasicBlock* tblock = new InterCodeBasicBlock();
proc->Append(tblock);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock();
proc->Append(fblock);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
proc->Append(eblock);
InterCodeBasicBlock* tblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc);
TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper);
@ -3421,15 +3402,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction* jins2 = new InterInstruction(exp->mLocation, IC_JUMP);
InterInstruction* jins3 = new InterInstruction(exp->mLocation, IC_JUMP);
InterCodeBasicBlock* cblock = new InterCodeBasicBlock();
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* lblock = cblock;
proc->Append(cblock);
InterCodeBasicBlock* bblock = new InterCodeBasicBlock();
proc->Append(bblock);
InterCodeBasicBlock* iblock = new InterCodeBasicBlock();
proc->Append(iblock);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
proc->Append(eblock);
InterCodeBasicBlock* bblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* iblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc);
block->Append(jins0);
block->Close(cblock, nullptr);
@ -3464,11 +3441,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
InterCodeBasicBlock* cblock = new InterCodeBasicBlock();
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* lblock = cblock;
proc->Append(cblock);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
proc->Append(eblock);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc);
block->Append(jins);
block->Close(cblock, nullptr);
@ -3493,8 +3468,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block = nullptr;
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
proc->Append(eblock);
InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc);
SwitchNodeArray switchNodes({ 0 });
@ -3504,8 +3478,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
Expression* cexp = sexp->mLeft;
if (cexp->mType == EX_CASE)
{
InterCodeBasicBlock* nblock = new InterCodeBasicBlock();
proc->Append(nblock);
InterCodeBasicBlock* nblock = new InterCodeBasicBlock(proc);
SwitchNode snode;
snode.mBlock = nblock;
@ -3538,8 +3511,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{
if (!dblock)
{
dblock = new InterCodeBasicBlock();
proc->Append(dblock);
dblock = new InterCodeBasicBlock(proc);
if (block)
{
@ -3661,6 +3633,8 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
var->mIndex = dec->mVarIndex;
var->mOffset = 0;
var->mSize = dec->mSize;
if (dec->mFlags & DTF_VAR_ALIASING)
var->mAliased = true;
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment);
dec->mLinkerObject = var->mLinkerObject;
var->mLinkerObject->AddData(dec->mData, dec->mSize);
@ -3727,16 +3701,14 @@ void InterCodeGenerator::TranslateLogic(Declaration* procType, InterCodeProcedur
break;
case EX_LOGICAL_AND:
{
InterCodeBasicBlock* ablock = new InterCodeBasicBlock();
proc->Append(ablock);
InterCodeBasicBlock* ablock = new InterCodeBasicBlock(proc);
TranslateLogic(procType, proc, block, ablock, fblock, exp->mLeft, inlineMapper);
TranslateLogic(procType, proc, ablock, tblock, fblock, exp->mRight, inlineMapper);
break;
}
case EX_LOGICAL_OR:
{
InterCodeBasicBlock* oblock = new InterCodeBasicBlock();
proc->Append(oblock);
InterCodeBasicBlock* oblock = new InterCodeBasicBlock(proc);
TranslateLogic(procType, proc, block, tblock, oblock, exp->mLeft, inlineMapper);
TranslateLogic(procType, proc, oblock, tblock, fblock, exp->mRight, inlineMapper);
break;
@ -3782,6 +3754,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
if (dec->mFlags & DTF_FUNC_INTRCALLED)
proc->mInterruptCalled = true;
if (dec->mFlags & DTF_DYNSTACK)
proc->mDynamicStack = true;
if (dec->mBase->mFlags & DTF_FASTCALL)
{
@ -3806,9 +3781,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
proc->mValueReturn = true;
InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock();
proc->Append(entryBlock);
InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock(proc);
InterCodeBasicBlock* exitBlock = entryBlock;

View File

@ -19208,7 +19208,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
changed = true;
}
}
else if (ns >= 3 && mIns[ns - 3].mType == ASMIT_LDA && mIns[ns - 3].mMode == ASMIM_ZERO_PAGE && !(mIns[ns - 2].mLive & LIVE_CPU_REG_X))
else if (ns >= 3 && mIns[ns - 3].mType == ASMIT_LDA && mIns[ns - 3].mMode == ASMIM_ZERO_PAGE && !(mIns[ns - 2].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_A)))
{
if (mTrueJump->mEntryRequiredRegs[ins.mAddress] && !mFalseJump->mEntryRequiredRegs[ins.mAddress] && mTrueJump->mEntryBlocks.Size() == 1)
{
@ -24671,6 +24671,8 @@ bool NativeCodeBasicBlock::EliminateUpper16BitSum(NativeCodeProcedure* nproc)
{
mVisited = true;
CheckLive();
for (int i = 0; i + 2 < mIns.Size(); i++)
{
if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
@ -28346,7 +28348,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
}
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
}
else if (!(mIns[i + 0].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && !mExitRequiredRegs[mIns[i + 1].mAddress])
else if (j > i && !(mIns[i + 0].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && !mExitRequiredRegs[mIns[i + 1].mAddress])
{
int j = mIns.Size() - 1;
@ -39078,7 +39080,7 @@ void NativeCodeProcedure::RebuildEntry(void)
void NativeCodeProcedure::Optimize(void)
{
CheckFunc = !strcmp(mInterProc->mIdent->mString, "main");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "bm_polygon_nc_fill");
#if 1
int step = 0;
@ -39330,7 +39332,10 @@ void NativeCodeProcedure::Optimize(void)
{
ResetVisited();
if (mEntryBlock->JoinTailCodeSequences(this, step > 4))
{
changed = true;
BuildDataFlowSets();
}
ResetVisited();
if (mEntryBlock->PropagateSinglePath())
@ -39339,6 +39344,7 @@ void NativeCodeProcedure::Optimize(void)
#endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks(true);
@ -39390,6 +39396,7 @@ void NativeCodeProcedure::Optimize(void)
#endif
}
#endif
if (step > 4 && !changed)
{
ResetVisited();
@ -39704,6 +39711,7 @@ void NativeCodeProcedure::Optimize(void)
mGenerator->mErrors->Error(mInterProc->mLocation, EWARN_OPTIMIZER_LOCKED, "Optimizer locked in infinite loop", mInterProc->mIdent);
}
#if 1
if (!changed && step < 11)
{
@ -39716,8 +39724,10 @@ void NativeCodeProcedure::Optimize(void)
else
cnt++;
} while (changed);
#if 1
ResetVisited();
mEntryBlock->ReduceLocalYPressure();

View File

@ -1051,6 +1051,11 @@ Declaration* Parser::ParseDeclaration(bool variable, bool expression)
storageFlags |= DTF_EXPORT;
mScanner->NextToken();
}
else if (mScanner->mToken == TK_DYNSTACK)
{
storageFlags |= DTF_DYNSTACK;
mScanner->NextToken();
}
else if (mScanner->mToken == TK_FASTCALL)
{
storageFlags |= DTF_FASTCALL;
@ -1818,7 +1823,7 @@ Expression* Parser::ParsePrefixExpression(void)
}
else if (nexp->mToken == TK_BANKOF)
{
nexp->mDecType == TheUnsignedCharTypeDeclaration;
nexp->mDecType = TheUnsignedCharTypeDeclaration;
}
else
nexp->mDecType = nexp->mLeft->mDecType;

View File

@ -60,6 +60,7 @@ const char* TokenNames[] =
"__zeropage",
"__noinline",
"__striped",
"__dynstack",
"number",
"char",
@ -1375,6 +1376,8 @@ void Scanner::NextRawToken(void)
mToken = TK_NOINLINE;
else if (!strcmp(tkident, "__striped"))
mToken = TK_STRIPED;
else if (!strcmp(tkident, "__dynstack"))
mToken = TK_DYNSTACK;
else
{
mToken = TK_IDENT;

View File

@ -58,6 +58,7 @@ enum Token
TK_ZEROPAGE,
TK_NOINLINE,
TK_STRIPED,
TK_DYNSTACK,
TK_NUMBER,
TK_CHARACTER,

View File

@ -114,7 +114,7 @@ int main2(int argc, const char** argv)
strcpy_s(crtPath, includePath);
strcat_s(crtPath, "crt.c");
bool emulate = false, profile = false;
bool emulate = false, profile = false, trace = false;
targetPath[0] = 0;
diskPath[0] = 0;
@ -203,6 +203,8 @@ int main2(int argc, const char** argv)
emulate = true;
if (arg[2] == 'p')
profile = true;
else if (arg[2] == 't')
trace = true;
}
else if (arg[1] == 'd')
{
@ -457,7 +459,7 @@ int main2(int argc, const char** argv)
}
if (emulate)
compiler->ExecuteCode(profile);
compiler->ExecuteCode(profile, trace);
}
}

View File

@ -70,7 +70,6 @@ int main(void)
}
bm_polygon_nc_fill(&Screen, &cr, rpx, rpy, 10, NineShadesOfGrey[i % 9]);
for(int j=0; j<10; j++)
{
int k = (j + 1) % 10;