Instructions bypassing small if branches
This commit is contained in:
parent
c24cf916db
commit
7bd3622bbd
|
@ -806,6 +806,262 @@ void ValueSet::InsertValue(InterInstruction * ins)
|
||||||
mInstructions[mNum++] = ins;
|
mInstructions[mNum++] = ins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool CanBypassLoad(const InterInstruction* lins, const InterInstruction* bins)
|
||||||
|
{
|
||||||
|
// Check ambiguity
|
||||||
|
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Side effects
|
||||||
|
if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// True data dependency
|
||||||
|
if (bins->UsesTemp(lins->mDst.mTemp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (bins->mCode == IC_STORE)
|
||||||
|
{
|
||||||
|
if (lins->mVolatile)
|
||||||
|
return false;
|
||||||
|
else if (lins->mSrc[0].mTemp >= 0 || bins->mSrc[1].mTemp >= 0)
|
||||||
|
return false;
|
||||||
|
else if (lins->mSrc[0].mMemory != bins->mSrc[1].mMemory)
|
||||||
|
return true;
|
||||||
|
else if (lins->mSrc[0].mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
return lins->mSrc[0].mLinkerObject != bins->mSrc[1].mLinkerObject ||
|
||||||
|
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
||||||
|
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
||||||
|
}
|
||||||
|
else if (lins->mSrc[0].mMemory == IM_ABSOLUTE)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
||||||
|
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
||||||
|
}
|
||||||
|
else if (lins->mSrc[0].mMemory == IM_LOCAL)
|
||||||
|
{
|
||||||
|
return lins->mSrc[0].mVarIndex != bins->mSrc[1].mVarIndex ||
|
||||||
|
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
||||||
|
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// False data dependency
|
||||||
|
if (lins->mSrc[0].mTemp >= 0 && lins->mSrc[0].mTemp == bins->mDst.mTemp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CanBypass(const InterInstruction* lins, const InterInstruction* bins)
|
||||||
|
{
|
||||||
|
if (lins->mDst.mTemp >= 0)
|
||||||
|
{
|
||||||
|
if (lins->mDst.mTemp == bins->mDst.mTemp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < bins->mNumOperands; i++)
|
||||||
|
if (lins->mDst.mTemp == bins->mSrc[i].mTemp)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bins->mDst.mTemp >= 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < lins->mNumOperands; i++)
|
||||||
|
if (bins->mDst.mTemp == lins->mSrc[i].mTemp)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME)
|
||||||
|
{
|
||||||
|
if (lins->mCode == IC_CONSTANT && lins->mDst.mType == IT_POINTER && lins->mConst.mMemory == IM_FRAME)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bins)
|
||||||
|
{
|
||||||
|
if (lins->mDst.mTemp >= 0)
|
||||||
|
{
|
||||||
|
if (lins->mDst.mTemp == bins->mDst.mTemp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < bins->mNumOperands; i++)
|
||||||
|
if (lins->mDst.mTemp == bins->mSrc[i].mTemp)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bins->mDst.mTemp >= 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < lins->mNumOperands; i++)
|
||||||
|
if (bins->mDst.mTemp == lins->mSrc[i].mTemp)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME)
|
||||||
|
{
|
||||||
|
if (lins->mCode == IC_CONSTANT && lins->mDst.mType == IT_POINTER && lins->mConst.mMemory == IM_FRAME)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CanBypassLoadUp(const InterInstruction* lins, const InterInstruction* bins)
|
||||||
|
{
|
||||||
|
// Check ambiguity
|
||||||
|
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Side effects
|
||||||
|
if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// False data dependency
|
||||||
|
if (bins->UsesTemp(lins->mDst.mTemp) || bins->mDst.mTemp == lins->mDst.mTemp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// True data dependency
|
||||||
|
if (lins->mSrc[0].mTemp >= 0 && lins->mSrc[0].mTemp == bins->mDst.mTemp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (bins->mCode == IC_STORE)
|
||||||
|
{
|
||||||
|
if (lins->mVolatile)
|
||||||
|
return false;
|
||||||
|
else if (lins->mSrc[0].mTemp >= 0 || bins->mSrc[1].mTemp >= 0)
|
||||||
|
return false;
|
||||||
|
else if (lins->mSrc[0].mMemory != bins->mSrc[1].mMemory)
|
||||||
|
return true;
|
||||||
|
else if (lins->mSrc[0].mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
return lins->mSrc[0].mLinkerObject != bins->mSrc[1].mLinkerObject ||
|
||||||
|
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
||||||
|
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
||||||
|
}
|
||||||
|
else if (lins->mSrc[0].mMemory == IM_ABSOLUTE)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
||||||
|
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
||||||
|
}
|
||||||
|
else if (lins->mSrc[0].mMemory == IM_LOCAL)
|
||||||
|
{
|
||||||
|
return lins->mSrc[0].mVarIndex != bins->mSrc[1].mVarIndex ||
|
||||||
|
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
||||||
|
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool IsChained(const InterInstruction* ins, const InterInstruction* nins)
|
||||||
|
{
|
||||||
|
if (ins->mDst.mTemp >= 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nins->mNumOperands; i++)
|
||||||
|
if (ins->mDst.mTemp == nins->mSrc[i].mTemp)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CanBypassStore(const InterInstruction* sins, const InterInstruction* bins)
|
||||||
|
{
|
||||||
|
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_PUSH_FRAME)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
InterMemory sm = IM_NONE, bm = IM_NONE;
|
||||||
|
int bi = -1, si = -1, bt = -1, st = -1, bo = 0, so = 0, bz = 1, sz = 1;
|
||||||
|
if (sins->mCode == IC_LOAD)
|
||||||
|
{
|
||||||
|
sm = sins->mSrc[0].mMemory;
|
||||||
|
si = sins->mSrc[0].mVarIndex;
|
||||||
|
st = sins->mSrc[0].mTemp;
|
||||||
|
so = sins->mSrc[0].mIntConst;
|
||||||
|
sz = InterTypeSize[sins->mDst.mType];
|
||||||
|
}
|
||||||
|
else if (sins->mCode == IC_LEA || sins->mCode == IC_STORE)
|
||||||
|
{
|
||||||
|
sm = sins->mSrc[1].mMemory;
|
||||||
|
si = sins->mSrc[1].mVarIndex;
|
||||||
|
st = sins->mSrc[1].mTemp;
|
||||||
|
so = sins->mSrc[1].mIntConst;
|
||||||
|
sz = InterTypeSize[sins->mSrc[0].mType];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bins->mCode == IC_LOAD)
|
||||||
|
{
|
||||||
|
bm = bins->mSrc[0].mMemory;
|
||||||
|
bi = bins->mSrc[0].mVarIndex;
|
||||||
|
bt = sins->mSrc[0].mTemp;
|
||||||
|
bo = sins->mSrc[0].mIntConst;
|
||||||
|
bz = InterTypeSize[sins->mDst.mType];
|
||||||
|
}
|
||||||
|
else if (bins->mCode == IC_LEA || bins->mCode == IC_STORE)
|
||||||
|
{
|
||||||
|
bm = bins->mSrc[1].mMemory;
|
||||||
|
bi = bins->mSrc[1].mVarIndex;
|
||||||
|
bt = sins->mSrc[1].mTemp;
|
||||||
|
bo = sins->mSrc[1].mIntConst;
|
||||||
|
bz = InterTypeSize[sins->mSrc[0].mType];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check ambiguity
|
||||||
|
if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD)
|
||||||
|
{
|
||||||
|
if (sm == IM_LOCAL)
|
||||||
|
{
|
||||||
|
if (bm == IM_PARAM || bm == IM_GLOBAL || bm == IM_FPARAM)
|
||||||
|
;
|
||||||
|
else if (bm == IM_LOCAL)
|
||||||
|
{
|
||||||
|
if (bi == si)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (sm == IM_FRAME || sm == IM_FFRAME)
|
||||||
|
;
|
||||||
|
else if (sm == IM_FPARAM)
|
||||||
|
{
|
||||||
|
if (bi == si)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (sm == IM_INDIRECT && bm == IM_INDIRECT && st == bt)
|
||||||
|
{
|
||||||
|
return so + sz <= bz || bo + bz <= so;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sm == IM_FRAME && (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Side effects
|
||||||
|
if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// True data dependency
|
||||||
|
if (bins->mDst.mTemp >= 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < sins->mNumOperands; i++)
|
||||||
|
if (bins->mDst.mTemp == sins->mSrc[i].mTemp)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
|
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
|
||||||
{
|
{
|
||||||
InterMemory lmem, smem;
|
InterMemory lmem, smem;
|
||||||
|
@ -3902,6 +4158,35 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
|
||||||
ins->mSrc[1].mTemp = pins->mSrc[1].mTemp;
|
ins->mSrc[1].mTemp = pins->mSrc[1].mTemp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ins->mOperator == IA_SUB && pins->mOperator == IA_SUB)
|
||||||
|
{
|
||||||
|
if (pins->mSrc[0].mTemp < 0)
|
||||||
|
{
|
||||||
|
ins->mSrc[0].mIntConst = ConstantFolding(IA_ADD, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst);
|
||||||
|
ins->mSrc[1].mTemp = pins->mSrc[1].mTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ins->mOperator == IA_ADD && pins->mOperator == IA_SUB)
|
||||||
|
{
|
||||||
|
if (pins->mSrc[0].mTemp < 0)
|
||||||
|
{
|
||||||
|
ins->mSrc[0].mIntConst = ConstantFolding(IA_SUB, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst);
|
||||||
|
ins->mSrc[1].mTemp = pins->mSrc[1].mTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ins->mOperator == IA_SUB && pins->mOperator == IA_ADD)
|
||||||
|
{
|
||||||
|
if (pins->mSrc[1].mTemp < 0)
|
||||||
|
{
|
||||||
|
ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[1].mIntConst);
|
||||||
|
ins->mSrc[1].mTemp = pins->mSrc[0].mTemp;
|
||||||
|
}
|
||||||
|
else if (pins->mSrc[0].mTemp < 0)
|
||||||
|
{
|
||||||
|
ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst);
|
||||||
|
ins->mSrc[1].mTemp = pins->mSrc[1].mTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (ins->mOperator == IA_SHL && (pins->mOperator == IA_SHR || pins->mOperator == IA_SAR) && pins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst == pins->mSrc[0].mIntConst)
|
else if (ins->mOperator == IA_SHL && (pins->mOperator == IA_SHR || pins->mOperator == IA_SAR) && pins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst == pins->mSrc[0].mIntConst)
|
||||||
{
|
{
|
||||||
ins->mOperator = IA_AND;
|
ins->mOperator = IA_AND;
|
||||||
|
@ -4111,11 +4396,14 @@ void InterCodeBasicBlock::CollectLocalUsedTemps(int numTemps)
|
||||||
mVisited = true;
|
mVisited = true;
|
||||||
|
|
||||||
mLocalUsedTemps.Reset(numTemps);
|
mLocalUsedTemps.Reset(numTemps);
|
||||||
|
mLocalModifiedTemps.Reset(numTemps);
|
||||||
|
|
||||||
for (int i = 0; i < mInstructions.Size(); i++)
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
{
|
{
|
||||||
InterInstruction* ins(mInstructions[i]);
|
InterInstruction* ins(mInstructions[i]);
|
||||||
|
|
||||||
|
if (ins->mDst.mTemp >= 0)
|
||||||
|
mLocalModifiedTemps += ins->mDst.mTemp;
|
||||||
for (int j = 0; j < ins->mNumOperands; j++)
|
for (int j = 0; j < ins->mNumOperands; j++)
|
||||||
{
|
{
|
||||||
if (ins->mSrc[j].mTemp >= 0)
|
if (ins->mSrc[j].mTemp >= 0)
|
||||||
|
@ -6774,9 +7062,19 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
|
||||||
|
|
||||||
if (mTrueJump && mFalseJump)
|
if (mTrueJump && mFalseJump)
|
||||||
{
|
{
|
||||||
|
InterCodeBasicBlock* joinedBlock = nullptr;
|
||||||
|
|
||||||
|
|
||||||
NumberSet trueExitRequiredTemps(mTrueJump->mEntryRequiredTemps), falseExitRequiredTems(mFalseJump->mEntryRequiredTemps);
|
NumberSet trueExitRequiredTemps(mTrueJump->mEntryRequiredTemps), falseExitRequiredTems(mFalseJump->mEntryRequiredTemps);
|
||||||
NumberSet providedTemps(mExitRequiredTemps.Size()), requiredTemps(mExitRequiredTemps.Size());
|
NumberSet providedTemps(mExitRequiredTemps.Size()), requiredTemps(mExitRequiredTemps.Size());
|
||||||
|
|
||||||
|
if (mTrueJump->mTrueJump && mFalseJump->mTrueJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump &&
|
||||||
|
mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1 &&
|
||||||
|
mTrueJump->mTrueJump == mFalseJump->mTrueJump && mTrueJump->mTrueJump->mNumEntries == 2)
|
||||||
|
{
|
||||||
|
joinedBlock = mTrueJump->mTrueJump;
|
||||||
|
}
|
||||||
|
|
||||||
bool hadStore = false;
|
bool hadStore = false;
|
||||||
|
|
||||||
int i = mInstructions.Size();
|
int i = mInstructions.Size();
|
||||||
|
@ -6785,9 +7083,10 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
|
||||||
i--;
|
i--;
|
||||||
InterInstruction* ins(mInstructions[i]);
|
InterInstruction* ins(mInstructions[i]);
|
||||||
|
|
||||||
|
int dtemp = ins->mDst.mTemp;
|
||||||
bool moved = false;
|
bool moved = false;
|
||||||
|
|
||||||
if (ins->mDst.mTemp >= 0 && !providedTemps[ins->mDst.mTemp] && !requiredTemps[ins->mDst.mTemp])
|
if (dtemp >= 0 && !providedTemps[dtemp] && !requiredTemps[dtemp])
|
||||||
{
|
{
|
||||||
int j = 0;
|
int j = 0;
|
||||||
while (j < ins->mNumOperands && (ins->mSrc[j].mTemp < 0 || !(providedTemps[ins->mSrc[j].mTemp] || IsTempModifiedOnPath(ins->mSrc[j].mTemp, i + 1))))
|
while (j < ins->mNumOperands && (ins->mSrc[j].mTemp < 0 || !(providedTemps[ins->mSrc[j].mTemp] || IsTempModifiedOnPath(ins->mSrc[j].mTemp, i + 1))))
|
||||||
|
@ -6795,7 +7094,7 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
|
||||||
|
|
||||||
if (j == ins->mNumOperands && IsMoveable(ins->mCode) && (ins->mCode != IC_LOAD || !hadStore))
|
if (j == ins->mNumOperands && IsMoveable(ins->mCode) && (ins->mCode != IC_LOAD || !hadStore))
|
||||||
{
|
{
|
||||||
if (mTrueJump->mNumEntries == 1 && trueExitRequiredTemps[ins->mDst.mTemp] && !falseExitRequiredTems[ins->mDst.mTemp])
|
if (mTrueJump->mNumEntries == 1 && trueExitRequiredTemps[dtemp] && !falseExitRequiredTems[dtemp])
|
||||||
{
|
{
|
||||||
for (int j = 0; j < ins->mNumOperands; j++)
|
for (int j = 0; j < ins->mNumOperands; j++)
|
||||||
{
|
{
|
||||||
|
@ -6807,7 +7106,7 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
|
||||||
moved = true;
|
moved = true;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
else if (mFalseJump->mNumEntries == 1 && !trueExitRequiredTemps[ins->mDst.mTemp] && falseExitRequiredTems[ins->mDst.mTemp])
|
else if (mFalseJump->mNumEntries == 1 && !trueExitRequiredTemps[dtemp] && falseExitRequiredTems[dtemp])
|
||||||
{
|
{
|
||||||
for (int j = 0; j < ins->mNumOperands; j++)
|
for (int j = 0; j < ins->mNumOperands; j++)
|
||||||
{
|
{
|
||||||
|
@ -6819,6 +7118,53 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
|
||||||
moved = true;
|
moved = true;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
else if (joinedBlock && !HasSideEffect(ins->mCode) &&
|
||||||
|
!mFalseJump->mLocalUsedTemps[dtemp] && !mFalseJump->mLocalModifiedTemps[dtemp] &&
|
||||||
|
!mTrueJump->mLocalUsedTemps[dtemp] && !mTrueJump->mLocalModifiedTemps[dtemp])
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
while (j < ins->mNumOperands && !(ins->mSrc[j].mTemp >= 0 && (mFalseJump->mLocalModifiedTemps[dtemp] || mTrueJump->mLocalModifiedTemps[dtemp])))
|
||||||
|
j++;
|
||||||
|
|
||||||
|
if (j == ins->mNumOperands)
|
||||||
|
{
|
||||||
|
if (ins->mCode == IC_LOAD)
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
while (j < mTrueJump->mInstructions.Size() && CanBypassLoad(ins, mTrueJump->mInstructions[j]))
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if (ins->mCode != IC_LOAD || j == mTrueJump->mInstructions.Size())
|
||||||
|
{
|
||||||
|
if (ins->mCode == IC_LOAD)
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
while (j < mFalseJump->mInstructions.Size() && CanBypassLoad(ins, mFalseJump->mInstructions[j]))
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ins->mCode != IC_LOAD || j == mFalseJump->mInstructions.Size())
|
||||||
|
{
|
||||||
|
for (int j = 0; j < ins->mNumOperands; j++)
|
||||||
|
{
|
||||||
|
if (ins->mSrc[j].mTemp >= 0)
|
||||||
|
{
|
||||||
|
trueExitRequiredTemps += ins->mSrc[j].mTemp;
|
||||||
|
falseExitRequiredTems += ins->mSrc[j].mTemp;
|
||||||
|
joinedBlock->mEntryRequiredTemps += ins->mSrc[j].mTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joinedBlock->mInstructions.Insert(0, ins);
|
||||||
|
mInstructions.Remove(i);
|
||||||
|
moved = true;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
providedTemps += ins->mDst.mTemp;
|
providedTemps += ins->mDst.mTemp;
|
||||||
|
@ -6939,261 +7285,6 @@ bool InterCodeBasicBlock::IsLeafProcedure(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CanBypassLoad(const InterInstruction * lins, const InterInstruction * bins)
|
|
||||||
{
|
|
||||||
// Check ambiguity
|
|
||||||
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Side effects
|
|
||||||
if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// True data dependency
|
|
||||||
if (bins->UsesTemp(lins->mDst.mTemp))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (bins->mCode == IC_STORE)
|
|
||||||
{
|
|
||||||
if (lins->mVolatile)
|
|
||||||
return false;
|
|
||||||
else if (lins->mSrc[0].mTemp >= 0 || bins->mSrc[1].mTemp >= 0)
|
|
||||||
return false;
|
|
||||||
else if (lins->mSrc[0].mMemory != bins->mSrc[1].mMemory)
|
|
||||||
return true;
|
|
||||||
else if (lins->mSrc[0].mMemory == IM_GLOBAL)
|
|
||||||
{
|
|
||||||
return lins->mSrc[0].mLinkerObject != bins->mSrc[1].mLinkerObject ||
|
|
||||||
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
|
||||||
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
|
||||||
}
|
|
||||||
else if (lins->mSrc[0].mMemory == IM_ABSOLUTE)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
|
||||||
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
|
||||||
}
|
|
||||||
else if (lins->mSrc[0].mMemory == IM_LOCAL)
|
|
||||||
{
|
|
||||||
return lins->mSrc[0].mVarIndex != bins->mSrc[1].mVarIndex ||
|
|
||||||
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
|
||||||
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// False data dependency
|
|
||||||
if (lins->mSrc[0].mTemp >= 0 && lins->mSrc[0].mTemp == bins->mDst.mTemp)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CanBypass(const InterInstruction* lins, const InterInstruction* bins)
|
|
||||||
{
|
|
||||||
if (lins->mDst.mTemp >= 0)
|
|
||||||
{
|
|
||||||
if (lins->mDst.mTemp == bins->mDst.mTemp)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int i = 0; i < bins->mNumOperands; i++)
|
|
||||||
if (lins->mDst.mTemp == bins->mSrc[i].mTemp)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bins->mDst.mTemp >= 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < lins->mNumOperands; i++)
|
|
||||||
if (bins->mDst.mTemp == lins->mSrc[i].mTemp)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME)
|
|
||||||
{
|
|
||||||
if (lins->mCode == IC_CONSTANT && lins->mDst.mType == IT_POINTER && lins->mConst.mMemory == IM_FRAME)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bins)
|
|
||||||
{
|
|
||||||
if (lins->mDst.mTemp >= 0)
|
|
||||||
{
|
|
||||||
if (lins->mDst.mTemp == bins->mDst.mTemp)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int i = 0; i < bins->mNumOperands; i++)
|
|
||||||
if (lins->mDst.mTemp == bins->mSrc[i].mTemp)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bins->mDst.mTemp >= 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < lins->mNumOperands; i++)
|
|
||||||
if (bins->mDst.mTemp == lins->mSrc[i].mTemp)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME)
|
|
||||||
{
|
|
||||||
if (lins->mCode == IC_CONSTANT && lins->mDst.mType == IT_POINTER && lins->mConst.mMemory == IM_FRAME)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CanBypassLoadUp(const InterInstruction* lins, const InterInstruction* bins)
|
|
||||||
{
|
|
||||||
// Check ambiguity
|
|
||||||
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Side effects
|
|
||||||
if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// False data dependency
|
|
||||||
if (bins->UsesTemp(lins->mDst.mTemp) || bins->mDst.mTemp == lins->mDst.mTemp)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// True data dependency
|
|
||||||
if (lins->mSrc[0].mTemp >= 0 && lins->mSrc[0].mTemp == bins->mDst.mTemp)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (bins->mCode == IC_STORE)
|
|
||||||
{
|
|
||||||
if (lins->mVolatile)
|
|
||||||
return false;
|
|
||||||
else if (lins->mSrc[0].mTemp >= 0 || bins->mSrc[1].mTemp >= 0)
|
|
||||||
return false;
|
|
||||||
else if (lins->mSrc[0].mMemory != bins->mSrc[1].mMemory)
|
|
||||||
return true;
|
|
||||||
else if (lins->mSrc[0].mMemory == IM_GLOBAL)
|
|
||||||
{
|
|
||||||
return lins->mSrc[0].mLinkerObject != bins->mSrc[1].mLinkerObject ||
|
|
||||||
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
|
||||||
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
|
||||||
}
|
|
||||||
else if (lins->mSrc[0].mMemory == IM_ABSOLUTE)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
|
||||||
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
|
||||||
}
|
|
||||||
else if (lins->mSrc[0].mMemory == IM_LOCAL)
|
|
||||||
{
|
|
||||||
return lins->mSrc[0].mVarIndex != bins->mSrc[1].mVarIndex ||
|
|
||||||
lins->mSrc[0].mIntConst + lins->mSrc[0].mOperandSize <= bins->mSrc[1].mIntConst ||
|
|
||||||
lins->mSrc[0].mIntConst >= bins->mSrc[1].mIntConst + bins->mSrc[1].mOperandSize;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool IsChained(const InterInstruction* ins, const InterInstruction* nins)
|
|
||||||
{
|
|
||||||
if (ins->mDst.mTemp >= 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < nins->mNumOperands; i++)
|
|
||||||
if (ins->mDst.mTemp == nins->mSrc[i].mTemp)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CanBypassStore(const InterInstruction * sins, const InterInstruction * bins)
|
|
||||||
{
|
|
||||||
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_PUSH_FRAME)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
InterMemory sm = IM_NONE, bm = IM_NONE;
|
|
||||||
int bi = -1, si = -1, bt = -1, st = -1, bo = 0, so = 0, bz = 1, sz = 1;
|
|
||||||
if (sins->mCode == IC_LOAD)
|
|
||||||
{
|
|
||||||
sm = sins->mSrc[0].mMemory;
|
|
||||||
si = sins->mSrc[0].mVarIndex;
|
|
||||||
st = sins->mSrc[0].mTemp;
|
|
||||||
so = sins->mSrc[0].mIntConst;
|
|
||||||
sz = InterTypeSize[sins->mDst.mType];
|
|
||||||
}
|
|
||||||
else if (sins->mCode == IC_LEA || sins->mCode == IC_STORE)
|
|
||||||
{
|
|
||||||
sm = sins->mSrc[1].mMemory;
|
|
||||||
si = sins->mSrc[1].mVarIndex;
|
|
||||||
st = sins->mSrc[1].mTemp;
|
|
||||||
so = sins->mSrc[1].mIntConst;
|
|
||||||
sz = InterTypeSize[sins->mSrc[0].mType];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bins->mCode == IC_LOAD)
|
|
||||||
{
|
|
||||||
bm = bins->mSrc[0].mMemory;
|
|
||||||
bi = bins->mSrc[0].mVarIndex;
|
|
||||||
bt = sins->mSrc[0].mTemp;
|
|
||||||
bo = sins->mSrc[0].mIntConst;
|
|
||||||
bz = InterTypeSize[sins->mDst.mType];
|
|
||||||
}
|
|
||||||
else if (bins->mCode == IC_LEA || bins->mCode == IC_STORE)
|
|
||||||
{
|
|
||||||
bm = bins->mSrc[1].mMemory;
|
|
||||||
bi = bins->mSrc[1].mVarIndex;
|
|
||||||
bt = sins->mSrc[1].mTemp;
|
|
||||||
bo = sins->mSrc[1].mIntConst;
|
|
||||||
bz = InterTypeSize[sins->mSrc[0].mType];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check ambiguity
|
|
||||||
if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD)
|
|
||||||
{
|
|
||||||
if (sm == IM_LOCAL)
|
|
||||||
{
|
|
||||||
if (bm == IM_PARAM || bm == IM_GLOBAL || bm == IM_FPARAM)
|
|
||||||
;
|
|
||||||
else if (bm == IM_LOCAL)
|
|
||||||
{
|
|
||||||
if (bi == si)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (sm == IM_FRAME || sm == IM_FFRAME)
|
|
||||||
;
|
|
||||||
else if (sm == IM_FPARAM)
|
|
||||||
{
|
|
||||||
if (bi == si)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (sm == IM_INDIRECT && bm == IM_INDIRECT && st == bt)
|
|
||||||
{
|
|
||||||
return so + sz <= bz || bo + bz <= so;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm == IM_FRAME && (bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Side effects
|
|
||||||
if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// True data dependency
|
|
||||||
if (bins->mDst.mTemp >= 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < sins->mNumOperands; i++)
|
|
||||||
if (bins->mDst.mTemp == sins->mSrc[i].mTemp)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc)
|
void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
|
@ -8702,7 +8793,7 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
|
||||||
#if 1
|
#if 1
|
||||||
else if (
|
else if (
|
||||||
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SHR && mInstructions[i + 0]->mSrc[0].mTemp < 0 &&
|
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SHR && mInstructions[i + 0]->mSrc[0].mTemp < 0 &&
|
||||||
mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U &&
|
mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U &&
|
||||||
mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 2]->mOperator == IA_MUL && mInstructions[i + 2]->mSrc[0].mTemp < 0 &&
|
mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 2]->mOperator == IA_MUL && mInstructions[i + 2]->mSrc[0].mTemp < 0 &&
|
||||||
mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal &&
|
mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal &&
|
||||||
mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mFinal &&
|
mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mFinal &&
|
||||||
|
@ -8744,7 +8835,7 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
|
||||||
else if (
|
else if (
|
||||||
mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mExitRequiredTemps[mInstructions[i + 1]->mDst.mTemp] &&
|
mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mExitRequiredTemps[mInstructions[i + 1]->mDst.mTemp] &&
|
||||||
(!mExitRequiredTemps[mInstructions[i + 1]->mSrc[0].mTemp] ||
|
(!mExitRequiredTemps[mInstructions[i + 1]->mSrc[0].mTemp] ||
|
||||||
(mEntryRequiredTemps[mInstructions[i + 1]->mDst.mTemp] && !mEntryRequiredTemps[mInstructions[i + 1]->mSrc[0].mTemp])) &&
|
(mEntryRequiredTemps[mInstructions[i + 1]->mDst.mTemp] && !mEntryRequiredTemps[mInstructions[i + 1]->mSrc[0].mTemp])) &&
|
||||||
mInstructions[i + 0]->mDst.mTemp == mInstructions[i + 1]->mSrc[0].mTemp)
|
mInstructions[i + 0]->mDst.mTemp == mInstructions[i + 1]->mSrc[0].mTemp)
|
||||||
{
|
{
|
||||||
mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp;
|
mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp;
|
||||||
|
@ -8791,6 +8882,51 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
|
||||||
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mDst;
|
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mDst;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_ADD && mInstructions[i + 0]->mSrc[1].mTemp < 0 && mInstructions[i + 0]->mSrc[0].mType == IT_INT16 &&
|
||||||
|
mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].IsUByte() &&
|
||||||
|
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 + 2]->mSrc[0] = mInstructions[i + 0]->mSrc[0];
|
||||||
|
mInstructions[i + 2]->mSrc[1].mIntConst += mInstructions[i + 0]->mSrc[1].mIntConst;
|
||||||
|
|
||||||
|
mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0;
|
||||||
|
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].mType == IT_INT16 &&
|
||||||
|
mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].IsUByte() &&
|
||||||
|
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 + 2]->mSrc[0] = mInstructions[i + 0]->mSrc[1];
|
||||||
|
mInstructions[i + 2]->mSrc[1].mIntConst += mInstructions[i + 0]->mSrc[0].mIntConst;
|
||||||
|
|
||||||
|
mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0;
|
||||||
|
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_SUB && mInstructions[i + 0]->mSrc[0].mTemp < 0 && mInstructions[i + 0]->mSrc[1].mType == IT_INT16 &&
|
||||||
|
mInstructions[i + 1]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].IsUByte() &&
|
||||||
|
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 + 2]->mSrc[0] = mInstructions[i + 0]->mSrc[1];
|
||||||
|
mInstructions[i + 2]->mSrc[1].mIntConst -= mInstructions[i + 0]->mSrc[0].mIntConst;
|
||||||
|
|
||||||
|
mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0;
|
||||||
|
mInstructions[i + 1]->mCode = IC_NONE; mInstructions[i + 1]->mNumOperands = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// Postincrement artifact
|
// Postincrement artifact
|
||||||
|
@ -9636,6 +9772,9 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CollectLocalUsedTemps(mTemporaries.Size());
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
changed = mEntryBlock->PushSinglePathResultInstructions();
|
changed = mEntryBlock->PushSinglePathResultInstructions();
|
||||||
|
|
||||||
|
|
|
@ -326,7 +326,7 @@ public:
|
||||||
|
|
||||||
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath;
|
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath;
|
||||||
|
|
||||||
NumberSet mLocalUsedTemps;
|
NumberSet mLocalUsedTemps, mLocalModifiedTemps;
|
||||||
NumberSet mLocalRequiredTemps, mLocalProvidedTemps;
|
NumberSet mLocalRequiredTemps, mLocalProvidedTemps;
|
||||||
NumberSet mEntryRequiredTemps, mEntryProvidedTemps;
|
NumberSet mEntryRequiredTemps, mEntryProvidedTemps;
|
||||||
NumberSet mExitRequiredTemps, mExitProvidedTemps;
|
NumberSet mExitRequiredTemps, mExitProvidedTemps;
|
||||||
|
|
|
@ -9915,6 +9915,9 @@ bool NativeCodeBasicBlock::CanReplaceYRegWithXReg(int start, int end)
|
||||||
|
|
||||||
if (ins.mMode == ASMIM_INDIRECT_Y)
|
if (ins.mMode == ASMIM_INDIRECT_Y)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_ABSOLUTE_Y && !HasAsmInstructionMode(ins.mType, ASMIM_ABSOLUTE_X))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -9931,6 +9934,10 @@ bool NativeCodeBasicBlock::CanReplaceXRegWithYReg(int start, int end)
|
||||||
|
|
||||||
if (ins.mMode == ASMIM_INDIRECT_X)
|
if (ins.mMode == ASMIM_INDIRECT_X)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_ABSOLUTE_X && !HasAsmInstructionMode(ins.mType, ASMIM_ABSOLUTE_Y))
|
||||||
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue