Improved value forwarding across conditiona branches

This commit is contained in:
drmortalwombat 2021-09-12 22:32:31 +02:00
parent 3a94be4a35
commit 8de4bef436
7 changed files with 305 additions and 102 deletions

View File

@ -199,6 +199,14 @@ public:
for (i = 0; i < size; i++) array[i] = a.array[i];
}
GrowingArray & operator=(const GrowingArray& a)
{
Grow(a.size, true);
int i;
for (i = 0; i < size; i++) array[i] = a.array[i];
return *this;
}
~GrowingArray(void)
{
delete[] array;

View File

@ -55,38 +55,11 @@ bool ByteCodeInstruction::IsStore(void) const
bool ByteCodeInstruction::ChangesAccu(void) const
{
if (mCode == BC_LOAD_REG_16 || mCode == BC_LOAD_REG_32)
return true;
if (mCode >= BC_BINOP_ADDR_16 && mCode <= BC_BINOP_SHRR_I16)
return true;
if (mCode >= BC_BINOP_CMPUR_16 && mCode <= BC_BINOP_CMPSI_16)
return true;
if (mCode >= BC_OP_NEGATE_16 && mCode <= BC_OP_INVERT_16)
return true;
if (mCode >= BC_BINOP_ADD_F32 && mCode <= BC_OP_CEIL_F32)
return true;
if (mCode >= BC_CONV_U16_F32 && mCode <= BC_CONV_F32_I16)
return true;
if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_U16)
return true;
if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE)
return true;
if (mCode == BC_JSR || mCode == BC_CALL)
return true;
return ChangesRegister(BC_REG_ACCU);
}
bool ByteCodeInstruction::ChangesAddr(void) const
{
if (mCode == BC_ADDR_REG)
return true;
if (mCode >= BC_LOAD_ABS_U8 && mCode <= BC_STORE_ABS_32)
return true;
if (mCode == BC_JSR || mCode == BC_CALL)
return true;
return ChangesRegister(BC_REG_ADDR);
}
@ -160,6 +133,38 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
return true;
}
if (reg == BC_REG_ACCU)
{
if (mCode == BC_LOAD_REG_16 || mCode == BC_LOAD_REG_32)
return true;
if (mCode >= BC_BINOP_ADDR_16 && mCode <= BC_BINOP_SHRR_I16)
return true;
if (mCode >= BC_BINOP_CMPUR_16 && mCode <= BC_BINOP_CMPSI_16)
return true;
if (mCode >= BC_OP_NEGATE_16 && mCode <= BC_OP_INVERT_16)
return true;
if (mCode >= BC_BINOP_ADD_F32 && mCode <= BC_OP_CEIL_F32)
return true;
if (mCode >= BC_CONV_U16_F32 && mCode <= BC_CONV_F32_I16)
return true;
if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_U16)
return true;
if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE)
return true;
if (mCode == BC_JSR || mCode == BC_CALL)
return true;
}
if (reg == BC_REG_ADDR)
{
if (mCode == BC_ADDR_REG)
return true;
if (mCode >= BC_LOAD_ABS_U8 && mCode <= BC_STORE_ABS_32)
return true;
if (mCode == BC_JSR || mCode == BC_CALL)
return true;
}
return false;
}
@ -2537,6 +2542,16 @@ void ByteCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 0].mCode = BC_NOP;
mBranch = TransposeBranchCondition(mBranch);
}
else if (mIns[i + 0].mCode == BC_LOAD_REG_16 &&
mIns[i + 1].mCode == BC_STORE_REG_16 &&
mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister)
{
mIns[i + 2].mCode = BC_NOP;
}
else if (mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 2].mCode == BC_CONST_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 0].mValue == mIns[i + 2].mValue && !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister))
{
mIns[i + 2].mCode = BC_NOP;
}
}
if (i + 1 < mIns.Size())
{
@ -2601,6 +2616,13 @@ void ByteCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i].mRegister = BC_REG_ADDR;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
}
if ((mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) && accuTemp == mIns[i].mRegister)
@ -2948,9 +2970,12 @@ const char* ByteCodeProcedure::TempName(uint8 tmp, char* buffer, InterCodeProced
else if (tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize)
{
int i = 0;
while (i + 1 < proc->mTempOffset.Size() && proc->mTempOffset[i + 1] <= tmp - BC_REG_TMP)
while (i < proc->mTempOffset.Size() && proc->mTempOffset[i] != tmp - BC_REG_TMP)
i++;
if (i < proc->mTempOffset.Size())
sprintf_s(buffer, 10, "T%d", i);
else
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
else

View File

@ -24,6 +24,24 @@ ValueSet::ValueSet(const ValueSet& values)
mInstructions[i] = values.mInstructions[i];
}
ValueSet& ValueSet::operator=(const ValueSet& values)
{
int i;
mNum = values.mNum;
if (mSize != values.mSize)
{
delete[] mInstructions;
mSize = values.mSize;
mInstructions = new InterInstructionPtr[mSize];
}
for (i = 0; i < mNum; i++)
mInstructions[i] = values.mInstructions[i];
return *this;
}
ValueSet::~ValueSet(void)
{
delete[] mInstructions;
@ -265,7 +283,7 @@ static bool MemRange(const InterInstruction * ins, const GrowingInstructionPtrAr
return false;
}
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals)
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
{
InterMemory lmem, smem;
int lvindex, svindex;
@ -286,12 +304,31 @@ static bool StoreAliasing(const InterInstruction * lins, const InterInstruction*
if (lmem == IM_LOCAL)
return aliasedLocals[lvindex];
else if (lmem == IM_PARAM)
return aliasedParams[lvindex];
}
return true;
}
void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals)
void ValueSet::Intersect(ValueSet& set)
{
int k = 0;
for(int i=0; i<mNum; i++)
{
int j = 0;
while (j < set.mNum && mInstructions[i] != set.mInstructions[j])
j++;
if (j < set.mNum)
{
mInstructions[k] = mInstructions[i];
k++;
}
}
mNum = k;
}
void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
{
int i, value, temp;
@ -383,7 +420,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
i = 0;
while (i < mNum)
{
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals))
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals, aliasedParams))
{
mNum--;
if (mNum > 0)
@ -399,7 +436,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
i = 0;
while (i < mNum)
{
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals))
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals, aliasedParams))
{
mNum--;
if (mNum > 0)
@ -556,7 +593,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1;
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
return;
}
@ -575,7 +612,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[1] = -1;
assert(ins.mSTemp[0] >= 0);
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
return;
}
@ -586,7 +623,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1;
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
return;
}
@ -601,7 +638,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[1] = -1;
assert(ins.mSTemp[0] >= 0);
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
return;
}
@ -613,7 +650,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1;
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
return;
}
@ -623,7 +660,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mOperator = IA_NEG;
ins.mSTemp[1] = -1;
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
return;
}
@ -637,7 +674,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1;
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
return;
}
@ -647,7 +684,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[1] = -1;
assert(ins.mSTemp[0] >= 0);
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
return;
}
@ -864,7 +901,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1;
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
}
break;
case IT_POINTER:
@ -878,7 +915,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1;
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
}
else if (ins.mSTemp[1] == ins.mSTemp[0])
{
@ -904,7 +941,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1;
UpdateValue(ins, tvalue, aliasedLocals);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
}
break;
}
@ -1006,31 +1043,39 @@ static void FilterTempDefineUsage(NumberSet& requiredTemps, NumberSet& providedT
}
}
void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable)
void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable)
{
if (mCode == IC_CONSTANT)
{
if (mTType == IT_POINTER && mMemory == IM_LOCAL)
localTable[mTTemp] = mVarIndex;
else if (mTType == IT_POINTER && mMemory == IM_PARAM)
paramTable[mTTemp] = mVarIndex;
}
else if (mCode == IC_LEA)
{
if (mMemory == IM_LOCAL)
localTable[mTTemp] = localTable[mSTemp[1]];
else if (mMemory == IM_PARAM)
paramTable[mTTemp] = paramTable[mSTemp[1]];
}
else if (mCode == IC_LOAD_TEMPORARY)
{
localTable[mTTemp] = localTable[mSTemp[0]];
paramTable[mTTemp] = paramTable[mSTemp[0]];
}
}
void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals)
void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams)
{
if (mCode == IC_STORE)
{
int l = localTable[mSTemp[0]];
if (l >= 0)
aliasedLocals += l;
l = paramTable[mSTemp[0]];
if (l >= 0)
aliasedParams += l;
}
}
@ -1156,7 +1201,7 @@ void InterInstruction::BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSe
if (mSTemp[2] >= 0) requiredTemps += mSTemp[2];
}
bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, InterInstruction* pre, NumberSet& requiredTemps)
bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredTemps)
{
bool changed = false;
@ -1328,7 +1373,7 @@ void InterInstruction::ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeAr
if (mSTemp[2] >= 0) mSTemp[2] = set.Index(mSTemp[2]);
}
void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes)
void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes)
{
switch (mCode)
{
@ -1341,6 +1386,14 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
else
complexLocals += mVarIndex;
}
else if (mMemory == IM_PARAM && mSTemp[0] < 0)
{
paramTypes[mVarIndex] = mTType;
if (mOperandSize == 2)
simpleParams += mVarIndex;
else
complexParams += mVarIndex;
}
break;
case IC_STORE:
if (mMemory == IM_LOCAL && mSTemp[1] < 0)
@ -1351,14 +1404,26 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
else
complexLocals += mVarIndex;
}
else if (mMemory == IM_PARAM && mSTemp[1] < 0)
{
paramTypes[mVarIndex] = mSType[0];
if (mOperandSize == 2)
simpleParams += mVarIndex;
else
complexParams += mVarIndex;
}
break;
case IC_LEA:
if (mMemory == IM_LOCAL && mSTemp[1] < 0)
complexLocals += mVarIndex;
else if (mMemory == IM_PARAM && mSTemp[1] < 0)
complexParams += mVarIndex;
break;
case IC_CONSTANT:
if (mTType == IT_POINTER && mMemory == IM_LOCAL)
complexLocals += mVarIndex;
else if (mTType == IT_POINTER && mMemory == IM_PARAM)
complexParams += mVarIndex;
break;
}
}
@ -1476,8 +1541,14 @@ void InterInstruction::Disassemble(FILE* file)
if (mTTemp >= 0) fprintf(file, "R%d(%c)", mTTemp, typechars[mTType]);
fprintf(file, "\t<-\t");
if (mSTemp[2] >= 0) fprintf(file, "R%d(%c%c), ", mSTemp[2], typechars[mSType[2]], mSFinal[2] ? 'F' : '-');
if (mSTemp[1] >= 0) fprintf(file, "R%d(%c%c), ", mSTemp[1], typechars[mSType[1]], mSFinal[1] ? 'F' : '-');
if (mSTemp[0] >= 0) fprintf(file, "R%d(%c%c)", mSTemp[0], typechars[mSType[0]], mSFinal[0] ? 'F' : '-');
if (mSTemp[1] >= 0)
fprintf(file, "R%d(%c%c), ", mSTemp[1], typechars[mSType[1]], mSFinal[1] ? 'F' : '-');
else if (this->mCode == IC_STORE)
fprintf(file, "V%d+%d, ", mVarIndex, mSIntConst[1]);
if (mSTemp[0] >= 0)
fprintf(file, "R%d(%c%c)", mSTemp[0], typechars[mSType[0]], mSFinal[0] ? 'F' : '-');
else if (this->mCode == IC_LOAD)
fprintf(file, "V%d+%d", mVarIndex, mSIntConst[0]);
if (this->mCode == IC_CONSTANT)
{
if (mTType == IT_POINTER)
@ -1495,8 +1566,10 @@ void InterInstruction::Disassemble(FILE* file)
}
InterCodeBasicBlock::InterCodeBasicBlock(void)
: mInstructions(InterInstruction()), mEntryRenameTable(-1), mExitRenameTable(-1)
: mInstructions(InterInstruction()), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr)
{
mInPath = false;
mLoopHead = false;
}
InterCodeBasicBlock::~InterCodeBasicBlock(void)
@ -1533,9 +1606,13 @@ void InterCodeBasicBlock::GenerateTraces(void)
{
int i;
if (mInPath)
mLoopHead = true;
if (!mVisited)
{
mVisited = true;
mInPath = true;
for (;;)
{
@ -1575,6 +1652,8 @@ void InterCodeBasicBlock::GenerateTraces(void)
if (mTrueJump) mTrueJump->GenerateTraces();
if (mFalseJump) mFalseJump->GenerateTraces();
mInPath = false;
}
}
@ -2076,7 +2155,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
}
void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable)
void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable)
{
int i;
@ -2085,14 +2164,14 @@ void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable)
mVisited = true;
for (i = 0; i < mInstructions.Size(); i++)
mInstructions[i].CollectLocalAddressTemps(localTable);
mInstructions[i].CollectLocalAddressTemps(localTable, paramTable);
if (mTrueJump) mTrueJump->CollectLocalAddressTemps(localTable);
if (mFalseJump) mFalseJump->CollectLocalAddressTemps(localTable);
if (mTrueJump) mTrueJump->CollectLocalAddressTemps(localTable, paramTable);
if (mFalseJump) mFalseJump->CollectLocalAddressTemps(localTable, paramTable);
}
}
void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals)
void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams)
{
int i;
@ -2101,10 +2180,10 @@ void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTabl
mVisited = true;
for (i = 0; i < mInstructions.Size(); i++)
mInstructions[i].MarkAliasedLocalTemps(localTable, aliasedLocals);
mInstructions[i].MarkAliasedLocalTemps(localTable, aliasedLocals, paramTable, aliasedParams);
if (mTrueJump) mTrueJump->MarkAliasedLocalTemps(localTable, aliasedLocals);
if (mFalseJump) mFalseJump->MarkAliasedLocalTemps(localTable, aliasedLocals);
if (mTrueJump) mTrueJump->MarkAliasedLocalTemps(localTable, aliasedLocals, paramTable, aliasedParams);
if (mFalseJump) mFalseJump->MarkAliasedLocalTemps(localTable, aliasedLocals, paramTable, aliasedParams);
}
}
@ -2351,13 +2430,11 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr
NumberSet requiredVars(mExitRequiredVars);
int i;
for (i = mInstructions.Size() - 1; i > 0; i--)
for (i = mInstructions.Size() - 1; i >= 0; i--)
{
if (mInstructions[i].RemoveUnusedStoreInstructions(localVars, &(mInstructions[i - 1]), requiredVars))
if (mInstructions[i].RemoveUnusedStoreInstructions(localVars, requiredVars))
changed = true;
}
if (mInstructions[0].RemoveUnusedStoreInstructions(localVars, nullptr, requiredVars))
changed = true;
if (mTrueJump)
{
@ -2375,7 +2452,7 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr
}
void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals)
void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
{
int i;
@ -2384,32 +2461,57 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra
GrowingInstructionPtrArray ltvalue(tvalue);
ValueSet lvalues(values);
mVisited = true;
tvalid.Clear();
if (mNumEntries != 1)
if (mLoopHead)
{
lvalues.FlushAll();
ltvalue.Clear();
}
else
#if 0
else if (mNumEntries > 1)
{
lvalues.FlushAll();
ltvalue.Clear();
}
#endif
else if (mNumEntries > 0)
{
if (mNumEntered > 0)
{
lvalues.Intersect(mMergeValues);
for (int i = 0; i < ltvalue.Size(); i++)
{
if (mMergeTValues[i] != ltvalue[i])
ltvalue[i] = nullptr;
}
}
mNumEntered++;
if (mNumEntered < mNumEntries)
{
mMergeTValues = ltvalue;
mMergeValues = lvalues;
return;
}
}
mVisited = true;
tvalid.Clear();
for (i = 0; i < ltvalue.Size(); i++)
{
if (ltvalue[i])
tvalid += i;
}
}
for (i = 0; i < mInstructions.Size(); i++)
{
lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals);
lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams);
mInstructions[i].PerformValueForwarding(ltvalue, tvalid);
}
if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals);
if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals);
if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams);
if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams);
}
}
@ -2974,7 +3076,7 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
}
}
void InterCodeBasicBlock::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes)
void InterCodeBasicBlock::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes)
{
int i;
@ -2984,11 +3086,11 @@ void InterCodeBasicBlock::CollectSimpleLocals(FastNumberSet& complexLocals, Fast
for (i = 0; i < mInstructions.Size(); i++)
{
mInstructions[i].CollectSimpleLocals(complexLocals, simpleLocals, localTypes);
mInstructions[i].CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
}
if (mTrueJump) mTrueJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes);
if (mFalseJump) mFalseJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes);
if (mTrueJump) mTrueJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
if (mFalseJump) mFalseJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
}
}
@ -3055,7 +3157,8 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets)
{
mVisited = true;
fprintf(file, "L%d: (%d)\n", mIndex, mNumEntries);
const char* s = mLoopHead ? "Head" : "";
fprintf(file, "L%d: (%d) %s\n", mIndex, mNumEntries, s);
if (dumpSets)
{
@ -3106,7 +3209,10 @@ void InterCodeProcedure::ResetVisited(void)
int i;
for (i = 0; i < mBlocks.Size(); i++)
{
mBlocks[i]->mVisited = false;
mBlocks[i]->mNumEntered = 0;
}
}
void InterCodeProcedure::Append(InterCodeBasicBlock* block)
@ -3331,18 +3437,22 @@ void InterCodeProcedure::Close(void)
//
// Find all local variables that are never aliased
//
GrowingIntArray localTable(-1);
GrowingIntArray localTable(-1), paramTable(-1);
ResetVisited();
mBlocks[0]->CollectLocalAddressTemps(localTable);
mBlocks[0]->CollectLocalAddressTemps(localTable, paramTable);
int nlocals = 0;
int nlocals = 0, nparams = 0;
for (int i = 0; i < localTable.Size(); i++)
if (localTable[i] + 1 > nlocals)
nlocals = localTable[i] + 1;
for (int i = 0; i < paramTable.Size(); i++)
if (paramTable[i] + 1 > nparams)
nparams = paramTable[i] + 1;
mLocalAliasedSet.Reset(nlocals);
mParamAliasedSet.Reset(nparams);
ResetVisited();
mBlocks[0]->MarkAliasedLocalTemps(localTable, mLocalAliasedSet);
mBlocks[0]->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet);
//
// Now forward constant values
@ -3353,7 +3463,7 @@ void InterCodeProcedure::Close(void)
mValueForwardingTable.SetSize(numTemps, true);
ResetVisited();
mBlocks[0]->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet);
mBlocks[0]->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet);
DisassembleDebug("value forwarding");
@ -3441,8 +3551,11 @@ void InterCodeProcedure::Close(void)
FastNumberSet simpleLocals(nlocals), complexLocals(nlocals);
GrowingTypeArray localTypes(IT_NONE);
FastNumberSet simpleParams(nparams), complexParams(nparams);
GrowingTypeArray paramTypes(IT_NONE);
ResetVisited();
mBlocks[0]->CollectSimpleLocals(complexLocals, simpleLocals, localTypes);
mBlocks[0]->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
for (int i = 0; i < simpleLocals.Num(); i++)
{

View File

@ -123,13 +123,16 @@ public:
ValueSet(const ValueSet& values);
~ValueSet(void);
ValueSet& operator=(const ValueSet& values);
void FlushAll(void);
void FlushCallAliases(void);
void RemoveValue(int index);
void InsertValue(InterInstruction& ins);
void UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals);
void UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams);
void Intersect(ValueSet& set);
};
class TempForwardingTable
@ -276,13 +279,13 @@ public:
InterInstruction(void);
void SetCode(const Location & loc, InterCode code);
void CollectLocalAddressTemps(GrowingIntArray& localTable);
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals);
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable);
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
void FilterTempUsage(NumberSet& requiredVars, NumberSet& providedVars);
void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredTemps, NumberSet& providedTemps);
bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps, int numStaticTemps);
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, InterInstruction* pre, NumberSet& requiredTemps);
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredTemps);
void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps);
@ -297,7 +300,7 @@ public:
void CollectActiveTemporaries(FastNumberSet& set);
void ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeArray& temporaries);
void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes);
void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes);
void SimpleLocalToTemp(int vindex, int temp);
void Disassemble(FILE* file);
@ -351,11 +354,11 @@ public:
class InterCodeBasicBlock
{
public:
int mIndex, mNumEntries;
int mIndex, mNumEntries, mNumEntered;
InterCodeBasicBlock* mTrueJump, * mFalseJump;
GrowingInstructionArray mInstructions;
bool mVisited;
bool mVisited, mInPath, mLoopHead;
NumberSet mLocalRequiredTemps, mLocalProvidedTemps;
NumberSet mEntryRequiredTemps, mEntryProvidedTemps;
@ -365,6 +368,9 @@ public:
NumberSet mEntryRequiredVars, mEntryProvidedVars;
NumberSet mExitRequiredVars, mExitProvidedVars;
GrowingInstructionPtrArray mMergeTValues;
ValueSet mMergeValues;
InterCodeBasicBlock(void);
~InterCodeBasicBlock(void);
@ -376,8 +382,8 @@ public:
void LocalToTemp(int vindex, int temp);
void CollectLocalAddressTemps(GrowingIntArray& localTable);
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals);
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable);
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
void BuildLocalTempSets(int num, int numFixed);
void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps);
@ -399,13 +405,13 @@ public:
void CheckValueUsage(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue);
void PerformTempForwarding(TempForwardingTable& forwardingTable);
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals);
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams);
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
void BuildCollisionTable(NumberSet* collisionSets);
void ReduceTemporaries(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray & localTypes);
void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray & localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes);
void SimpleLocalToTemp(int vindex, int temp);
void CollectActiveTemporaries(FastNumberSet& set);
@ -434,7 +440,7 @@ protected:
TempForwardingTable mTempForwardingTable;
GrowingInstructionPtrArray mValueForwardingTable;
int numFixedTemporaries;
NumberSet mLocalAliasedSet;
NumberSet mLocalAliasedSet, mParamAliasedSet;
void ResetVisited(void);
public:

View File

@ -445,6 +445,28 @@ bool NativeCodeInstruction::ChangesAddress(void) const
}
bool NativeCodeInstruction::SameEffectiveAddress(const NativeCodeInstruction& ins) const
{
if (mMode != ins.mMode)
return false;
switch (mMode)
{
case ASMIM_ZERO_PAGE:
case ASMIM_ZERO_PAGE_X:
case ASMIM_ZERO_PAGE_Y:
case ASMIM_INDIRECT_X:
case ASMIM_INDIRECT_Y:
return ins.mAddress == mAddress;
case ASMIM_ABSOLUTE:
case ASMIM_ABSOLUTE_X:
case ASMIM_ABSOLUTE_Y:
return (ins.mVarIndex == mVarIndex && ins.mAddress == mAddress && ins.mFunction == mFunction && ins.mRuntime == mRuntime);
default:
return false;
}
}
bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
{
bool changed = false;
@ -2645,10 +2667,10 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
{
if (sins0)
{
insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg);
insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg + 1);
insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_WORK + 0);
insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_WORK + 1);
LoadValueToReg(proc, *sins0, treg, nullptr, nullptr);
LoadValueToReg(proc, *sins0, BC_REG_WORK, nullptr, nullptr);
}
else
{
@ -3784,7 +3806,34 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i].mType = ASMIT_NOP;
progress = true;
}
else if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 2].mAddress &&
mIns[i + 1].mType == ASMIT_INC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && (mIns[i + 2].mLive & LIVE_CPU_REG_C) == 0)
{
mIns[i + 0].mType = ASMIT_CLC;
mIns[i + 0].mMode = ASMIM_IMPLIED;
mIns[i + 1].mType = ASMIT_ADC;
mIns[i + 1].mMode = ASMIM_IMMEDIATE;
mIns[i + 1].mAddress = 1;
mIns[i + 2].mType = ASMIT_STA;
progress = true;
}
}
if (i + 3 < mIns.Size())
{
if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) &&
mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
(mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) &&
(mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0)
{
mIns[i + 0].mType = ASMIT_NOP;
mIns[i + 1].mType = ASMIT_NOP;
mIns[i + 2].mType = ASMIT_NOP;
mIns[i + 3].mType = ASMIT_INC;
}
}
if (i + 4 < mIns.Size())
{

View File

@ -46,6 +46,7 @@ public:
bool LoadsAccu(void) const;
bool ChangesAddress(void) const;
bool SameEffectiveAddress(const NativeCodeInstruction& ins) const;
};
class NativeCodeBasicBlock

View File

@ -549,6 +549,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
{
dtype->mFlags |= DTF_DEFINED;
dtype->mSize = index;
dec->mSize = index;
}
}
else