Combining consecutive pointer arithmetic
This commit is contained in:
parent
71a071fea4
commit
23091a0536
|
@ -12264,22 +12264,10 @@ void InterCodeBasicBlock::CheckBlocks(void)
|
|||
}
|
||||
|
||||
|
||||
void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& staticVars)
|
||||
bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray& staticVars)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
CheckFinalLocal();
|
||||
if (mTrueJump) mTrueJump->CheckFinalLocal();
|
||||
if (mFalseJump) mFalseJump->CheckFinalLocal();
|
||||
|
||||
// Remove none instructions
|
||||
|
||||
int j = 0;
|
||||
for (i = 0; i < mInstructions.Size(); i++)
|
||||
for (int i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
if (mInstructions[i]->mCode != IC_NONE)
|
||||
{
|
||||
|
@ -12288,291 +12276,9 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
|||
}
|
||||
mInstructions.SetSize(j);
|
||||
|
||||
|
||||
// shorten lifespan
|
||||
|
||||
int loopTmp = -1;
|
||||
|
||||
int limit = mInstructions.Size() - 1;
|
||||
if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH)
|
||||
{
|
||||
limit--;
|
||||
#if 1
|
||||
// try to move conditional source down
|
||||
int i = limit;
|
||||
while (i >= 0 && mInstructions[i]->mDst.mTemp != mInstructions[limit + 1]->mSrc[0].mTemp)
|
||||
i--;
|
||||
|
||||
if (i >= 0 && i != limit)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
|
||||
if (ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR)
|
||||
{
|
||||
if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
int k = i;
|
||||
while (k < limit && CanBypass(ins, mInstructions[k + 1]))
|
||||
k++;
|
||||
|
||||
if (k == limit)
|
||||
{
|
||||
for (int l = i; l < limit; l++)
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[l + 1]);
|
||||
mInstructions[l] = mInstructions[l + 1];
|
||||
}
|
||||
mInstructions[limit] = ins;
|
||||
|
||||
// mInstructions.Remove(i);
|
||||
// mInstructions.Insert(limit, ins);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (limit > 0 && mInstructions[limit]->mCode == IC_RELATIONAL_OPERATOR)
|
||||
{
|
||||
if (mInstructions[limit]->mSrc[1].mTemp)
|
||||
loopTmp = mInstructions[limit]->mSrc[1].mTemp;
|
||||
else if (mInstructions[limit]->mSrc[0].mTemp)
|
||||
loopTmp = mInstructions[limit]->mSrc[0].mTemp;
|
||||
limit--;
|
||||
|
||||
if (loopTmp >= 0)
|
||||
{
|
||||
int i = limit;
|
||||
while (i >= 0 && !(mInstructions[i]->mCode == IC_BINARY_OPERATOR && mInstructions[i]->mDst.mTemp == loopTmp))
|
||||
i--;
|
||||
if (i >= 0 && i < limit)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
|
||||
if (limit > 0 && mInstructions[limit]->mCode == IC_BINARY_OPERATOR && (mInstructions[limit]->mDst.mTemp == loopTmp))
|
||||
limit--;
|
||||
}
|
||||
}
|
||||
else if (limit > 0 && mInstructions[limit]->mDst.mTemp == mInstructions[limit + 1]->mSrc[0].mTemp)
|
||||
limit--;
|
||||
}
|
||||
else if (limit >= 0 && mInstructions[limit]->mCode == IC_JUMP)
|
||||
limit --;
|
||||
|
||||
CheckFinalLocal();
|
||||
|
||||
int i = limit;
|
||||
#if 1
|
||||
while (i >= 0)
|
||||
{
|
||||
// move non indirect loads down
|
||||
if (mInstructions[i]->mCode == IC_LOAD && (mInstructions[i]->mSrc[0].mMemory != IM_INDIRECT || mInstructions[i]->mDst.mType != IT_INT8 || !mInstructions[i]->mSrc[0].mFinal))
|
||||
{
|
||||
InterInstruction * ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_BINARY_OPERATOR || mInstructions[i]->mCode == IC_UNARY_OPERATOR || mInstructions[i]->mCode == IC_CONVERSION_OPERATOR || mInstructions[i]->mCode == IC_CONSTANT)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
|
||||
int k = i;
|
||||
while (k < limit && CanBypass(ins, mInstructions[k + 1]))
|
||||
k++;
|
||||
if (k < limit)
|
||||
{
|
||||
while (k > i && IsChained(mInstructions[k], mInstructions[k + 1]))
|
||||
k--;
|
||||
}
|
||||
|
||||
int j = i;
|
||||
while (j < k)
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_LEA && (mInstructions[i]->mSrc[0].mTemp < 0 || mInstructions[i]->mSrc[1].mTemp < 0))
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
|
||||
i--;
|
||||
}
|
||||
|
||||
CheckFinalLocal();
|
||||
#endif
|
||||
#if 1
|
||||
// move indirect load/store pairs up
|
||||
i = 0;
|
||||
while (i + 1 < mInstructions.Size())
|
||||
{
|
||||
if (mInstructions[i + 0]->mCode == IC_LOAD && mInstructions[i + 1]->mCode == IC_STORE && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal)
|
||||
{
|
||||
if (mInstructions[i + 0]->mSrc[0].mMemory == IM_INDIRECT)
|
||||
{
|
||||
InterInstruction* lins(mInstructions[i + 0]);
|
||||
InterInstruction* sins(mInstructions[i + 1]);
|
||||
|
||||
int j = i;
|
||||
while (j > 0 &&
|
||||
CanBypassLoadUp(lins, mInstructions[j - 1]) &&
|
||||
CanBypassStore(sins, mInstructions[j - 1]))
|
||||
{
|
||||
SwapInstructions(mInstructions[j - 1], lins);
|
||||
SwapInstructions(mInstructions[j - 1], sins);
|
||||
|
||||
mInstructions[j + 1] = mInstructions[j - 1];
|
||||
j--;
|
||||
}
|
||||
|
||||
if (i != j)
|
||||
{
|
||||
mInstructions[j + 0] = lins;
|
||||
mInstructions[j + 1] = sins;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
CheckFinalLocal();
|
||||
#endif
|
||||
#if 1
|
||||
i = 0;
|
||||
while (i < mInstructions.Size())
|
||||
{
|
||||
// move stores up
|
||||
if (mInstructions[i]->mCode == IC_STORE)
|
||||
{
|
||||
InterInstruction * ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j > 0 && CanBypassStore(ins, mInstructions[j - 1]))
|
||||
{
|
||||
SwapInstructions(mInstructions[j - 1], ins);
|
||||
mInstructions[j] = mInstructions[j - 1];
|
||||
j--;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_BINARY_OPERATOR && mInstructions[i]->mSrc[0].mTemp >= 0 && mInstructions[i]->mSrc[0].mFinal && mInstructions[i]->mSrc[1].mTemp >= 0 && mInstructions[i]->mSrc[1].mFinal)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j > 0 && CanBypassUp(ins, mInstructions[j - 1]))
|
||||
{
|
||||
SwapInstructions(mInstructions[j - 1], ins);
|
||||
mInstructions[j] = mInstructions[j - 1];
|
||||
j--;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_LOAD && mInstructions[i]->mSrc[0].mMemory == IM_INDIRECT && mInstructions[i]->mSrc[0].mFinal && mInstructions[i]->mDst.mType == IT_INT8)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j > 0 && CanBypassLoadUp(ins, mInstructions[j - 1]))
|
||||
{
|
||||
SwapInstructions(mInstructions[j - 1], ins);
|
||||
mInstructions[j] = mInstructions[j - 1];
|
||||
j--;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
CheckFinalLocal();
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
i = limit;
|
||||
while (i >= 0)
|
||||
{
|
||||
// move non indirect loads down
|
||||
if (mInstructions[i]->mCode == IC_LOAD && (mInstructions[i]->mSrc[0].mMemory != IM_INDIRECT || mInstructions[i]->mDst.mType != IT_INT8 || !mInstructions[i]->mSrc[0].mFinal))
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_CONSTANT || (mInstructions[i]->mCode == IC_LEA && mInstructions[i]->mSrc[0].mTemp == -1))
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
|
||||
i--;
|
||||
}
|
||||
#endif
|
||||
|
||||
CheckFinalLocal();
|
||||
|
||||
bool changed = false;
|
||||
do
|
||||
{
|
||||
int j = 0;
|
||||
for (i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
if (mInstructions[i]->mCode != IC_NONE)
|
||||
{
|
||||
mInstructions[j++] = mInstructions[i];
|
||||
}
|
||||
}
|
||||
mInstructions.SetSize(j);
|
||||
|
||||
changed = false;
|
||||
|
||||
for (i = 0; i < mInstructions.Size(); i++)
|
||||
for (int i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
if (mInstructions[i]->mCode == IC_LOAD_TEMPORARY && mInstructions[i]->mDst.mTemp == mInstructions[i]->mSrc->mTemp)
|
||||
{
|
||||
|
@ -13065,6 +12771,51 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
|||
mInstructions[i + 1]->mCode = IC_NONE; mInstructions[i + 1]->mNumOperands = 0;
|
||||
changed = true;
|
||||
}
|
||||
else if (
|
||||
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_ADD &&
|
||||
mInstructions[i + 0]->mSrc[0].mTemp < 0 && mInstructions[i + 0]->mSrc[1].mTemp >= 0 &&
|
||||
mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 1]->mOperator == IA_ADD &&
|
||||
mInstructions[i + 1]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mTemp >= 0 &&
|
||||
mInstructions[i + 2]->mCode == IC_LEA && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal &&
|
||||
mInstructions[i + 2]->mSrc[1].mTemp < 0 &&
|
||||
mInstructions[i + 0]->mDst.mTemp != mInstructions[i + 0]->mSrc[1].mTemp)
|
||||
{
|
||||
mInstructions[i + 2]->mSrc[1].mIntConst += mInstructions[i + 0]->mSrc[0].mIntConst;
|
||||
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mSrc[1];
|
||||
mInstructions[i + 0]->mSrc[1].mFinal = false;
|
||||
mInstructions[i + 1]->mSrc[0].mFinal = false;
|
||||
changed = true;
|
||||
}
|
||||
else if (
|
||||
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_ADD &&
|
||||
mInstructions[i + 0]->mSrc[0].mTemp < 0 && mInstructions[i + 0]->mSrc[1].mTemp >= 0 &&
|
||||
|
||||
mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 1]->mOperator == IA_ADD &&
|
||||
mInstructions[i + 1]->mSrc[0].mTemp < 0 && mInstructions[i + 1]->mSrc[1].mTemp >= 0 &&
|
||||
|
||||
mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 2]->mOperator == IA_ADD &&
|
||||
mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i + 1]->mDst.mTemp &&
|
||||
mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp &&
|
||||
|
||||
// !mInstructions[i + 1]->ReferencesTemp(mInstructions[i + 0]->mDst.mTemp) &&
|
||||
(mInstructions[i + 2]->mSrc[0].mFinal || mInstructions[i + 2]->mSrc[1].mFinal))
|
||||
{
|
||||
if (mInstructions[i + 2]->mSrc[0].mFinal)
|
||||
{
|
||||
mInstructions[i + 0]->mSrc[0].mIntConst += mInstructions[i + 1]->mSrc[0].mIntConst;
|
||||
mInstructions[i + 1]->mSrc[1].mFinal = false;
|
||||
mInstructions[i + 2]->mSrc[1] = mInstructions[i + 1]->mSrc[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
mInstructions[i + 1]->mSrc[0].mIntConst += mInstructions[i + 0]->mSrc[0].mIntConst;
|
||||
mInstructions[i + 0]->mSrc[1].mFinal = false;
|
||||
mInstructions[i + 2]->mSrc[0] = mInstructions[i + 0]->mSrc[1];
|
||||
}
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
else if (
|
||||
mInstructions[i + 0]->mCode == IC_LEA && mInstructions[i + 0]->mSrc[1].mMemory == IM_GLOBAL &&
|
||||
mInstructions[i + 1]->mCode == IC_LEA && mInstructions[i + 1]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[1].mFinal &&
|
||||
|
@ -13210,7 +12961,303 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
|||
#endif
|
||||
}
|
||||
|
||||
} while (changed);
|
||||
return changed;
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& staticVars)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
CheckFinalLocal();
|
||||
if (mTrueJump) mTrueJump->CheckFinalLocal();
|
||||
if (mFalseJump) mFalseJump->CheckFinalLocal();
|
||||
|
||||
// Remove none instructions
|
||||
|
||||
int j = 0;
|
||||
for (i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
if (mInstructions[i]->mCode != IC_NONE)
|
||||
{
|
||||
mInstructions[j++] = mInstructions[i];
|
||||
}
|
||||
}
|
||||
mInstructions.SetSize(j);
|
||||
|
||||
|
||||
// shorten lifespan
|
||||
|
||||
int loopTmp = -1;
|
||||
|
||||
int limit = mInstructions.Size() - 1;
|
||||
if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH)
|
||||
{
|
||||
limit--;
|
||||
#if 1
|
||||
// try to move conditional source down
|
||||
int i = limit;
|
||||
while (i >= 0 && mInstructions[i]->mDst.mTemp != mInstructions[limit + 1]->mSrc[0].mTemp)
|
||||
i--;
|
||||
|
||||
if (i >= 0 && i != limit)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
|
||||
if (ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR)
|
||||
{
|
||||
if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
int k = i;
|
||||
while (k < limit && CanBypass(ins, mInstructions[k + 1]))
|
||||
k++;
|
||||
|
||||
if (k == limit)
|
||||
{
|
||||
for (int l = i; l < limit; l++)
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[l + 1]);
|
||||
mInstructions[l] = mInstructions[l + 1];
|
||||
}
|
||||
mInstructions[limit] = ins;
|
||||
|
||||
// mInstructions.Remove(i);
|
||||
// mInstructions.Insert(limit, ins);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (limit > 0 && mInstructions[limit]->mCode == IC_RELATIONAL_OPERATOR)
|
||||
{
|
||||
if (mInstructions[limit]->mSrc[1].mTemp)
|
||||
loopTmp = mInstructions[limit]->mSrc[1].mTemp;
|
||||
else if (mInstructions[limit]->mSrc[0].mTemp)
|
||||
loopTmp = mInstructions[limit]->mSrc[0].mTemp;
|
||||
limit--;
|
||||
|
||||
if (loopTmp >= 0)
|
||||
{
|
||||
int i = limit;
|
||||
while (i >= 0 && !(mInstructions[i]->mCode == IC_BINARY_OPERATOR && mInstructions[i]->mDst.mTemp == loopTmp))
|
||||
i--;
|
||||
if (i >= 0 && i < limit)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
|
||||
if (limit > 0 && mInstructions[limit]->mCode == IC_BINARY_OPERATOR && (mInstructions[limit]->mDst.mTemp == loopTmp))
|
||||
limit--;
|
||||
}
|
||||
}
|
||||
else if (limit > 0 && mInstructions[limit]->mDst.mTemp == mInstructions[limit + 1]->mSrc[0].mTemp)
|
||||
limit--;
|
||||
}
|
||||
else if (limit >= 0 && mInstructions[limit]->mCode == IC_JUMP)
|
||||
limit --;
|
||||
|
||||
CheckFinalLocal();
|
||||
|
||||
int i = limit;
|
||||
#if 1
|
||||
while (i >= 0)
|
||||
{
|
||||
// move non indirect loads down
|
||||
if (mInstructions[i]->mCode == IC_LOAD && (mInstructions[i]->mSrc[0].mMemory != IM_INDIRECT || mInstructions[i]->mDst.mType != IT_INT8 || !mInstructions[i]->mSrc[0].mFinal))
|
||||
{
|
||||
InterInstruction * ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_BINARY_OPERATOR || mInstructions[i]->mCode == IC_UNARY_OPERATOR || mInstructions[i]->mCode == IC_CONVERSION_OPERATOR || mInstructions[i]->mCode == IC_CONSTANT)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
|
||||
int k = i;
|
||||
while (k < limit && CanBypass(ins, mInstructions[k + 1]))
|
||||
k++;
|
||||
if (k < limit)
|
||||
{
|
||||
while (k > i && IsChained(mInstructions[k], mInstructions[k + 1]))
|
||||
k--;
|
||||
}
|
||||
|
||||
int j = i;
|
||||
while (j < k)
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_LEA && (mInstructions[i]->mSrc[0].mTemp < 0 || mInstructions[i]->mSrc[1].mTemp < 0))
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
|
||||
i--;
|
||||
}
|
||||
|
||||
CheckFinalLocal();
|
||||
#endif
|
||||
#if 1
|
||||
// move indirect load/store pairs up
|
||||
i = 0;
|
||||
while (i + 1 < mInstructions.Size())
|
||||
{
|
||||
if (mInstructions[i + 0]->mCode == IC_LOAD && mInstructions[i + 1]->mCode == IC_STORE && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal)
|
||||
{
|
||||
if (mInstructions[i + 0]->mSrc[0].mMemory == IM_INDIRECT)
|
||||
{
|
||||
InterInstruction* lins(mInstructions[i + 0]);
|
||||
InterInstruction* sins(mInstructions[i + 1]);
|
||||
|
||||
int j = i;
|
||||
while (j > 0 &&
|
||||
CanBypassLoadUp(lins, mInstructions[j - 1]) &&
|
||||
CanBypassStore(sins, mInstructions[j - 1]))
|
||||
{
|
||||
SwapInstructions(mInstructions[j - 1], lins);
|
||||
SwapInstructions(mInstructions[j - 1], sins);
|
||||
|
||||
mInstructions[j + 1] = mInstructions[j - 1];
|
||||
j--;
|
||||
}
|
||||
|
||||
if (i != j)
|
||||
{
|
||||
mInstructions[j + 0] = lins;
|
||||
mInstructions[j + 1] = sins;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
CheckFinalLocal();
|
||||
#endif
|
||||
#if 1
|
||||
i = 0;
|
||||
while (i < mInstructions.Size())
|
||||
{
|
||||
// move stores up
|
||||
if (mInstructions[i]->mCode == IC_STORE)
|
||||
{
|
||||
InterInstruction * ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j > 0 && CanBypassStore(ins, mInstructions[j - 1]))
|
||||
{
|
||||
SwapInstructions(mInstructions[j - 1], ins);
|
||||
mInstructions[j] = mInstructions[j - 1];
|
||||
j--;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_BINARY_OPERATOR && mInstructions[i]->mSrc[0].mTemp >= 0 && mInstructions[i]->mSrc[0].mFinal && mInstructions[i]->mSrc[1].mTemp >= 0 && mInstructions[i]->mSrc[1].mFinal)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j > 0 && CanBypassUp(ins, mInstructions[j - 1]))
|
||||
{
|
||||
SwapInstructions(mInstructions[j - 1], ins);
|
||||
mInstructions[j] = mInstructions[j - 1];
|
||||
j--;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_LOAD && mInstructions[i]->mSrc[0].mMemory == IM_INDIRECT && mInstructions[i]->mSrc[0].mFinal && mInstructions[i]->mDst.mType == IT_INT8)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j > 0 && CanBypassLoadUp(ins, mInstructions[j - 1]))
|
||||
{
|
||||
SwapInstructions(mInstructions[j - 1], ins);
|
||||
mInstructions[j] = mInstructions[j - 1];
|
||||
j--;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
CheckFinalLocal();
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
i = limit;
|
||||
while (i >= 0)
|
||||
{
|
||||
// move non indirect loads down
|
||||
if (mInstructions[i]->mCode == IC_LOAD && (mInstructions[i]->mSrc[0].mMemory != IM_INDIRECT || mInstructions[i]->mDst.mType != IT_INT8 || !mInstructions[i]->mSrc[0].mFinal))
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypassLoad(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
else if (mInstructions[i]->mCode == IC_CONSTANT || (mInstructions[i]->mCode == IC_LEA && mInstructions[i]->mSrc[0].mTemp == -1))
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
int j = i;
|
||||
while (j < limit && CanBypass(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
|
||||
i--;
|
||||
}
|
||||
#endif
|
||||
|
||||
CheckFinalLocal();
|
||||
|
||||
do {} while (PeepholeReplaceOptimization(staticVars));
|
||||
|
||||
// build trains
|
||||
#if 1
|
||||
|
@ -13256,6 +13303,8 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
|||
|
||||
// sort stores up
|
||||
|
||||
bool changed;
|
||||
|
||||
do
|
||||
{
|
||||
changed = false;
|
||||
|
@ -13330,6 +13379,10 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
|||
|
||||
CheckFinalLocal();
|
||||
|
||||
do {} while (PeepholeReplaceOptimization(staticVars));
|
||||
|
||||
CheckFinalLocal();
|
||||
|
||||
if (mTrueJump) mTrueJump->PeepholeOptimization(staticVars);
|
||||
if (mFalseJump) mFalseJump->PeepholeOptimization(staticVars);
|
||||
}
|
||||
|
|
|
@ -499,6 +499,8 @@ public:
|
|||
void CheckBlocks(void);
|
||||
|
||||
void PeepholeOptimization(const GrowingVariableArray& staticVars);
|
||||
bool PeepholeReplaceOptimization(const GrowingVariableArray& staticVars);
|
||||
|
||||
void SingleBlockLoopOptimisation(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
|
||||
void SingleBlockLoopUnrolling(void);
|
||||
bool SingleBlockLoopPointerSplit(int& spareTemps);
|
||||
|
|
Loading…
Reference in New Issue