Eliminate stores to unused function arguments

This commit is contained in:
drmortalwombat 2024-08-17 20:55:00 +02:00
parent cc576bd640
commit 122dc12d40
4 changed files with 123 additions and 3 deletions

View File

@ -5262,7 +5262,7 @@ void InterInstruction::Disassemble(FILE* file, InterCodeProcedure* proc)
{ {
if (this->mCode != IC_NONE) if (this->mCode != IC_NONE)
{ {
static char memchars[] = "NPLGFPITAZZ"; static char memchars[] = "NPLGFPITAZC";
fprintf(file, "\t"); fprintf(file, "\t");
switch (this->mCode) switch (this->mCode)
@ -9973,6 +9973,10 @@ bool InterCodeBasicBlock::BuildGlobalRequiredVariableSet(const GrowingVariableAr
return revisit; return revisit;
} }
bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory) bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory)
{ {
bool changed = false; bool changed = false;
@ -10008,6 +10012,76 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr
} }
bool InterCodeBasicBlock::RemoveUnusedArgumentStoreInstructions(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
mEntryRequiredArgs.Reset(64, true);
if (mTrueJump && mTrueJump == this)
{
if (mFalseJump)
{
if (mFalseJump->RemoveUnusedArgumentStoreInstructions())
changed = true;
mEntryRequiredArgs = mFalseJump->mEntryRequiredArgs;
}
else
mEntryRequiredArgs.Reset(64, false);
}
else if (mFalseJump && mFalseJump == this)
{
if (mTrueJump->RemoveUnusedArgumentStoreInstructions())
changed = true;
mEntryRequiredArgs = mTrueJump->mEntryRequiredArgs;
}
else
{
if (mTrueJump && mTrueJump->RemoveUnusedArgumentStoreInstructions())
changed = true;
if (mFalseJump && mFalseJump->RemoveUnusedArgumentStoreInstructions())
changed = true;
if (mTrueJump)
{
mEntryRequiredArgs = mTrueJump->mEntryRequiredArgs;
if (mFalseJump)
mEntryRequiredArgs |= mTrueJump->mEntryRequiredArgs;
}
else
mEntryRequiredArgs.Reset(64, false);
}
int i = mInstructions.Size() - 1;
while (i >= 0)
{
InterInstruction* ins(mInstructions[i]);
if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE)
{
mEntryRequiredArgs.Fill();
}
else if (ins->mCode == IC_STORE && ins->mSrc[1].mMemory == IM_FFRAME)
{
if (mEntryRequiredArgs.RangeClear(ins->mSrc[1].mVarIndex, InterTypeSize[ins->mSrc[0].mType]))
{
mInstructions.Remove(i);
changed = true;
}
else
mEntryRequiredArgs.SubRange(ins->mSrc[1].mVarIndex, InterTypeSize[ins->mSrc[0].mType]);
}
i--;
}
}
return changed;
}
bool InterCodeBasicBlock::RemoveUnusedIndirectStoreInstructions(void) bool InterCodeBasicBlock::RemoveUnusedIndirectStoreInstructions(void)
{ {
bool changed = false; bool changed = false;
@ -15237,7 +15311,7 @@ void InterCodeBasicBlock::ConstLoopOptimization(void)
const InterInstruction* ins(mInstructions[i]); const InterInstruction* ins(mInstructions[i]);
if (ins->mCode == IC_CONSTANT || ins->mCode == IC_BRANCH || if (ins->mCode == IC_CONSTANT || ins->mCode == IC_BRANCH ||
ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR) ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR || ins->mCode == IC_LEA)
{ {
int j = 0; int j = 0;
while (j < ins->mNumOperands && (ins->mSrc[j].mTemp < 0 || cset[ins->mSrc[j].mTemp])) while (j < ins->mNumOperands && (ins->mSrc[j].mTemp < 0 || cset[ins->mSrc[j].mTemp]))
@ -17450,6 +17524,21 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
} }
} }
} }
else if (ains->mCode == IC_LEA && cins->mCode == IC_RELATIONAL_OPERATOR && bins->mCode == IC_BRANCH)
{
if (ains->mSrc[1].mTemp == ains->mDst.mTemp && ains->mSrc[0].mTemp < 0 &&
(cins->mSrc[1].mTemp == ains->mDst.mTemp || cins->mSrc[0].mTemp == ains->mDst.mTemp) &&
bins->mSrc[0].mTemp == cins->mDst.mTemp && bins->mSrc[0].mFinal)
{
if (cins->mOperator == IA_CMPNE && mTrueJump == this && !tailBlock->mEntryRequiredTemps[ains->mDst.mTemp])
{
cins->mCode = IC_CONSTANT;
cins->mConst.mType = IT_BOOL;
cins->mConst.mIntConst = 0;
cins->mNumOperands = 0;
}
}
}
} }
if (!hasCall && (mProc->mCompilerOptions & COPT_OPTIMIZE_BASIC)) if (!hasCall && (mProc->mCompilerOptions & COPT_OPTIMIZE_BASIC))
@ -21793,7 +21882,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "shots_move"); CheckFunc = !strcmp(mIdent->mString, "REUArray<struct Point>::CacheNode::*CacheNode");
CheckCase = false; CheckCase = false;
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];
@ -21915,6 +22004,11 @@ void InterCodeProcedure::Close(void)
} }
} }
ResetVisited();
mEntryBlock->RemoveUnusedArgumentStoreInstructions();
DisassembleDebug("RemoveUnusedArgumentStoreInstructions");
// //
// //
// Now remove needless temporary moves, that appear due to // Now remove needless temporary moves, that appear due to
@ -22589,6 +22683,7 @@ void InterCodeProcedure::Close(void)
mEntryBlock->ForwardShortLoadStoreOffsets(); mEntryBlock->ForwardShortLoadStoreOffsets();
DisassembleDebug("ForwardShortLoadStoreOffsets"); DisassembleDebug("ForwardShortLoadStoreOffsets");
ConstLoopOptimization();
// CollapseDispatch(); // CollapseDispatch();
// DisassembleDebug("CollapseDispatch"); // DisassembleDebug("CollapseDispatch");

View File

@ -390,6 +390,8 @@ public:
NumberSet mEntryRequiredParams, mEntryProvidedParams; NumberSet mEntryRequiredParams, mEntryProvidedParams;
NumberSet mExitRequiredParams, mExitProvidedParams; NumberSet mExitRequiredParams, mExitProvidedParams;
NumberSet mEntryRequiredArgs;
GrowingInstructionArray mLoadStoreInstructions; GrowingInstructionArray mLoadStoreInstructions;
GrowingIntegerValueRangeArray mEntryValueRange, mTrueValueRange, mFalseValueRange; GrowingIntegerValueRangeArray mEntryValueRange, mTrueValueRange, mFalseValueRange;
@ -451,6 +453,8 @@ public:
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory); bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory);
bool RemoveUnusedIndirectStoreInstructions(void); bool RemoveUnusedIndirectStoreInstructions(void);
bool RemoveUnusedArgumentStoreInstructions(void);
void BuildStaticVariableSet(const GrowingVariableArray& staticVars); void BuildStaticVariableSet(const GrowingVariableArray& staticVars);
void BuildGlobalProvidedStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet fromProvidedVars); void BuildGlobalProvidedStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet fromProvidedVars);
bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars); bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars);

View File

@ -47,6 +47,26 @@ NumberSet::~NumberSet(void)
delete[] bits; delete[] bits;
} }
void NumberSet::Expand(int size, bool set)
{
if (size > this->size)
{
int ndwsize = (size + 31) >> 5;
if (dwsize != ndwsize)
{
uint32 * nbits = new uint32[ndwsize];
for (int i = 0; i < dwsize; i++)
nbits[i] = bits[i];
for (int i = dwsize; i < ndwsize; i++)
nbits[i] = 0;
delete[] bits;
dwsize = ndwsize;
bits = nbits;
}
this->size = size;
}
}
void NumberSet::Reset(int size, bool set) void NumberSet::Reset(int size, bool set)
{ {
int i; int i;

View File

@ -16,6 +16,7 @@ public:
~NumberSet(void); ~NumberSet(void);
void Reset(int size, bool set = false); void Reset(int size, bool set = false);
void Expand(int size, bool set = false);
NumberSet& operator+=(int elem); NumberSet& operator+=(int elem);
NumberSet& operator-=(int elem); NumberSet& operator-=(int elem);