Code size optimization

This commit is contained in:
drmortalwombat 2021-10-15 21:52:07 +02:00
parent 35a4658f28
commit 438a926b88
6 changed files with 480 additions and 129 deletions

View File

@ -249,6 +249,16 @@ public:
array[at] = t; array[at] = t;
} }
void Remove(int at)
{
while (at + 1 < size)
{
array[at] = array[at + 1];
at++;
}
Grow(at, false);
}
T Top(void) const T Top(void) const
{ {
return array[size - 1]; return array[size - 1];

View File

@ -123,6 +123,20 @@ bool ByteCodeInstruction::IsLocalAccess(void) const
return IsLocalStore() || IsLocalLoad(); return IsLocalStore() || IsLocalLoad();
} }
bool ByteCodeInstruction::IsShiftByRegister(void) const
{
return
mCode == BC_BINOP_SHLR_16 || mCode == BC_BINOP_SHRR_I16 || mCode == BC_BINOP_SHRR_U16 ||
mCode == BC_BINOP_SHL_L32 || mCode == BC_BINOP_SHR_U32 || mCode == BC_BINOP_SHR_I32;
}
bool ByteCodeInstruction::IsIntegerConst(void) const
{
return mCode >= BC_CONST_8 && mCode <= BC_CONST_32;
}
bool ByteCodeInstruction::IsSame(const ByteCodeInstruction& ins) const bool ByteCodeInstruction::IsSame(const ByteCodeInstruction& ins) const
{ {
@ -3405,6 +3419,17 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 2].mCode = BC_NOP; mIns[i + 2].mCode = BC_NOP;
progress = true; progress = true;
} }
else if (
mIns[i + 0].mCode == BC_LOAD_REG_8 &&
mIns[i + 1].mCode == BC_STORE_REG_16 &&
mIns[i + 2].IsIntegerConst() && mIns[i + 2].mRegister == BC_REG_ACCU &&
mIns[i + 3].IsShiftByRegister() && mIns[i + 3].mRegister == mIns[i + 1].mRegister && mIns[i + 3].mRegisterFinal)
{
mIns[i + 0].mCode = BC_NOP;
mIns[i + 1].mCode = BC_NOP;
mIns[i + 3].mRegister = mIns[i + 0].mRegister;
progress = true;
}
} }
#endif #endif
#if 1 #if 1
@ -3658,6 +3683,12 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i].mCode = BC_NOP; mIns[i].mCode = BC_NOP;
progress = true; progress = true;
} }
else if (mIns[i].mCode == BC_STORE_REG_8 && mIns[i + 1].mCode == BC_LOAD_REG_8 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i + 1].mRegister = BC_REG_ACCU;
mIns[i].mCode = BC_NOP;
progress = true;
}
#if 0 #if 0
else if ((mIns[i].mCode == BC_LOAD_LOCAL_16 || mIns[i].mCode == BC_LOAD_ABS_16) && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) else if ((mIns[i].mCode == BC_LOAD_LOCAL_16 || mIns[i].mCode == BC_LOAD_ABS_16) && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{ {

View File

@ -201,6 +201,8 @@ public:
bool IsLocalStore(void) const; bool IsLocalStore(void) const;
bool IsLocalLoad(void) const; bool IsLocalLoad(void) const;
bool IsLocalAccess(void) const; bool IsLocalAccess(void) const;
bool IsShiftByRegister(void) const;
bool IsIntegerConst(void) const;
bool IsCommutative(void) const; bool IsCommutative(void) const;
bool IsSame(const ByteCodeInstruction& ins) const; bool IsSame(const ByteCodeInstruction& ins) const;

View File

@ -429,6 +429,28 @@ bool InterInstruction::ReferencesTemp(int temp) const
return false; return false;
} }
bool InterInstruction::IsEqual(const InterInstruction* ins) const
{
if (mCode != ins->mCode)
return false;
if (mCode == IC_BINARY_OPERATOR || mCode == IC_UNARY_OPERATOR || mCode == IC_RELATIONAL_OPERATOR || mCode == IC_CONVERSION_OPERATOR)
{
if (mOperator != ins->mOperator)
return false;
}
if (!mDst.IsEqual(ins->mDst))
return false;
for (int i = 0; i < mNumOperands; i++)
if (!mSrc[i].IsEqual(ins->mSrc[i]))
return false;
return true;
}
void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams) void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
{ {
int i, value, temp; int i, value, temp;
@ -1063,6 +1085,25 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
} }
} }
InterOperand::InterOperand(void)
: mTemp(INVALID_TEMPORARY), mType(IT_NONE), mFinal(false), mIntConst(0), mFloatConst(0), mVarIndex(-1), mOperandSize(0), mLinkerObject(nullptr), mMemory(IM_NONE)
{}
bool InterOperand::IsEqual(const InterOperand& op) const
{
if (mType != op.mType || mTemp != op.mTemp)
return false;
if (mMemory != op.mMemory)
return false;
if (mIntConst != op.mIntConst || mFloatConst != op.mFloatConst || mVarIndex != op.mVarIndex || mLinkerObject != op.mLinkerObject)
return false;
return true;
}
InterInstruction::InterInstruction(void) InterInstruction::InterInstruction(void)
{ {
mCode = IC_NONE; mCode = IC_NONE;
@ -1176,20 +1217,39 @@ void InterInstruction::FilterTempUsage(NumberSet& requiredTemps, NumberSet& prov
FilterTempDefineUsage(requiredTemps, providedTemps, mDst.mTemp); FilterTempDefineUsage(requiredTemps, providedTemps, mDst.mTemp);
} }
void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars) void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory)
{ {
if (mCode == IC_LOAD && mSrc[0].mMemory == IM_LOCAL) if (mCode == IC_LOAD)
{ {
assert(mSrc[0].mTemp < 0); if (mSrc[0].mMemory == IM_LOCAL)
if (!providedVars[mSrc[0].mVarIndex]) {
requiredVars += mSrc[0].mVarIndex; assert(mSrc[0].mTemp < 0);
if (!providedVars[mSrc[0].mVarIndex])
requiredVars += mSrc[0].mVarIndex;
}
else if (mSrc[0].mMemory == paramMemory)
{
assert(mSrc[0].mTemp < 0);
if (!providedParams[mSrc[0].mVarIndex])
requiredParams += mSrc[0].mVarIndex;
}
} }
else if (mCode == IC_STORE && mSrc[1].mMemory == IM_LOCAL) else if (mCode == IC_STORE)
{ {
assert(mSrc[1].mTemp < 0); if (mSrc[1].mMemory == IM_LOCAL)
if (!providedVars[mSrc[1].mVarIndex] && (mSrc[1].mIntConst != 0 || mSrc[1].mOperandSize != localVars[mSrc[1].mVarIndex]->mSize)) {
requiredVars += mSrc[1].mVarIndex; assert(mSrc[1].mTemp < 0);
providedVars += mSrc[1].mVarIndex; if (!providedVars[mSrc[1].mVarIndex] && (mSrc[1].mIntConst != 0 || mSrc[1].mOperandSize != localVars[mSrc[1].mVarIndex]->mSize))
requiredVars += mSrc[1].mVarIndex;
providedVars += mSrc[1].mVarIndex;
}
else if (mSrc[1].mMemory == paramMemory)
{
assert(mSrc[1].mTemp < 0);
if (!providedParams[mSrc[1].mVarIndex] && (mSrc[1].mIntConst != 0 || mSrc[1].mOperandSize != params[mSrc[1].mVarIndex]->mSize))
requiredParams += mSrc[1].mVarIndex;
providedParams += mSrc[1].mVarIndex;
}
} }
} }
@ -1271,11 +1331,11 @@ bool HasSideEffect(InterCode code)
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER; return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER;
} }
bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps, int numStaticTemps) bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps)
{ {
bool changed = false; bool changed = false;
if (pre && mCode == IC_LOAD_TEMPORARY && pre->mDst.mTemp == mSrc[0].mTemp && !requiredTemps[mSrc[0].mTemp] && pre->mDst.mTemp >= numStaticTemps) if (pre && mCode == IC_LOAD_TEMPORARY && pre->mDst.mTemp == mSrc[0].mTemp && !requiredTemps[mSrc[0].mTemp] && pre->mDst.mTemp >= 0)
{ {
// previous instruction produced result, but it is not needed here // previous instruction produced result, but it is not needed here
pre->mDst.mTemp = mDst.mTemp; pre->mDst.mTemp = mDst.mTemp;
@ -1289,7 +1349,7 @@ bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, Num
} }
else if (mDst.mTemp != -1) else if (mDst.mTemp != -1)
{ {
if (!requiredTemps[mDst.mTemp] && mDst.mTemp >= numStaticTemps) if (!requiredTemps[mDst.mTemp] && mDst.mTemp >= 0)
{ {
if (!HasSideEffect(mCode)) if (!HasSideEffect(mCode))
{ {
@ -1313,7 +1373,7 @@ bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, Num
for (int i = 0; i < mNumOperands; i++) for (int i = 0; i < mNumOperands; i++)
{ {
if (mSrc[i].mTemp >= 0) mSrc[i].mFinal = !requiredTemps[mSrc[i].mTemp] && mSrc[i].mTemp >= numStaticTemps; if (mSrc[i].mTemp >= 0) mSrc[i].mFinal = !requiredTemps[mSrc[i].mTemp] && mSrc[i].mTemp >= 0;
} }
for (int i = 0; i < mNumOperands; i++) for (int i = 0; i < mNumOperands; i++)
@ -1336,7 +1396,7 @@ void InterInstruction::BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSe
if (mSrc[i].mTemp >= 0) requiredTemps += mSrc[i].mTemp; if (mSrc[i].mTemp >= 0) requiredTemps += mSrc[i].mTemp;
} }
bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredTemps) bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory)
{ {
bool changed = false; bool changed = false;
@ -1344,7 +1404,11 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
{ {
if (mSrc[0].mMemory == IM_LOCAL) if (mSrc[0].mMemory == IM_LOCAL)
{ {
requiredTemps += mSrc[0].mVarIndex; requiredVars += mSrc[0].mVarIndex;
}
else if (mSrc[0].mMemory == paramMemory)
{
requiredParams += mSrc[0].mVarIndex;
} }
} }
else if (mCode == IC_STORE) else if (mCode == IC_STORE)
@ -1353,10 +1417,25 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
{ {
if (localVars[mSrc[1].mVarIndex]->mAliased) if (localVars[mSrc[1].mVarIndex]->mAliased)
; ;
else if (requiredTemps[mSrc[1].mVarIndex]) else if (requiredVars[mSrc[1].mVarIndex])
{ {
if (mSrc[1].mIntConst == 0 && mSrc[1].mOperandSize == localVars[mSrc[1].mVarIndex]->mSize) if (mSrc[1].mIntConst == 0 && mSrc[1].mOperandSize == localVars[mSrc[1].mVarIndex]->mSize)
requiredTemps -= mSrc[1].mVarIndex; requiredVars -= mSrc[1].mVarIndex;
}
else
{
mCode = IC_NONE;
changed = true;
}
}
else if (mSrc[1].mMemory == paramMemory)
{
if (params[mSrc[1].mVarIndex]->mAliased)
;
else if (requiredParams[mSrc[1].mVarIndex])
{
if (mSrc[1].mIntConst == 0 && mSrc[1].mOperandSize == params[mSrc[1].mVarIndex]->mSize)
requiredParams -= mSrc[1].mVarIndex;
} }
else else
{ {
@ -1424,12 +1503,12 @@ void InterInstruction::PerformValueForwarding(GrowingInstructionPtrArray& tvalue
} }
} }
void InterInstruction::LocalRenameRegister(GrowingIntArray& renameTable, int& num, int fixed) void InterInstruction::LocalRenameRegister(GrowingIntArray& renameTable, int& num)
{ {
for (int i = 0; i < mNumOperands; i++) for (int i = 0; i < mNumOperands; i++)
if (mSrc[i].mTemp >= 0) mSrc[i].mTemp = renameTable[mSrc[i].mTemp]; if (mSrc[i].mTemp >= 0) mSrc[i].mTemp = renameTable[mSrc[i].mTemp];
if (mDst.mTemp >= fixed) if (mDst.mTemp >= 0)
{ {
renameTable[mDst.mTemp] = num; renameTable[mDst.mTemp] = num;
mDst.mTemp = num++; mDst.mTemp = num++;
@ -2465,7 +2544,7 @@ bool InterCodeBasicBlock::PropagateConstTemps(const GrowingInstructionPtrArray&
return changed; return changed;
} }
void InterCodeBasicBlock::BuildLocalTempSets(int num, int numFixed) void InterCodeBasicBlock::BuildLocalTempSets(int num)
{ {
int i; int i;
@ -2489,14 +2568,8 @@ void InterCodeBasicBlock::BuildLocalTempSets(int num, int numFixed)
mEntryRequiredTemps = mLocalRequiredTemps; mEntryRequiredTemps = mLocalRequiredTemps;
exitProvidedTemps = mLocalProvidedTemps; exitProvidedTemps = mLocalProvidedTemps;
for (i = 0; i < numFixed; i++) if (mTrueJump) mTrueJump->BuildLocalTempSets(num);
{ if (mFalseJump) mFalseJump->BuildLocalTempSets(num);
mEntryRequiredTemps += i;
exitProvidedTemps += i;
}
if (mTrueJump) mTrueJump->BuildLocalTempSets(num, numFixed);
if (mFalseJump) mFalseJump->BuildLocalTempSets(num, numFixed);
} }
} }
@ -2591,7 +2664,7 @@ bool InterCodeBasicBlock::BuildGlobalRequiredTempSet(NumberSet& fromRequiredTemp
return revisit; return revisit;
} }
bool InterCodeBasicBlock::RemoveUnusedResultInstructions(int numStaticTemps) bool InterCodeBasicBlock::RemoveUnusedResultInstructions(void)
{ {
bool changed = false; bool changed = false;
@ -2602,28 +2675,25 @@ bool InterCodeBasicBlock::RemoveUnusedResultInstructions(int numStaticTemps)
NumberSet requiredTemps(mExitRequiredTemps); NumberSet requiredTemps(mExitRequiredTemps);
int i; int i;
for (i = 0; i < numStaticTemps; i++)
requiredTemps += i;
if (mInstructions.Size() > 0) if (mInstructions.Size() > 0)
{ {
for (i = mInstructions.Size() - 1; i > 0; i--) for (i = mInstructions.Size() - 1; i > 0; i--)
{ {
if (mInstructions[i]->RemoveUnusedResultInstructions(mInstructions[i - 1], requiredTemps, numStaticTemps)) if (mInstructions[i]->RemoveUnusedResultInstructions(mInstructions[i - 1], requiredTemps))
changed = true; changed = true;
} }
if (mInstructions[0]->RemoveUnusedResultInstructions(NULL, requiredTemps, numStaticTemps)) if (mInstructions[0]->RemoveUnusedResultInstructions(NULL, requiredTemps))
changed = true; changed = true;
} }
if (mTrueJump) if (mTrueJump)
{ {
if (mTrueJump->RemoveUnusedResultInstructions(numStaticTemps)) if (mTrueJump->RemoveUnusedResultInstructions())
changed = true; changed = true;
} }
if (mFalseJump) if (mFalseJump)
{ {
if (mFalseJump->RemoveUnusedResultInstructions(numStaticTemps)) if (mFalseJump->RemoveUnusedResultInstructions())
changed = true; changed = true;
} }
} }
@ -2651,7 +2721,7 @@ void InterCodeBasicBlock::BuildCallerSaveTempSet(NumberSet& callerSaveTemps)
} }
void InterCodeBasicBlock::BuildLocalVariableSets(const GrowingVariableArray& localVars) void InterCodeBasicBlock::BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory)
{ {
int i; int i;
@ -2667,34 +2737,48 @@ void InterCodeBasicBlock::BuildLocalVariableSets(const GrowingVariableArray& loc
mExitRequiredVars = NumberSet(localVars.Size()); mExitRequiredVars = NumberSet(localVars.Size());
mExitProvidedVars = NumberSet(localVars.Size()); mExitProvidedVars = NumberSet(localVars.Size());
mLocalRequiredParams = NumberSet(params.Size());
mLocalProvidedParams = NumberSet(params.Size());
mEntryRequiredParams = NumberSet(params.Size());
mEntryProvidedParams = NumberSet(params.Size());
mExitRequiredParams = NumberSet(params.Size());
mExitProvidedParams = NumberSet(params.Size());
for (i = 0; i < mInstructions.Size(); i++) for (i = 0; i < mInstructions.Size(); i++)
{ {
mInstructions[i]->FilterVarsUsage(localVars, mLocalRequiredVars, mLocalProvidedVars); mInstructions[i]->FilterVarsUsage(localVars, mLocalRequiredVars, mLocalProvidedVars, params, mLocalRequiredParams, mLocalProvidedParams, paramMemory);
} }
mEntryRequiredVars = mLocalRequiredVars; mEntryRequiredVars = mLocalRequiredVars;
mExitProvidedVars = mLocalProvidedVars; mExitProvidedVars = mLocalProvidedVars;
if (mTrueJump) mTrueJump->BuildLocalVariableSets(localVars); mEntryRequiredParams = mLocalRequiredParams;
if (mFalseJump) mFalseJump->BuildLocalVariableSets(localVars); mExitProvidedParams = mLocalProvidedParams;
if (mTrueJump) mTrueJump->BuildLocalVariableSets(localVars, params, paramMemory);
if (mFalseJump) mFalseJump->BuildLocalVariableSets(localVars, params, paramMemory);
} }
} }
void InterCodeBasicBlock::BuildGlobalProvidedVariableSet(const GrowingVariableArray& localVars, NumberSet fromProvidedVars) void InterCodeBasicBlock::BuildGlobalProvidedVariableSet(const GrowingVariableArray& localVars, NumberSet fromProvidedVars, const GrowingVariableArray& params, NumberSet fromProvidedParams, InterMemory paramMemory)
{ {
if (!mVisited || !(fromProvidedVars <= mEntryProvidedVars)) if (!mVisited || !(fromProvidedVars <= mEntryProvidedVars) || !(fromProvidedParams <= mEntryProvidedParams))
{ {
mEntryProvidedVars |= fromProvidedVars; mEntryProvidedVars |= fromProvidedVars;
fromProvidedVars |= mExitProvidedVars; fromProvidedVars |= mExitProvidedVars;
mEntryProvidedParams |= fromProvidedParams;
fromProvidedParams |= mExitProvidedParams;
mVisited = true; mVisited = true;
if (mTrueJump) mTrueJump->BuildGlobalProvidedVariableSet(localVars, fromProvidedVars); if (mTrueJump) mTrueJump->BuildGlobalProvidedVariableSet(localVars, fromProvidedVars, params, fromProvidedParams, paramMemory);
if (mFalseJump) mFalseJump->BuildGlobalProvidedVariableSet(localVars, fromProvidedVars); if (mFalseJump) mFalseJump->BuildGlobalProvidedVariableSet(localVars, fromProvidedVars, params, fromProvidedParams, paramMemory);
} }
} }
bool InterCodeBasicBlock::BuildGlobalRequiredVariableSet(const GrowingVariableArray& localVars, NumberSet& fromRequiredVars) bool InterCodeBasicBlock::BuildGlobalRequiredVariableSet(const GrowingVariableArray& localVars, NumberSet& fromRequiredVars, const GrowingVariableArray& params, NumberSet& fromRequiredParams, InterMemory paramMemory)
{ {
bool revisit = false; bool revisit = false;
int i; int i;
@ -2704,27 +2788,33 @@ bool InterCodeBasicBlock::BuildGlobalRequiredVariableSet(const GrowingVariableAr
mVisited = true; mVisited = true;
NumberSet newRequiredVars(mExitRequiredVars); NumberSet newRequiredVars(mExitRequiredVars);
NumberSet newRequiredParams(mExitRequiredParams);
if (mTrueJump && mTrueJump->BuildGlobalRequiredVariableSet(localVars, newRequiredVars)) revisit = true; if (mTrueJump && mTrueJump->BuildGlobalRequiredVariableSet(localVars, newRequiredVars, params, newRequiredParams, paramMemory)) revisit = true;
if (mFalseJump && mFalseJump->BuildGlobalRequiredVariableSet(localVars, newRequiredVars)) revisit = true; if (mFalseJump && mFalseJump->BuildGlobalRequiredVariableSet(localVars, newRequiredVars, params, newRequiredParams, paramMemory)) revisit = true;
if (!(newRequiredVars <= mExitRequiredVars)) if (!(newRequiredVars <= mExitRequiredVars) || !(newRequiredParams <= mExitRequiredParams))
{ {
revisit = true; revisit = true;
mExitRequiredVars = newRequiredVars; mExitRequiredVars = newRequiredVars;
newRequiredVars -= mLocalProvidedVars; newRequiredVars -= mLocalProvidedVars;
mEntryRequiredVars |= newRequiredVars; mEntryRequiredVars |= newRequiredVars;
mExitRequiredParams = newRequiredParams;
newRequiredParams -= mLocalProvidedParams;
mEntryRequiredParams |= newRequiredParams;
} }
} }
fromRequiredVars |= mEntryRequiredVars; fromRequiredVars |= mEntryRequiredVars;
fromRequiredParams |= mEntryRequiredParams;
return revisit; return revisit;
} }
bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars) bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory)
{ {
bool changed = false; bool changed = false;
@ -2733,22 +2823,24 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr
mVisited = true; mVisited = true;
NumberSet requiredVars(mExitRequiredVars); NumberSet requiredVars(mExitRequiredVars);
NumberSet requiredParams(mExitRequiredParams);
int i; int i;
for (i = mInstructions.Size() - 1; i >= 0; i--) for (i = mInstructions.Size() - 1; i >= 0; i--)
{ {
if (mInstructions[i]->RemoveUnusedStoreInstructions(localVars, requiredVars)) if (mInstructions[i]->RemoveUnusedStoreInstructions(localVars, requiredVars, params, requiredParams, paramMemory))
changed = true; changed = true;
} }
if (mTrueJump) if (mTrueJump)
{ {
if (mTrueJump->RemoveUnusedStoreInstructions(localVars)) if (mTrueJump->RemoveUnusedStoreInstructions(localVars, params, paramMemory))
changed = true; changed = true;
} }
if (mFalseJump) if (mFalseJump)
{ {
if (mFalseJump->RemoveUnusedStoreInstructions(localVars)) if (mFalseJump->RemoveUnusedStoreInstructions(localVars, params, paramMemory))
changed = true; changed = true;
} }
} }
@ -3102,7 +3194,7 @@ static int Find(GrowingIntArray& table, int i)
} }
void InterCodeBasicBlock::LocalRenameRegister(const GrowingIntArray& renameTable, int& num, int fixed) void InterCodeBasicBlock::LocalRenameRegister(const GrowingIntArray& renameTable, int& num)
{ {
int i; int i;
@ -3115,12 +3207,7 @@ void InterCodeBasicBlock::LocalRenameRegister(const GrowingIntArray& renameTable
for (i = 0; i < renameTable.Size(); i++) for (i = 0; i < renameTable.Size(); i++)
{ {
if (i < fixed) if (mEntryRequiredTemps[i])
{
mEntryRenameTable[i] = i;
mExitRenameTable[i] = i;
}
else if (mEntryRequiredTemps[i])
{ {
if (renameTable[i] < 0) if (renameTable[i] < 0)
{ {
@ -3141,11 +3228,11 @@ void InterCodeBasicBlock::LocalRenameRegister(const GrowingIntArray& renameTable
for (i = 0; i < mInstructions.Size(); i++) for (i = 0; i < mInstructions.Size(); i++)
{ {
mInstructions[i]->LocalRenameRegister(mExitRenameTable, num, fixed); mInstructions[i]->LocalRenameRegister(mExitRenameTable, num);
} }
if (mTrueJump) mTrueJump->LocalRenameRegister(mExitRenameTable, num, fixed); if (mTrueJump) mTrueJump->LocalRenameRegister(mExitRenameTable, num);
if (mFalseJump) mFalseJump->LocalRenameRegister(mExitRenameTable, num, fixed); if (mFalseJump) mFalseJump->LocalRenameRegister(mExitRenameTable, num);
} }
} }
@ -3455,6 +3542,87 @@ static bool CanBypassStore(const InterInstruction * sins, const InterInstruction
return true; return true;
} }
void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc)
{
if (!mVisited)
{
mVisited = true;
if (mTrueJump && mFalseJump && mInstructions.Size() > 2)
{
InterCodeBasicBlock* block = new InterCodeBasicBlock();
proc->Append(block);
if (mInstructions[mInstructions.Size() - 2]->mCode == IC_RELATIONAL_OPERATOR)
{
block->mInstructions.Push(mInstructions[mInstructions.Size() - 2]);
block->mInstructions.Push(mInstructions[mInstructions.Size() - 1]);
mInstructions.SetSize(mInstructions.Size() - 2);
}
else
{
block->mInstructions.Push(mInstructions.Pop());
}
InterInstruction* jins = new InterInstruction();
jins->mCode = IC_JUMP;
mInstructions.Push(jins);
block->Close(mTrueJump, mFalseJump);
mTrueJump = block;
mFalseJump = nullptr;
block->mNumEntries = 1;
block->SplitBranches(proc);
}
else
{
if (mTrueJump)
mTrueJump->SplitBranches(proc);
if (mFalseJump)
mFalseJump->SplitBranches(proc);
}
}
}
bool InterCodeBasicBlock::IsEqual(const InterCodeBasicBlock* block) const
{
if (mTrueJump == block->mTrueJump && mFalseJump == block->mFalseJump && mInstructions.Size() == block->mInstructions.Size())
{
for (int i = 0; i < mInstructions.Size(); i++)
if (!mInstructions[i]->IsEqual(block->mInstructions[i]))
return false;
return true;
}
return false;
}
void InterCodeBasicBlock::FollowJumps(void)
{
if (!mVisited)
{
mVisited = true;
while (mInstructions.Size() > 0 && mInstructions[mInstructions.Size() - 1]->mCode == IC_JUMP && mTrueJump->mNumEntries == 1)
{
InterCodeBasicBlock* block = mTrueJump;
mInstructions.SetSize(mInstructions.Size() - 1);
for (int i = 0; i < block->mInstructions.Size(); i++)
mInstructions.Push(block->mInstructions[i]);
block->mNumEntries = 0;
block->mInstructions.Clear();
mTrueJump = block->mTrueJump;
mFalseJump = block->mFalseJump;
}
if (mTrueJump)
mTrueJump->FollowJumps();
if (mFalseJump)
mFalseJump->FollowJumps();
}
}
InterCodeBasicBlock* InterCodeBasicBlock::PropagateDominator(InterCodeProcedure* proc) InterCodeBasicBlock* InterCodeBasicBlock::PropagateDominator(InterCodeProcedure* proc)
{ {
if (!mVisited) if (!mVisited)
@ -3667,6 +3835,8 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
int limit = mInstructions.Size() - 1; int limit = mInstructions.Size() - 1;
if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH) if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH)
limit -= 2; limit -= 2;
else if (limit >= 0 && mInstructions[limit]->mCode == IC_JUMP)
limit -= 1;
int i = limit; int i = limit;
@ -3845,7 +4015,7 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
} }
void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars) void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars, GrowingVariableArray& paramVars, InterMemory paramMemory)
{ {
int i; int i;
@ -3873,6 +4043,17 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
localVars[varIndex]->mSize = size; localVars[varIndex]->mSize = size;
localVars[varIndex]->mAliased = true; localVars[varIndex]->mAliased = true;
} }
else if (ins->mConst.mMemory == paramMemory)
{
int varIndex = ins->mConst.mVarIndex;
if (!paramVars[varIndex])
paramVars[varIndex] = new InterVariable;
int size = ins->mConst.mOperandSize + ins->mConst.mIntConst;
if (size > paramVars[varIndex]->mSize)
paramVars[varIndex]->mSize = size;
paramVars[varIndex]->mAliased = true;
}
break; break;
case IC_STORE: case IC_STORE:
@ -3892,13 +4073,23 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
if (size > localVars[varIndex]->mSize) if (size > localVars[varIndex]->mSize)
localVars[varIndex]->mSize = size; localVars[varIndex]->mSize = size;
} }
else if (ins->mSrc[j].mMemory == IM_FPARAM || ins->mSrc[j].mMemory == IM_PARAM)
{
int varIndex = ins->mSrc[j].mVarIndex;
if (!paramVars[varIndex])
paramVars[varIndex] = new InterVariable;
int size = ins->mSrc[j].mOperandSize + ins->mSrc[j].mIntConst;
if (size > paramVars[varIndex]->mSize)
paramVars[varIndex]->mSize = size;
}
} }
break; break;
} }
} }
if (mTrueJump) mTrueJump->CollectVariables(globalVars, localVars); if (mTrueJump) mTrueJump->CollectVariables(globalVars, localVars, paramVars, paramMemory);
if (mFalseJump) mFalseJump->CollectVariables(globalVars, localVars); if (mFalseJump) mFalseJump->CollectVariables(globalVars, localVars, paramVars, paramMemory);
} }
} }
@ -4019,9 +4210,9 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets)
InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & location, const Ident* ident, LinkerObject * linkerObject) InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & location, const Ident* ident, LinkerObject * linkerObject)
: mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1), mTempSizes(0), : mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1), mTempSizes(0),
mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1), mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1),
mValueForwardingTable(nullptr), mLocalVars(nullptr), mModule(mod), mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod),
mIdent(ident), mLinkerObject(linkerObject), mIdent(ident), mLinkerObject(linkerObject),
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr) mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false)
{ {
mID = mModule->mProcedures.Size(); mID = mModule->mProcedures.Size();
mModule->mProcedures.Push(this); mModule->mProcedures.Push(this);
@ -4096,7 +4287,7 @@ void InterCodeProcedure::BuildDataFlowSets(void)
// Build set with local provided/required temporaries // Build set with local provided/required temporaries
// //
ResetVisited(); ResetVisited();
mEntryBlock->BuildLocalTempSets(numTemps, numFixedTemporaries); mEntryBlock->BuildLocalTempSets(numTemps);
// //
// Build set of globaly provided temporaries // Build set of globaly provided temporaries
@ -4126,15 +4317,13 @@ void InterCodeProcedure::RenameTemporaries(void)
int i, j, numRename; int i, j, numRename;
numRename = numFixedTemporaries; numRename = 0;
for (i = 0; i < numRename; i++)
mRenameTable[i] = i;
// //
// First localy rename all temporaries // First localy rename all temporaries
// //
ResetVisited(); ResetVisited();
mEntryBlock->LocalRenameRegister(mRenameTable, numRename, numFixedTemporaries); mEntryBlock->LocalRenameRegister(mRenameTable, numRename);
DisassembleDebug("local renamed temps"); DisassembleDebug("local renamed temps");
@ -4162,12 +4351,9 @@ void InterCodeProcedure::RenameTemporaries(void)
mGlobalRenameTable.SetSize(numRename, true); mGlobalRenameTable.SetSize(numRename, true);
for (i = 0; i < numFixedTemporaries; i++) numRenamedTemps = 0;
mGlobalRenameTable[i] = i;
numRenamedTemps = numFixedTemporaries; for (i = 0; i < numRename; i++)
for (i = numFixedTemporaries; i < numRename; i++)
{ {
j = Find(mRenameUnionTable, i); j = Find(mRenameUnionTable, i);
@ -4216,7 +4402,7 @@ void InterCodeProcedure::RemoveUnusedInstructions(void)
do { do {
ResetVisited(); ResetVisited();
mEntryBlock->BuildLocalTempSets(numTemps, numFixedTemporaries); mEntryBlock->BuildLocalTempSets(numTemps);
ResetVisited(); ResetVisited();
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps)); mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps));
@ -4228,7 +4414,7 @@ void InterCodeProcedure::RemoveUnusedInstructions(void)
} while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired2)); } while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired2));
ResetVisited(); ResetVisited();
} while (mEntryBlock->RemoveUnusedResultInstructions(numFixedTemporaries)); } while (mEntryBlock->RemoveUnusedResultInstructions());
} }
void InterCodeProcedure::Close(void) void InterCodeProcedure::Close(void)
@ -4236,7 +4422,6 @@ void InterCodeProcedure::Close(void)
int i, j, k, start; int i, j, k, start;
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
numFixedTemporaries = 0;
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];
DisassembleDebug("start"); DisassembleDebug("start");
@ -4350,7 +4535,7 @@ void InterCodeProcedure::Close(void)
do { do {
ResetVisited(); ResetVisited();
mEntryBlock->BuildLocalTempSets(numTemps, numFixedTemporaries); mEntryBlock->BuildLocalTempSets(numTemps);
ResetVisited(); ResetVisited();
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps)); mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps));
@ -4362,21 +4547,28 @@ void InterCodeProcedure::Close(void)
} while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired2)); } while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired2));
ResetVisited(); ResetVisited();
} while (mEntryBlock->RemoveUnusedResultInstructions(numFixedTemporaries)); } while (mEntryBlock->RemoveUnusedResultInstructions());
DisassembleDebug("removed unused instructions"); DisassembleDebug("removed unused instructions");
InterMemory paramMemory = mFastCallProcedure ? IM_FPARAM : IM_PARAM;
ResetVisited(); ResetVisited();
mEntryBlock->CollectVariables(mModule->mGlobalVars, mLocalVars); mEntryBlock->CollectVariables(mModule->mGlobalVars, mLocalVars, mParamVars, paramMemory);
if (mLocalVars.Size() > 0) if (mLocalVars.Size() > 0 || mParamVars.Size() > 0)
{ {
for (int i = 0; i < mLocalVars.Size(); i++) for (int i = 0; i < mLocalVars.Size(); i++)
{ {
if (mLocalAliasedSet[i]) if (mLocalAliasedSet[i])
mLocalVars[i]->mAliased = true; mLocalVars[i]->mAliased = true;
} }
for (int i = 0; i < mParamVars.Size(); i++)
{
if (mParamAliasedSet[i])
mParamVars[i]->mAliased = true;
}
// //
// Now remove unused stores // Now remove unused stores
@ -4384,19 +4576,20 @@ void InterCodeProcedure::Close(void)
do { do {
ResetVisited(); ResetVisited();
mEntryBlock->BuildLocalVariableSets(mLocalVars); mEntryBlock->BuildLocalVariableSets(mLocalVars, mParamVars, paramMemory);
ResetVisited(); ResetVisited();
mEntryBlock->BuildGlobalProvidedVariableSet(mLocalVars, NumberSet(mLocalVars.Size())); mEntryBlock->BuildGlobalProvidedVariableSet(mLocalVars, NumberSet(mLocalVars.Size()), mParamVars, NumberSet(mParamVars.Size()), paramMemory);
NumberSet totalRequired2(mLocalVars.Size()); NumberSet totalRequired2(mLocalVars.Size());
NumberSet totalRequiredParams(mParamVars.Size());
do { do {
ResetVisited(); ResetVisited();
} while (mEntryBlock->BuildGlobalRequiredVariableSet(mLocalVars, totalRequired2)); } while (mEntryBlock->BuildGlobalRequiredVariableSet(mLocalVars, totalRequired2, mParamVars, totalRequiredParams, paramMemory));
ResetVisited(); ResetVisited();
} while (mEntryBlock->RemoveUnusedStoreInstructions(mLocalVars)); } while (mEntryBlock->RemoveUnusedStoreInstructions(mLocalVars, mParamVars, paramMemory));
DisassembleDebug("removed unused local stores"); DisassembleDebug("removed unused local stores");
} }
@ -4479,8 +4672,6 @@ void InterCodeProcedure::Close(void)
// //
// And remove unused temporaries // And remove unused temporaries
// //
for (i = 0; i < numFixedTemporaries; i++)
activeSet += i;
ResetVisited(); ResetVisited();
mEntryBlock->CollectActiveTemporaries(activeSet); mEntryBlock->CollectActiveTemporaries(activeSet);
@ -4489,7 +4680,6 @@ void InterCodeProcedure::Close(void)
mTemporaries.SetSize(activeSet.Num(), true); mTemporaries.SetSize(activeSet.Num(), true);
ResetVisited(); ResetVisited();
mEntryBlock->ShrinkActiveTemporaries(activeSet, mTemporaries); mEntryBlock->ShrinkActiveTemporaries(activeSet, mTemporaries);
@ -4500,6 +4690,11 @@ void InterCodeProcedure::Close(void)
ReduceTemporaries(); ReduceTemporaries();
DisassembleDebug("Reduced Temporaries"); DisassembleDebug("Reduced Temporaries");
// Optimize for size
MergeBasicBlocks();
DisassembleDebug("Merged basic blocks");
} }
void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc) void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc)
@ -4527,6 +4722,115 @@ void InterCodeProcedure::MapVariables(void)
} }
} }
void InterCodeProcedure::MergeBasicBlocks(void)
{
ResetVisited();
mEntryBlock->FollowJumps();
ResetVisited();
mEntryBlock->SplitBranches(this);
bool changed;
do
{
changed = false;
GrowingArray<InterCodeBasicBlock* > blockMap(nullptr);
for (int i = 0; i < mBlocks.Size(); i++)
{
InterCodeBasicBlock* block = mBlocks[i];
if (block->mNumEntries)
{
int j = 0;
while (j < i && !(mBlocks[j]->mNumEntries && mBlocks[j]->IsEqual(block)))
j++;
blockMap[i] = mBlocks[j];
}
}
if (mEntryBlock != blockMap[mEntryBlock->mIndex])
{
mEntryBlock = blockMap[mEntryBlock->mIndex];
changed = true;
}
for (int i = 0; i < mBlocks.Size(); i++)
{
InterCodeBasicBlock* block = mBlocks[i];
if (block->mNumEntries)
{
if (block->mTrueJump && block->mTrueJump != blockMap[block->mTrueJump->mIndex])
{
block->mTrueJump = blockMap[block->mTrueJump->mIndex];
changed = true;
}
if (block->mFalseJump && block->mFalseJump != blockMap[block->mFalseJump->mIndex])
{
block->mFalseJump = blockMap[block->mFalseJump->mIndex];
changed = true;
}
}
}
if (changed)
{
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0;
mEntryBlock->CollectEntries();
}
for (int i = 0; i < mBlocks.Size(); i++)
{
InterCodeBasicBlock* block = mBlocks[i];
if (block->mNumEntries >= 2)
{
GrowingArray<InterCodeBasicBlock* > eblocks(nullptr);
for (int j = 0; j < mBlocks.Size(); j++)
{
InterCodeBasicBlock* eblock = mBlocks[j];
if (eblock->mNumEntries > 0 && eblock->mTrueJump == block && !eblock->mFalseJump)
eblocks.Push(eblock);
}
if (eblocks.Size() == block->mNumEntries)
{
bool ok;
do {
ok = false;
if (eblocks[0]->mInstructions.Size() > 1)
{
InterInstruction* ins = eblocks[0]->mInstructions[eblocks[0]->mInstructions.Size() - 2];
int j = 1;
while (j < eblocks.Size() && eblocks[j]->mInstructions.Size() > 1 && eblocks[j]->mInstructions[eblocks[j]->mInstructions.Size() - 2]->IsEqual(ins))
j++;
if (j == eblocks.Size())
{
block->mInstructions.Insert(0, ins);
for (int j = 0; j < eblocks.Size(); j++)
eblocks[j]->mInstructions.Remove(eblocks[j]->mInstructions.Size() - 2);
ok = true;
changed = true;
}
}
} while (ok);
}
}
}
} while (changed);
ResetVisited();
mEntryBlock->FollowJumps();
}
void InterCodeProcedure::BuildDominators(void) void InterCodeProcedure::BuildDominators(void)
{ {
ResetVisited(); ResetVisited();
@ -4559,7 +4863,7 @@ void InterCodeProcedure::ReduceTemporaries(void)
int numTemps = mTemporaries.Size(); int numTemps = mTemporaries.Size();
ResetVisited(); ResetVisited();
mEntryBlock->BuildLocalTempSets(numTemps, numFixedTemporaries); mEntryBlock->BuildLocalTempSets(numTemps);
ResetVisited(); ResetVisited();
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps)); mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps));
@ -4580,18 +4884,15 @@ void InterCodeProcedure::ReduceTemporaries(void)
mRenameTable.SetSize(numTemps, true); mRenameTable.SetSize(numTemps, true);
for (i = 0; i < numFixedTemporaries; i++) numRenamedTemps = 0;
mRenameTable[i] = i;
numRenamedTemps = numFixedTemporaries;
NumberSet usedTemps(numTemps); NumberSet usedTemps(numTemps);
for (i = numFixedTemporaries; i < numTemps; i++) for (i = 0; i < numTemps; i++)
{ {
usedTemps.Clear(); usedTemps.Clear();
for (j = numFixedTemporaries; j < numTemps; j++) for (j = 0; j < numTemps; j++)
{ {
if (mRenameTable[j] >= 0 && (collisionSet[i][j] || InterTypeSize[mTemporaries[j]] != InterTypeSize[mTemporaries[i]])) if (mRenameTable[j] >= 0 && (collisionSet[i][j] || InterTypeSize[mTemporaries[j]] != InterTypeSize[mTemporaries[i]]))
{ {
@ -4599,7 +4900,7 @@ void InterCodeProcedure::ReduceTemporaries(void)
} }
} }
j = numFixedTemporaries; j = 0;
while (usedTemps[j]) while (usedTemps[j])
j++; j++;
@ -4615,7 +4916,7 @@ void InterCodeProcedure::ReduceTemporaries(void)
delete[] collisionSet; delete[] collisionSet;
ResetVisited(); ResetVisited();
mEntryBlock->BuildLocalTempSets(numRenamedTemps, numFixedTemporaries); mEntryBlock->BuildLocalTempSets(numRenamedTemps);
ResetVisited(); ResetVisited();
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numRenamedTemps)); mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numRenamedTemps));

View File

@ -298,18 +298,9 @@ public:
LinkerObject * mLinkerObject; LinkerObject * mLinkerObject;
InterMemory mMemory; InterMemory mMemory;
InterOperand(void) InterOperand(void);
: mTemp(INVALID_TEMPORARY), mType(IT_NONE), mFinal(false), mIntConst(0), mFloatConst(0), mVarIndex(-1), mOperandSize(0), mLinkerObject(nullptr), mMemory(IM_NONE)
{} bool IsEqual(const InterOperand & op) const;
#if 0
bool Same(const InterOperand& op) const
{
if (mType != op.mType || mTemp != op.mTemp)
return false;
return true;
}
#endif
}; };
class InterInstruction class InterInstruction
@ -327,6 +318,8 @@ public:
InterInstruction(void); InterInstruction(void);
bool IsEqual(const InterInstruction* ins) const;
bool ReferencesTemp(int temp) const; bool ReferencesTemp(int temp) const;
bool UsesTemp(int temp) const; bool UsesTemp(int temp) const;
@ -335,14 +328,15 @@ public:
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable); void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable);
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams); void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
void FilterTempUsage(NumberSet& requiredVars, NumberSet& providedVars); void FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredTemps, NumberSet& providedTemps); void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory);
bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps, int numStaticTemps);
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredTemps); bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps);
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory);
void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid); void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps); void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps);
void LocalRenameRegister(GrowingIntArray& renameTable, int& num, int fixed); void LocalRenameRegister(GrowingIntArray& renameTable, int& num);
void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
void PerformTempForwarding(TempForwardingTable& forwardingTable); void PerformTempForwarding(TempForwardingTable& forwardingTable);
@ -422,6 +416,10 @@ public:
NumberSet mEntryRequiredVars, mEntryProvidedVars; NumberSet mEntryRequiredVars, mEntryProvidedVars;
NumberSet mExitRequiredVars, mExitProvidedVars; NumberSet mExitRequiredVars, mExitProvidedVars;
NumberSet mLocalRequiredParams, mLocalProvidedParams;
NumberSet mEntryRequiredParams, mEntryProvidedParams;
NumberSet mExitRequiredParams, mExitProvidedParams;
GrowingInstructionPtrArray mMergeTValues; GrowingInstructionPtrArray mMergeTValues;
ValueSet mMergeValues; ValueSet mMergeValues;
TempForwardingTable mMergeForwardingTable; TempForwardingTable mMergeForwardingTable;
@ -443,21 +441,21 @@ public:
void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps); void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps); bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
void BuildLocalTempSets(int num, int numFixed); void BuildLocalTempSets(int num);
void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps); void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps);
bool BuildGlobalRequiredTempSet(NumberSet& fromRequiredTemps); bool BuildGlobalRequiredTempSet(NumberSet& fromRequiredTemps);
bool RemoveUnusedResultInstructions(int numStaticTemps); bool RemoveUnusedResultInstructions(void);
void BuildCallerSaveTempSet(NumberSet& callerSaveTemps); void BuildCallerSaveTempSet(NumberSet& callerSaveTemps);
void BuildLocalVariableSets(const GrowingVariableArray& localVars); void BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory);
void BuildGlobalProvidedVariableSet(const GrowingVariableArray& localVars, NumberSet fromProvidedVars); void BuildGlobalProvidedVariableSet(const GrowingVariableArray& localVars, NumberSet fromProvidedVars, const GrowingVariableArray& params, NumberSet fromProvidedParams, InterMemory paramMemory);
bool BuildGlobalRequiredVariableSet(const GrowingVariableArray& localVars, NumberSet& fromRequiredVars); bool BuildGlobalRequiredVariableSet(const GrowingVariableArray& localVars, NumberSet& fromRequiredVars, const GrowingVariableArray& params, NumberSet& fromRequiredParams, InterMemory paramMemory);
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars); bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory);
GrowingIntArray mEntryRenameTable; GrowingIntArray mEntryRenameTable;
GrowingIntArray mExitRenameTable; GrowingIntArray mExitRenameTable;
void LocalRenameRegister(const GrowingIntArray& renameTable, int& num, int fixed); void LocalRenameRegister(const GrowingIntArray& renameTable, int& num);
void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable); void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable);
void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
@ -480,7 +478,7 @@ public:
void Disassemble(FILE* file, bool dumpSets); void Disassemble(FILE* file, bool dumpSets);
void CollectVariables(GrowingVariableArray & globalVars, GrowingVariableArray & localVars); void CollectVariables(GrowingVariableArray & globalVars, GrowingVariableArray & localVars, GrowingVariableArray& paramVars, InterMemory paramMemory);
void MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars); void MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars);
void CollectOuterFrame(int level, int& size, bool& inner, bool& inlineAssembler, bool& byteCodeCall); void CollectOuterFrame(int level, int& size, bool& inner, bool& inlineAssembler, bool& byteCodeCall);
@ -491,6 +489,12 @@ public:
void SingleBlockLoopOptimisation(const NumberSet& aliasedParams); void SingleBlockLoopOptimisation(const NumberSet& aliasedParams);
InterCodeBasicBlock* PropagateDominator(InterCodeProcedure * proc); InterCodeBasicBlock* PropagateDominator(InterCodeProcedure * proc);
void SplitBranches(InterCodeProcedure* proc);
void FollowJumps(void);
bool IsEqual(const InterCodeBasicBlock* block) const;
}; };
class InterCodeModule; class InterCodeModule;
@ -501,7 +505,6 @@ protected:
GrowingIntArray mRenameTable, mRenameUnionTable, mGlobalRenameTable; GrowingIntArray mRenameTable, mRenameUnionTable, mGlobalRenameTable;
TempForwardingTable mTempForwardingTable; TempForwardingTable mTempForwardingTable;
GrowingInstructionPtrArray mValueForwardingTable; GrowingInstructionPtrArray mValueForwardingTable;
int numFixedTemporaries;
NumberSet mLocalAliasedSet, mParamAliasedSet; NumberSet mLocalAliasedSet, mParamAliasedSet;
void ResetVisited(void); void ResetVisited(void);
@ -511,14 +514,14 @@ public:
GrowingTypeArray mTemporaries; GrowingTypeArray mTemporaries;
GrowingIntArray mTempOffset, mTempSizes; GrowingIntArray mTempOffset, mTempSizes;
int mTempSize, mCommonFrameSize, mCallerSavedTemps; int mTempSize, mCommonFrameSize, mCallerSavedTemps;
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode; bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure;
GrowingInterCodeProcedurePtrArray mCalledFunctions; GrowingInterCodeProcedurePtrArray mCalledFunctions;
InterCodeModule * mModule; InterCodeModule * mModule;
int mID; int mID;
int mLocalSize, mNumLocals; int mLocalSize, mNumLocals;
GrowingVariableArray mLocalVars; GrowingVariableArray mLocalVars, mParamVars;
Location mLocation; Location mLocation;
const Ident * mIdent, * mSection; const Ident * mIdent, * mSection;
@ -550,6 +553,8 @@ protected:
bool GlobalConstantPropagation(void); bool GlobalConstantPropagation(void);
void BuildDominators(void); void BuildDominators(void);
void MergeBasicBlocks(void);
void DisassembleDebug(const char* name); void DisassembleDebug(const char* name);
}; };

View File

@ -2901,6 +2901,8 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
if (dec->mBase->mFlags & DTF_FASTCALL) if (dec->mBase->mFlags & DTF_FASTCALL)
{ {
proc->mFastCallProcedure = true;
dec->mLinkerObject->mNumTemporaries = 1; dec->mLinkerObject->mNumTemporaries = 1;
dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS; dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS;
dec->mLinkerObject->mTempSizes[0] = 8; dec->mLinkerObject->mTempSizes[0] = 8;