Fix errors introduced with strength reduction

This commit is contained in:
drmortalwombat 2022-01-20 13:39:55 +01:00
parent 1c403dfeeb
commit 76322c005d
4 changed files with 204 additions and 191 deletions

View File

@ -4561,7 +4561,7 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
// assert(!(live & LIVE_ACCU));
int accuTemp = -1, addrTemp = -1, accuVal = 0, accuTempByte = -1;
bool accuConst = false;
bool accuConst = false, accuLong = false;
for (int i = 0; i < mIns.Size(); i++)
{
@ -5564,7 +5564,7 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
}
break;
case BC_CONST_32:
if (mIns[i].mValue == accuVal)
if (mIns[i].mValue == accuVal && accuLong)
{
mIns[i].mCode = BC_NOP;
progress = true;
@ -5585,6 +5585,7 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
accuTemp = -1;
accuTempByte = -1;
accuConst = false;
accuLong = false;
}
if (mIns[i].ChangesAddr())
addrTemp = -1;
@ -5613,6 +5614,7 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
case BC_CONST_32:
accuVal = mIns[i].mValue;
accuConst = true;
accuLong = true;
break;
case BC_CONST_8:
accuVal = mIns[i].mValue & 0xff;

View File

@ -625,6 +625,113 @@ void ValueSet::Intersect(ValueSet& set)
mNum = k;
}
TempForwardingTable::TempForwardingTable(void) : mAssoc(Assoc(-1, -1, -1))
{
}
TempForwardingTable::TempForwardingTable(const TempForwardingTable& table) : mAssoc(Assoc(-1, -1, -1))
{
for (int i = 0; i < table.mAssoc.Size(); i++)
{
mAssoc[i].mAssoc = table.mAssoc[i].mAssoc;
mAssoc[i].mSucc = table.mAssoc[i].mSucc;
mAssoc[i].mPred = table.mAssoc[i].mPred;
}
}
TempForwardingTable& TempForwardingTable::operator=(const TempForwardingTable& table)
{
mAssoc.SetSize(table.mAssoc.Size());
for (int i = 0; i < table.mAssoc.Size(); i++)
{
mAssoc[i].mAssoc = table.mAssoc[i].mAssoc;
mAssoc[i].mSucc = table.mAssoc[i].mSucc;
mAssoc[i].mPred = table.mAssoc[i].mPred;
}
return *this;
}
void TempForwardingTable::Intersect(const TempForwardingTable& table)
{
for (int i = 0; i < table.mAssoc.Size(); i++)
{
if (mAssoc[i].mAssoc != table.mAssoc[i].mAssoc)
this->Destroy(i);
}
}
void TempForwardingTable::SetSize(int size)
{
int i;
mAssoc.SetSize(size);
for (i = 0; i < size; i++)
mAssoc[i] = Assoc(i, i, i);
}
void TempForwardingTable::Reset(void)
{
int i;
for (i = 0; i < mAssoc.Size(); i++)
mAssoc[i] = Assoc(i, i, i);
}
int TempForwardingTable::operator[](int n)
{
return mAssoc[n].mAssoc;
}
void TempForwardingTable::Destroy(int n)
{
int i, j;
if (mAssoc[n].mAssoc == n)
{
i = mAssoc[n].mSucc;
while (i != n)
{
j = mAssoc[i].mSucc;
mAssoc[i] = Assoc(i, i, i);
i = j;
}
}
else
{
mAssoc[mAssoc[n].mPred].mSucc = mAssoc[n].mSucc;
mAssoc[mAssoc[n].mSucc].mPred = mAssoc[n].mPred;
}
mAssoc[n] = Assoc(n, n, n);
}
void TempForwardingTable::Build(int from, int to)
{
int i;
from = mAssoc[from].mAssoc;
to = mAssoc[to].mAssoc;
if (from != to)
{
i = mAssoc[from].mSucc;
while (i != from)
{
mAssoc[i].mAssoc = to;
i = mAssoc[i].mSucc;
}
mAssoc[from].mAssoc = to;
mAssoc[mAssoc[to].mSucc].mPred = mAssoc[from].mPred;
mAssoc[mAssoc[from].mPred].mSucc = mAssoc[to].mSucc;
mAssoc[to].mSucc = from;
mAssoc[from].mPred = to;
}
}
bool InterInstruction::ReferencesTemp(int temp) const
{
if (temp == mDst.mTemp)
@ -1710,28 +1817,6 @@ static bool TypeArithmetic(InterType t)
return t == IT_INT8 || t == IT_INT16 || t == IT_INT32 || t == IT_BOOL || t == IT_FLOAT;
}
static InterType TypeCheckArithmecitResult(InterType t1, InterType t2)
{
if (t1 == IT_FLOAT && t2 == IT_FLOAT)
return IT_FLOAT;
else if (TypeInteger(t1) && TypeInteger(t2))
return t1 > t2 ? t1 : t2;
else
throw InterCodeTypeMismatchException();
}
static void TypeCheckAssign(InterType& t, InterType s)
{
if (s == IT_NONE)
throw InterCodeUninitializedException();
else if (t == IT_NONE)
t = s;
else if (!TypeCompatible(t, s))
throw InterCodeTypeMismatchException();
}
static void FilterTempUseUsage(NumberSet& requiredTemps, NumberSet& providedTemps, int temp)
{
if (temp >= 0)
@ -2674,7 +2759,7 @@ void InterInstruction::Disassemble(FILE* file)
}
InterCodeBasicBlock::InterCodeBasicBlock(void)
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mDominator(nullptr),
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr),
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()), mEntryBlocks(nullptr)
{
mInPath = false;
@ -2729,6 +2814,47 @@ void InterCodeBasicBlock::CollectEntryBlocks(InterCodeBasicBlock* from)
}
}
void InterCodeBasicBlock::BuildDominatorTree(InterCodeBasicBlock* from)
{
if (!mDominator)
mDominator = from;
else if (from == mDominator)
return;
else
{
GrowingInterCodeBasicBlockPtrArray d1(nullptr), d2(nullptr);
InterCodeBasicBlock* b = mDominator;
while (b)
{
d1.Push(b);
b = b->mDominator;
}
b = from;
while (b)
{
d2.Push(b);
b = b->mDominator;
}
b = nullptr;
while (d1.Size() > 0 && d2.Size() > 0 && d1.Last() == d2.Last())
{
b = d1.Pop(); d2.Pop();
}
if (mDominator == b)
return;
mDominator = b;
}
if (mTrueJump)
mTrueJump->BuildDominatorTree(this);
if (mFalseJump)
mFalseJump->BuildDominatorTree(this);
}
void InterCodeBasicBlock::CollectEntries(void)
{
mNumEntries++;
@ -6278,16 +6404,16 @@ InterCodeBasicBlock* InterCodeBasicBlock::PropagateDominator(InterCodeProcedure*
if (mLoopHead)
{
mDominator = new InterCodeBasicBlock();
proc->Append(mDominator);
mLoopPrefix = new InterCodeBasicBlock();
proc->Append(mLoopPrefix);
InterInstruction * jins = new InterInstruction();
jins->mCode = IC_JUMP;
mDominator->Append(jins);
mDominator->Close(this, nullptr);
mLoopPrefix->Append(jins);
mLoopPrefix->Close(this, nullptr);
}
}
return mDominator ? mDominator : this;
return mLoopPrefix ? mLoopPrefix : this;
}
bool InterCodeBasicBlock::CollectLoopBody(InterCodeBasicBlock* head, GrowingArray<InterCodeBasicBlock*> & body)
@ -6349,7 +6475,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
for (int i = 0; i < mEntryBlocks.Size(); i++)
{
if (mEntryBlocks[i] != mDominator)
if (mEntryBlocks[i] != mLoopPrefix)
{
if (!mEntryBlocks[i]->CollectLoopBody(this, body))
innerLoop = false;
@ -6581,7 +6707,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
InterInstruction* ins = block->mInstructions[i];
if (ins->mInvariant && ins->mExpensive)
{
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins);
}
else
{
@ -6679,7 +6805,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
};
GrowingArray<Dependency> dep(DEP_UNKNOWN);
GrowingArray<int> indexStep(0), indexBase(0);
GrowingArray<int64> indexStep(0), indexBase(0);
GrowingArray<InterInstructionPtr> tvalues(nullptr);
for (int i = 0; i < mInstructions.Size(); i++)
@ -6787,7 +6913,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
InterInstruction* ins = mInstructions[i];
if (ins->mInvariant)
{
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins);
}
else if (ins->mDst.mTemp >= 0 && dep[ins->mDst.mTemp] == DEP_INDEX)
{
@ -6807,7 +6933,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
bins->mDst = ins->mDst;
bins->mSrc[0] = ins->mSrc[0];
bins->mSrc[1] = ins->mSrc[1];
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, bins);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, bins);
InterInstruction* ains = new InterInstruction();
ains->mCode = IC_BINARY_OPERATOR;
@ -6815,7 +6941,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
ains->mDst = ins->mDst;
ains->mSrc[0] = ins->mDst;
ains->mSrc[1] = ins->mSrc[1]; ains->mSrc[1].mIntConst = ins->mSrc[1].mIntConst * indexBase[ins->mSrc[0].mTemp];
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ains);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ains);
ins->mOperator = IA_ADD;
ins->mSrc[1].mIntConst = ins->mSrc[1].mIntConst * indexStep[ins->mSrc[0].mTemp];
@ -6834,7 +6960,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
bins->mDst = ins->mDst;
bins->mSrc[0] = ins->mSrc[0];
bins->mSrc[1] = ins->mSrc[1];
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, bins);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, bins);
InterInstruction* ains = new InterInstruction();
ains->mCode = IC_BINARY_OPERATOR;
@ -6842,7 +6968,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
ains->mDst = ins->mDst;
ains->mSrc[1] = ins->mDst;
ains->mSrc[0] = ins->mSrc[0]; ains->mSrc[0].mIntConst = ins->mSrc[0].mIntConst * indexBase[ins->mSrc[1].mTemp];
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ains);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ains);
ins->mOperator = IA_ADD;
ins->mSrc[0].mIntConst = ins->mSrc[0].mIntConst * indexStep[ins->mSrc[1].mTemp];
@ -6861,7 +6987,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
bins->mDst = ins->mDst;
bins->mSrc[0] = ins->mSrc[0];
bins->mSrc[1] = ins->mSrc[1];
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, bins);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, bins);
InterInstruction* ains = new InterInstruction();
ains->mCode = IC_BINARY_OPERATOR;
@ -6869,7 +6995,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
ains->mDst = ins->mDst;
ains->mSrc[1] = ins->mDst;
ains->mSrc[0] = ins->mSrc[0]; ains->mSrc[0].mIntConst = indexBase[ins->mSrc[1].mTemp] << ins->mSrc[0].mIntConst;
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ains);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ains);
ins->mOperator = IA_ADD;
ins->mSrc[0].mIntConst = indexStep[ins->mSrc[1].mTemp] << ins->mSrc[0].mIntConst;
@ -6882,7 +7008,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[1].mTemp];
indexBase[ins->mDst.mTemp] = 0;
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins);
InterInstruction* ains = new InterInstruction();
ains->mCode = IC_BINARY_OPERATOR;
@ -6900,7 +7026,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[0].mTemp];
indexBase[ins->mDst.mTemp] = 0;
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins);
InterInstruction* ains = new InterInstruction();
ains->mCode = IC_BINARY_OPERATOR;
@ -6918,7 +7044,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[0].mTemp];
indexBase[ins->mDst.mTemp] = 0;
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins);
InterInstruction* ains = new InterInstruction();
ains->mCode = IC_LEA;
@ -6938,7 +7064,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[0].mTemp];
indexBase[ins->mDst.mTemp] = indexBase[ins->mSrc[0].mTemp];
mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins);
InterInstruction* ains = new InterInstruction();
ains->mCode = ins->mCode;
@ -7454,7 +7580,7 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets)
mVisited = true;
const char* s = mLoopHead ? "Head" : "";
fprintf(file, "L%d: (%d) %s\n", mIndex, mNumEntries, s);
fprintf(file, "L%d: <= D%d: (%d) %s \n", mIndex, (mDominator ? mDominator->mIndex : -1), mNumEntries, s);
if (dumpSets)
{
@ -7560,6 +7686,11 @@ void InterCodeProcedure::BuildTraces(bool expand)
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0;
mEntryBlock->CollectEntries();
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mDominator = nullptr;
mEntryBlock->BuildDominatorTree(nullptr);
}
void InterCodeProcedure::BuildDataFlowSets(void)
@ -8164,6 +8295,17 @@ void InterCodeProcedure::Close(void)
BuildTraces(false);
#endif
#if 1
ResetVisited();
mEntryBlock->PeepholeOptimization();
TempForwarding();
RemoveUnusedInstructions();
DisassembleDebug("Peephole optimized");
#endif
MapVariables();

View File

@ -198,110 +198,22 @@ protected:
GrowingArray<Assoc> mAssoc;
public:
TempForwardingTable(void) : mAssoc(Assoc(-1, -1, -1))
{
}
TempForwardingTable(void);
TempForwardingTable(const TempForwardingTable& table);
TempForwardingTable(const TempForwardingTable & table) : mAssoc(Assoc(-1, -1, -1))
{
for (int i = 0; i < table.mAssoc.Size(); i++)
{
mAssoc[i].mAssoc = table.mAssoc[i].mAssoc;
mAssoc[i].mSucc = table.mAssoc[i].mSucc;
mAssoc[i].mPred = table.mAssoc[i].mPred;
}
}
TempForwardingTable& operator=(const TempForwardingTable& table);
TempForwardingTable& operator=(const TempForwardingTable& table)
{
mAssoc.SetSize(table.mAssoc.Size());
for (int i = 0; i < table.mAssoc.Size(); i++)
{
mAssoc[i].mAssoc = table.mAssoc[i].mAssoc;
mAssoc[i].mSucc = table.mAssoc[i].mSucc;
mAssoc[i].mPred = table.mAssoc[i].mPred;
}
void Intersect(const TempForwardingTable& table);
return *this;
}
void SetSize(int size);
void Intersect(const TempForwardingTable& table)
{
for (int i = 0; i < table.mAssoc.Size(); i++)
{
if (mAssoc[i].mAssoc != table.mAssoc[i].mAssoc)
this->Destroy(i);
}
}
void Reset(void);
void SetSize(int size)
{
int i;
mAssoc.SetSize(size);
int operator[](int n);
for (i = 0; i < size; i++)
mAssoc[i] = Assoc(i, i, i);
}
void Destroy(int n);
void Reset(void)
{
int i;
for (i = 0; i < mAssoc.Size(); i++)
mAssoc[i] = Assoc(i, i, i);
}
int operator[](int n)
{
return mAssoc[n].mAssoc;
}
void Destroy(int n)
{
int i, j;
if (mAssoc[n].mAssoc == n)
{
i = mAssoc[n].mSucc;
while (i != n)
{
j = mAssoc[i].mSucc;
mAssoc[i] = Assoc(i, i, i);
i = j;
}
}
else
{
mAssoc[mAssoc[n].mPred].mSucc = mAssoc[n].mSucc;
mAssoc[mAssoc[n].mSucc].mPred = mAssoc[n].mPred;
}
mAssoc[n] = Assoc(n, n, n);
}
void Build(int from, int to)
{
int i;
from = mAssoc[from].mAssoc;
to = mAssoc[to].mAssoc;
if (from != to)
{
i = mAssoc[from].mSucc;
while (i != from)
{
mAssoc[i].mAssoc = to;
i = mAssoc[i].mSucc;
}
mAssoc[from].mAssoc = to;
mAssoc[mAssoc[to].mSucc].mPred = mAssoc[from].mPred;
mAssoc[mAssoc[from].mPred].mSucc = mAssoc[to].mSucc;
mAssoc[to].mSucc = from;
mAssoc[from].mPred = to;
}
}
void Build(int from, int to);
};
class InterVariable
@ -400,56 +312,11 @@ public:
void Disassemble(FILE* file);
};
class InterCodeException
{
public:
InterCodeException()
{
}
};
class InterCodeStackException : public InterCodeException
{
public:
InterCodeStackException()
: InterCodeException()
{
}
};
class InterCodeUndefinedException : public InterCodeException
{
public:
InterCodeUndefinedException()
: InterCodeException()
{
}
};
class InterCodeTypeMismatchException : public InterCodeException
{
public:
InterCodeTypeMismatchException()
: InterCodeException()
{
}
};
class InterCodeUninitializedException : public InterCodeException
{
public:
InterCodeUninitializedException()
: InterCodeException()
{
}
};
class InterCodeBasicBlock
{
public:
int mIndex, mNumEntries, mNumEntered, mTraceIndex;
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mDominator;
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
GrowingInstructionArray mInstructions;
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable;
@ -487,6 +354,7 @@ public:
void CollectEntries(void);
void CollectEntryBlocks(InterCodeBasicBlock* from);
void GenerateTraces(bool expand);
void BuildDominatorTree(InterCodeBasicBlock * from);
void LocalToTemp(int vindex, int temp);

View File

@ -9495,7 +9495,7 @@ bool NativeCodeBasicBlock::PatchGlobalAdressSumYByX(int at, int reg, const Nativ
yindex = 0;
for (int i = at; i <= last; i++)
{
mIns[i].mLive | LIVE_CPU_REG_X;
mIns[i].mLive |= LIVE_CPU_REG_X;
if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE)
yindex = mIns[i].mAddress;
@ -9561,7 +9561,7 @@ bool NativeCodeBasicBlock::PatchDirectAddressSumY(int at, int reg, int apos, int
for (int i = apos; i <= last; i++)
{
mIns[i].mLive | LIVE_CPU_REG_Y;
mIns[i].mLive |= LIVE_CPU_REG_Y;
if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE)
{
@ -9842,6 +9842,7 @@ bool NativeCodeBasicBlock::MoveIndirectLoadStoreDown(int at)
{
mIns[j].mMode = ASMIM_INDIRECT_Y;
mIns[j].mAddress = mIns[at].mAddress;
mIns[j].mLive |= LIVE_MEM;
mIns[at + 0].mType = ASMIT_NOP; mIns[at + 0].mMode = ASMIM_IMPLIED;
mIns[at + 1].mType = ASMIT_NOP; mIns[at + 1].mMode = ASMIM_IMPLIED;
@ -12430,7 +12431,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
if (FindAddressSumY(i, sreg, apos, breg, ireg))
{
#if 1
if (!(breg == sreg || ireg == sreg)|| !(mIns[i + 0].mLive & LIVE_MEM))
if (!(breg == sreg || ireg == sreg) || !(mIns[i + 0].mLive & LIVE_MEM))
{
if (breg == sreg || ireg == sreg)
{