Added global constant propagation

This commit is contained in:
drmortalwombat 2021-09-13 09:26:58 +02:00
parent 8de4bef436
commit 9647cdb828
3 changed files with 126 additions and 1 deletions

View File

@ -1118,6 +1118,49 @@ static void PerformTempDefineForwarding(int temp, TempForwardingTable& forwardin
} }
} }
bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& ctemps)
{
switch (mCode)
{
case IC_LOAD:
if (mSTemp[0] >= 0 && ctemps[mSTemp[0]])
{
InterInstruction* ains = ctemps[mSTemp[0]];
mSIntConst[0] = ains->mIntValue;
mVarIndex = ains->mVarIndex;
mMemory = ains->mMemory;
mSTemp[0] = -1;
return true;
}
break;
case IC_STORE:
if (mSTemp[1] >= 0 && ctemps[mSTemp[1]])
{
InterInstruction* ains = ctemps[mSTemp[1]];
mSIntConst[1] = ains->mIntValue;
mVarIndex = ains->mVarIndex;
mMemory = ains->mMemory;
mSTemp[1] = -1;
return true;
}
break;
case IC_LOAD_TEMPORARY:
if (mSTemp[0] >= 0 && ctemps[mSTemp[0]])
{
InterInstruction* ains = ctemps[mSTemp[0]];
mCode = IC_CONSTANT;
mIntValue = ains->mIntValue;
mFloatValue = ains->mFloatValue;
mVarIndex = ains->mVarIndex;
mMemory = ains->mMemory;
mSTemp[0] = -1;
return true;
}
}
return false;
}
void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTable) void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTable)
{ {
PerformTempUseForwarding(mSTemp[0], forwardingTable); PerformTempUseForwarding(mSTemp[0], forwardingTable);
@ -2187,6 +2230,60 @@ void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTabl
} }
} }
void InterCodeBasicBlock::CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps)
{
int i;
if (!mVisited)
{
mVisited = true;
for (i = 0; i < mInstructions.Size(); i++)
{
int ttemp = mInstructions[i].mTTemp;
if (ttemp >= 0)
{
if (assignedTemps[ttemp])
ctemps[ttemp] = nullptr;
else
{
assignedTemps += ttemp;
if (mInstructions[i].mCode == IC_CONSTANT)
ctemps[ttemp] = &(mInstructions[i]);
}
}
}
if (mTrueJump) mTrueJump->CollectConstTemps(ctemps, assignedTemps);
if (mFalseJump) mFalseJump->CollectConstTemps(ctemps, assignedTemps);
}
}
bool InterCodeBasicBlock::PropagateConstTemps(const GrowingInstructionPtrArray& ctemps)
{
bool changed = false;
int i;
if (!mVisited)
{
mVisited = true;
for (i = 0; i < mInstructions.Size(); i++)
{
if (mInstructions[i].PropagateConstTemps(ctemps))
changed = true;
}
if (mTrueJump && mTrueJump->PropagateConstTemps(ctemps))
changed = true;
if (mFalseJump && mFalseJump->PropagateConstTemps(ctemps))
changed = true;
}
return changed;
}
void InterCodeBasicBlock::BuildLocalTempSets(int num, int numFixed) void InterCodeBasicBlock::BuildLocalTempSets(int num, int numFixed)
{ {
int i; int i;
@ -3472,6 +3569,8 @@ void InterCodeProcedure::Close(void)
ResetVisited(); ResetVisited();
mBlocks[0]->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet); mBlocks[0]->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet);
GlobalConstantPropagation();
DisassembleDebug("machine value forwarding"); DisassembleDebug("machine value forwarding");
// //
@ -3575,7 +3674,9 @@ void InterCodeProcedure::Close(void)
RenameTemporaries(); RenameTemporaries();
do {
TempForwarding(); TempForwarding();
} while (GlobalConstantPropagation());
// //
// Now remove unused instructions // Now remove unused instructions
@ -3635,6 +3736,20 @@ void InterCodeProcedure::MapVariables(void)
} }
} }
bool InterCodeProcedure::GlobalConstantPropagation(void)
{
NumberSet assignedTemps(mTemporaries.Size());
GrowingInstructionPtrArray ctemps(nullptr);
ResetVisited();
mBlocks[0]->CollectConstTemps(ctemps, assignedTemps);
ResetVisited();
return mBlocks[0]->PropagateConstTemps(ctemps);
}
void InterCodeProcedure::ReduceTemporaries(void) void InterCodeProcedure::ReduceTemporaries(void)
{ {
NumberSet* collisionSet; NumberSet* collisionSet;

View File

@ -293,6 +293,7 @@ public:
void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
void PerformTempForwarding(TempForwardingTable& forwardingTable); void PerformTempForwarding(TempForwardingTable& forwardingTable);
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets); void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets);
void ReduceTemporaries(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void ReduceTemporaries(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
@ -385,6 +386,9 @@ 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 CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
void BuildLocalTempSets(int num, int numFixed); void BuildLocalTempSets(int num, int numFixed);
void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps); void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps);
bool BuildGlobalRequiredTempSet(NumberSet& fromRequiredTemps); bool BuildGlobalRequiredTempSet(NumberSet& fromRequiredTemps);
@ -478,6 +482,7 @@ protected:
void RenameTemporaries(void); void RenameTemporaries(void);
void TempForwarding(void); void TempForwarding(void);
void RemoveUnusedInstructions(void); void RemoveUnusedInstructions(void);
bool GlobalConstantPropagation(void);
void DisassembleDebug(const char* name); void DisassembleDebug(const char* name);
}; };

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <assert.h>
typedef unsigned __int32 uint32; typedef unsigned __int32 uint32;
class NumberSet class NumberSet
@ -35,6 +37,7 @@ public:
__forceinline NumberSet& NumberSet::operator+=(int elem) __forceinline NumberSet& NumberSet::operator+=(int elem)
{ {
assert(elem >= 0 && elem < size);
bits[elem >> 5] |= (1UL << (elem & 31)); bits[elem >> 5] |= (1UL << (elem & 31));
return *this; return *this;
@ -42,6 +45,7 @@ __forceinline NumberSet& NumberSet::operator+=(int elem)
__forceinline NumberSet& NumberSet::operator-=(int elem) __forceinline NumberSet& NumberSet::operator-=(int elem)
{ {
assert(elem >= 0 && elem < size);
bits[elem >> 5] &= ~(1UL << (elem & 31)); bits[elem >> 5] &= ~(1UL << (elem & 31));
return *this; return *this;
@ -49,6 +53,7 @@ __forceinline NumberSet& NumberSet::operator-=(int elem)
__forceinline bool NumberSet::operator[](int elem) const __forceinline bool NumberSet::operator[](int elem) const
{ {
assert(elem >= 0 && elem < size);
return (bits[elem >> 5] & (1UL << (elem & 31))) != 0; return (bits[elem >> 5] & (1UL << (elem & 31))) != 0;
} }