Constant folding address of global and static variables
This commit is contained in:
parent
0aacc14287
commit
d2503aaf1f
|
@ -69,6 +69,8 @@ enum RIRQCodeIndex
|
|||
|
||||
RIRQ_DATA_19 = 101,
|
||||
RIRQ_ADDR_19 = 103,
|
||||
|
||||
RIRQ_SIZE_20 = 106,
|
||||
};
|
||||
|
||||
// One raster interrupt operation, handles up to five writes
|
||||
|
@ -79,6 +81,12 @@ typedef struct RIRQCode
|
|||
byte code[RIRQ_SIZE];
|
||||
} RIRQCode;
|
||||
|
||||
typedef struct RQIRCode20
|
||||
{
|
||||
RIRQCode c;
|
||||
byte code[RIRQ_SIZE_20 - RIRQ_SIZE];
|
||||
} RIRQCode20;
|
||||
|
||||
// Build one raster IRQ operation of the given size (wait + #ops) for up to 5 instructions
|
||||
void rirq_build(RIRQCode * ic, byte size);
|
||||
|
||||
|
|
|
@ -211,6 +211,17 @@ Expression* Expression::ConstantFold(Errors * errors)
|
|||
}
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
else if (mType == EX_PREFIX && mToken == TK_BINARY_AND && mLeft->mType == EX_VARIABLE && (mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)))
|
||||
{
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_POINTER);
|
||||
dec->mValue = mLeft;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = mDecType;
|
||||
return ex;
|
||||
}
|
||||
#endif
|
||||
else if (mType == EX_TYPECAST && mRight->mType == EX_CONSTANT)
|
||||
{
|
||||
if (mLeft->mDecType->mType == DT_TYPE_POINTER)
|
||||
|
|
|
@ -715,7 +715,7 @@ static void ConversionConstantFold(InterInstruction * ins, const InterOperand &
|
|||
}
|
||||
}
|
||||
|
||||
static void LoadConstantFold(InterInstruction* ins, InterInstruction* ains)
|
||||
static void LoadConstantFold(InterInstruction* ins, InterInstruction* ains, const GrowingVariableArray& staticVars)
|
||||
{
|
||||
const uint8* data;
|
||||
|
||||
|
@ -752,11 +752,18 @@ static void LoadConstantFold(InterInstruction* ins, InterInstruction* ains)
|
|||
i++;
|
||||
if (i < lobj->mReferences.Size())
|
||||
{
|
||||
int j = 0;
|
||||
while (j < staticVars.Size() && !(staticVars[j] && staticVars[j]->mLinkerObject == lobj->mReferences[i]->mRefObject))
|
||||
j++;
|
||||
|
||||
ins->mConst.mLinkerObject = lobj->mReferences[i]->mRefObject;
|
||||
ins->mConst.mIntConst = lobj->mReferences[i]->mRefOffset;
|
||||
ins->mConst.mMemory = IM_GLOBAL;
|
||||
ins->mConst.mOperandSize = ins->mConst.mLinkerObject->mSize;
|
||||
ins->mConst.mVarIndex = -1;
|
||||
if (j < staticVars.Size())
|
||||
ins->mConst.mVarIndex = staticVars[j]->mIndex;
|
||||
else
|
||||
ins->mConst.mVarIndex = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1107,7 +1114,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
|||
}
|
||||
else if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT && tvalue[ins->mSrc[0].mTemp]->mConst.mMemory == IM_GLOBAL && (tvalue[ins->mSrc[0].mTemp]->mConst.mLinkerObject->mFlags & LOBJF_CONST))
|
||||
{
|
||||
LoadConstantFold(ins, tvalue[ins->mSrc[0].mTemp]);
|
||||
LoadConstantFold(ins, tvalue[ins->mSrc[0].mTemp], staticVars);
|
||||
InsertValue(ins);
|
||||
}
|
||||
else
|
||||
|
@ -3430,7 +3437,7 @@ static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrA
|
|||
}
|
||||
|
||||
|
||||
void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue)
|
||||
void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars)
|
||||
{
|
||||
switch (ins->mCode)
|
||||
{
|
||||
|
@ -3507,7 +3514,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
|
|||
OptimizeAddress(ins, tvalue, 0);
|
||||
|
||||
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL && (ins->mSrc[0].mLinkerObject->mFlags & LOBJF_CONST))
|
||||
LoadConstantFold(ins, nullptr);
|
||||
LoadConstantFold(ins, nullptr, staticVars);
|
||||
|
||||
break;
|
||||
case IC_STORE:
|
||||
|
@ -6179,7 +6186,7 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra
|
|||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid)
|
||||
void InterCodeBasicBlock::PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -6229,12 +6236,12 @@ void InterCodeBasicBlock::PerformMachineSpecificValueUsageCheck(const GrowingIns
|
|||
|
||||
for (i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
CheckValueUsage(mInstructions[i], ltvalue);
|
||||
CheckValueUsage(mInstructions[i], ltvalue, staticVars);
|
||||
mInstructions[i]->PerformValueForwarding(ltvalue, tvalid);
|
||||
}
|
||||
|
||||
if (mTrueJump) mTrueJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid);
|
||||
if (mFalseJump) mFalseJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid);
|
||||
if (mTrueJump) mTrueJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid, staticVars);
|
||||
if (mFalseJump) mFalseJump->PerformMachineSpecificValueUsageCheck(ltvalue, tvalid, staticVars);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9464,7 +9471,7 @@ void InterCodeProcedure::Close(void)
|
|||
mTemporaries.SetSize(numTemps, true);
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet);
|
||||
mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet, mModule->mGlobalVars);
|
||||
|
||||
GlobalConstantPropagation();
|
||||
|
||||
|
@ -9911,6 +9918,43 @@ void InterCodeProcedure::MapVariables(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool InterCodeBasicBlock::SameExitCode(const InterCodeBasicBlock* block) const
|
||||
{
|
||||
if (mInstructions.Size() > 1 && block->mInstructions.Size() > 1)
|
||||
{
|
||||
InterInstruction* ins0 = mInstructions[mInstructions.Size() - 2];
|
||||
InterInstruction* ins1 = block->mInstructions[block->mInstructions.Size() - 2];
|
||||
|
||||
if (ins0->IsEqual(ins1))
|
||||
{
|
||||
if (ins0->mCode == IC_STORE && ins0->mSrc[1].mTemp >= 0)
|
||||
{
|
||||
int j0 = mInstructions.Size() - 2;
|
||||
while (j0 >= 0 && mInstructions[j0]->mDst.mTemp != ins0->mSrc[1].mTemp)
|
||||
j0--;
|
||||
int j1 = block->mInstructions.Size() - 2;
|
||||
while (j1 >= 0 && block->mInstructions[j1]->mDst.mTemp != ins0->mSrc[1].mTemp)
|
||||
j1--;
|
||||
|
||||
if (j0 >= 0 && j1 >= 0)
|
||||
{
|
||||
if (!(mInstructions[j0]->IsEqual(block->mInstructions[j1])))
|
||||
{
|
||||
if (mInstructions[j0]->mCode == IC_LEA && mInstructions[j0]->mSrc[1].mTemp < 0)
|
||||
return false;
|
||||
if (block->mInstructions[j1]->mCode == IC_LEA && mInstructions[j1]->mSrc[1].mTemp < 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void InterCodeProcedure::MergeBasicBlocks(void)
|
||||
{
|
||||
ResetVisited();
|
||||
|
@ -10017,7 +10061,7 @@ void InterCodeProcedure::MergeBasicBlocks(void)
|
|||
InterInstruction* ins = eblocks[0]->mInstructions[eblocks[0]->mInstructions.Size() - 2];
|
||||
|
||||
int j = 1;
|
||||
while (j < eblocks.Size() && eblocks[j]->mInstructions.Size() > 1 && eblocks[j]->mInstructions[eblocks[j]->mInstructions.Size() - 2]->IsEqual(ins))
|
||||
while (j < eblocks.Size() && eblocks[0]->SameExitCode(eblocks[j]))
|
||||
j++;
|
||||
if (j == eblocks.Size())
|
||||
{
|
||||
|
|
|
@ -407,10 +407,10 @@ public:
|
|||
void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable);
|
||||
void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
|
||||
|
||||
void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue);
|
||||
void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars);
|
||||
void PerformTempForwarding(TempForwardingTable& forwardingTable);
|
||||
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps, const GrowingVariableArray& staticVars);
|
||||
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
||||
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars);
|
||||
bool EliminateDeadBranches(void);
|
||||
|
||||
bool CalculateSingleAssignmentTemps(FastNumberSet& tassigned, GrowingInstructionPtrArray& tvalue, NumberSet& modifiedParams, InterMemory paramMemory);
|
||||
|
@ -463,6 +463,8 @@ public:
|
|||
|
||||
bool CheckStaticStack(void);
|
||||
void CollectStaticStack(LinkerObject * lobj, const GrowingVariableArray& localVars);
|
||||
|
||||
bool SameExitCode(const InterCodeBasicBlock* block) const;
|
||||
};
|
||||
|
||||
class InterCodeModule;
|
||||
|
|
|
@ -858,6 +858,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
case DT_CONST_POINTER:
|
||||
{
|
||||
vl = TranslateExpression(procType, proc, block, dec->mValue, breakBlock, continueBlock, inlineMapper);
|
||||
vl.mReference--;
|
||||
vl.mType = exp->mDecType;
|
||||
return vl;
|
||||
}
|
||||
case DT_CONST_DATA:
|
||||
|
@ -884,6 +886,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||
ins->mConst.mIntConst = 0;
|
||||
ins->mConst.mVarIndex = dec->mVarIndex;
|
||||
assert(dec->mVarIndex >= 0);
|
||||
ins->mConst.mLinkerObject = dec->mLinkerObject;
|
||||
ins->mConst.mMemory = IM_GLOBAL;
|
||||
block->Append(ins);
|
||||
|
@ -915,6 +918,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||
ins->mConst.mIntConst = 0;
|
||||
ins->mConst.mVarIndex = dec->mVarIndex;
|
||||
assert(dec->mVarIndex >= 0);
|
||||
ins->mConst.mLinkerObject = dec->mLinkerObject;
|
||||
ins->mConst.mMemory = IM_GLOBAL;
|
||||
block->Append(ins);
|
||||
|
@ -970,6 +974,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mConst.mMemory = IM_GLOBAL;
|
||||
ins->mConst.mLinkerObject = dec->mLinkerObject;
|
||||
ins->mConst.mVarIndex = dec->mVarIndex;
|
||||
assert(dec->mVarIndex >= 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -628,30 +628,39 @@ bool NativeCodeInstruction::RequiresXReg(void) const
|
|||
}
|
||||
|
||||
|
||||
void NativeCodeInstruction::ReplaceYRegWithXReg(void)
|
||||
bool NativeCodeInstruction::ReplaceYRegWithXReg(void)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
switch (mType)
|
||||
{
|
||||
case ASMIT_LDY:
|
||||
mType = ASMIT_LDX;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_STY:
|
||||
mType = ASMIT_STX;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_CPY:
|
||||
mType = ASMIT_CPX;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_TYA:
|
||||
mType = ASMIT_TXA;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_TAY:
|
||||
mType = ASMIT_TAX;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_INY:
|
||||
mType = ASMIT_INX;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_DEY:
|
||||
mType = ASMIT_DEX;
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -660,48 +669,62 @@ void NativeCodeInstruction::ReplaceYRegWithXReg(void)
|
|||
{
|
||||
assert(HasAsmInstructionMode(mType, ASMIM_ABSOLUTE_X));
|
||||
mMode = ASMIM_ABSOLUTE_X;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (mLive & LIVE_CPU_REG_X)
|
||||
mLive |= LIVE_CPU_REG_Y;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void NativeCodeInstruction::ReplaceXRegWithYReg(void)
|
||||
bool NativeCodeInstruction::ReplaceXRegWithYReg(void)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
switch (mType)
|
||||
{
|
||||
case ASMIT_LDX:
|
||||
mType = ASMIT_LDY;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_STX:
|
||||
mType = ASMIT_STY;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_CPX:
|
||||
mType = ASMIT_CPY;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_TXA:
|
||||
mType = ASMIT_TYA;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_TAX:
|
||||
mType = ASMIT_TAY;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_INX:
|
||||
mType = ASMIT_INY;
|
||||
changed = true;
|
||||
break;
|
||||
case ASMIT_DEX:
|
||||
mType = ASMIT_DEY;
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (mMode == ASMIM_ABSOLUTE_X)
|
||||
{
|
||||
assert(HasAsmInstructionMode(mType, ASMIM_ABSOLUTE_Y));
|
||||
mMode = ASMIM_ABSOLUTE_Y;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (mLive & LIVE_CPU_REG_Y)
|
||||
mLive |= LIVE_CPU_REG_X;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeInstruction::ChangesYReg(void) const
|
||||
|
@ -2088,7 +2111,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
|||
}
|
||||
else
|
||||
{
|
||||
if (mMode != ASMIM_ZERO_PAGE)
|
||||
if (mMode != ASMIM_ZERO_PAGE && mMode != ASMIM_ABSOLUTE)
|
||||
data.mRegs[CPU_REG_X].Reset();
|
||||
data.mRegs[CPU_REG_Z].Reset();
|
||||
}
|
||||
|
@ -2117,7 +2140,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
|||
}
|
||||
else
|
||||
{
|
||||
if (mMode != ASMIM_ZERO_PAGE)
|
||||
if (mMode != ASMIM_ZERO_PAGE && mMode != ASMIM_ABSOLUTE)
|
||||
data.mRegs[CPU_REG_Y].Reset();
|
||||
data.mRegs[CPU_REG_Z].Reset();
|
||||
}
|
||||
|
@ -2534,6 +2557,52 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
|||
else
|
||||
data.mRegs[CPU_REG_A].Reset();
|
||||
break;
|
||||
case ASMIT_LDY:
|
||||
if (!(mFlags & NCIF_VOLATILE))
|
||||
{
|
||||
if (data.mRegs[CPU_REG_Y].mMode == NRDM_ABSOLUTE && data.mRegs[CPU_REG_Y].mLinkerObject == mLinkerObject && data.mRegs[CPU_REG_Y].mValue == mAddress)
|
||||
{
|
||||
if (!(mLive & LIVE_CPU_REG_Z))
|
||||
{
|
||||
mType = ASMIT_NOP;
|
||||
mMode = ASMIM_IMPLIED;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.mRegs[CPU_REG_Y].mMode = NRDM_ABSOLUTE;
|
||||
data.mRegs[CPU_REG_Y].mLinkerObject = mLinkerObject;
|
||||
data.mRegs[CPU_REG_Y].mValue = mAddress;
|
||||
data.mRegs[CPU_REG_Y].mFlags = mFlags;
|
||||
}
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_Y].Reset();
|
||||
break;
|
||||
case ASMIT_LDX:
|
||||
if (!(mFlags & NCIF_VOLATILE))
|
||||
{
|
||||
if (data.mRegs[CPU_REG_X].mMode == NRDM_ABSOLUTE && data.mRegs[CPU_REG_X].mLinkerObject == mLinkerObject && data.mRegs[CPU_REG_X].mValue == mAddress)
|
||||
{
|
||||
if (!(mLive & LIVE_CPU_REG_Z))
|
||||
{
|
||||
mType = ASMIT_NOP;
|
||||
mMode = ASMIM_IMPLIED;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.mRegs[CPU_REG_X].mMode = NRDM_ABSOLUTE;
|
||||
data.mRegs[CPU_REG_X].mLinkerObject = mLinkerObject;
|
||||
data.mRegs[CPU_REG_X].mValue = mAddress;
|
||||
data.mRegs[CPU_REG_X].mFlags = mFlags;
|
||||
}
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_X].Reset();
|
||||
break;
|
||||
default:
|
||||
if (ChangesAddress())
|
||||
data.ResetAbsolute(mLinkerObject, mAddress);
|
||||
|
@ -9001,6 +9070,50 @@ bool NativeCodeBasicBlock::RemoveUnusedResultInstructions(void)
|
|||
return changed;
|
||||
}
|
||||
|
||||
void NativeCodeBasicBlock::BuildDominatorTree(NativeCodeBasicBlock* from)
|
||||
{
|
||||
if (from == this)
|
||||
return;
|
||||
else if (!mDominator)
|
||||
mDominator = from;
|
||||
else if (from == mDominator)
|
||||
return;
|
||||
else
|
||||
{
|
||||
GrowingArray< NativeCodeBasicBlock * > d1(nullptr), d2(nullptr);
|
||||
|
||||
NativeCodeBasicBlock* 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 NativeCodeBasicBlock::CountEntries(NativeCodeBasicBlock * fromJump)
|
||||
{
|
||||
if (mVisiting)
|
||||
|
@ -9419,13 +9532,16 @@ void NativeCodeBasicBlock::GlobalRegisterYMap(int reg)
|
|||
|
||||
bool NativeCodeBasicBlock::ReplaceYRegWithXReg(int start, int end)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
NativeCodeInstruction& ins(mIns[i]);
|
||||
ins.ReplaceYRegWithXReg();
|
||||
if (ins.ReplaceYRegWithXReg())
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::ReduceLocalYPressure(void)
|
||||
|
@ -9776,15 +9892,161 @@ bool NativeCodeBasicBlock::ForwardZpXIndex(bool full)
|
|||
|
||||
bool NativeCodeBasicBlock::ReplaceXRegWithYReg(int start, int end)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
NativeCodeInstruction& ins(mIns[i]);
|
||||
ins.ReplaceXRegWithYReg();
|
||||
if (ins.ReplaceXRegWithYReg())
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CanReplaceYRegWithXReg(int start, int end)
|
||||
{
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
NativeCodeInstruction& ins(mIns[i]);
|
||||
|
||||
if ((ins.mLive & LIVE_CPU_REG_X) && (ins.mLive & LIVE_CPU_REG_Y))
|
||||
return false;
|
||||
|
||||
if (ins.mMode == ASMIM_INDIRECT_Y)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CanReplaceXRegWithYReg(int start, int end)
|
||||
{
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
NativeCodeInstruction& ins(mIns[i]);
|
||||
|
||||
if ((ins.mLive & LIVE_CPU_REG_X) && (ins.mLive & LIVE_CPU_REG_Y))
|
||||
return false;
|
||||
|
||||
if (ins.mMode == ASMIM_INDIRECT_X)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::AlternateXYUsage(void)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
int start = 0;
|
||||
|
||||
|
||||
int predYPos = -1, predXPos = -1, currYPos = -1, currXPos = -1, predYEnd = -1, predXEnd = -1;
|
||||
|
||||
for (int start = 0; start < mIns.Size(); start++)
|
||||
{
|
||||
const NativeCodeInstruction& ins(mIns[start]);
|
||||
|
||||
if (ins.mType == ASMIT_LDY)
|
||||
{
|
||||
if ((ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE) && predYPos >= 0 && ins.SameEffectiveAddress(mIns[predYPos]))
|
||||
{
|
||||
if (CanReplaceYRegWithXReg(predYEnd, start))
|
||||
{
|
||||
if (ReplaceYRegWithXReg(predYEnd, start))
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currYPos >= 0)
|
||||
{
|
||||
predYPos = currYPos;
|
||||
predYEnd = start;
|
||||
}
|
||||
|
||||
if (ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE)
|
||||
currYPos = start;
|
||||
else
|
||||
currYPos = -1;
|
||||
}
|
||||
}
|
||||
else if (ins.mType == ASMIT_LDX)
|
||||
{
|
||||
if ((ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE) && predXPos >= 0 && ins.SameEffectiveAddress(mIns[predXPos]))
|
||||
{
|
||||
if (CanReplaceXRegWithYReg(predXEnd, start))
|
||||
{
|
||||
if (ReplaceXRegWithYReg(predXEnd, start))
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currXPos >= 0)
|
||||
{
|
||||
predXPos = currXPos;
|
||||
predXEnd = start;
|
||||
}
|
||||
|
||||
if (ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE)
|
||||
currXPos = start;
|
||||
else
|
||||
currXPos = -1;
|
||||
}
|
||||
}
|
||||
else if (ins.mType == ASMIT_JSR)
|
||||
{
|
||||
currYPos = predYPos = -1;
|
||||
currXPos = predXPos = -1;
|
||||
}
|
||||
else if (ins.ChangesXReg())
|
||||
{
|
||||
if (currXPos != -1)
|
||||
{
|
||||
predXEnd = start;
|
||||
predXPos = currXPos;
|
||||
}
|
||||
currXPos = -1;
|
||||
}
|
||||
else if (ins.ChangesYReg())
|
||||
{
|
||||
if (currYPos != -1)
|
||||
{
|
||||
predYEnd = start;
|
||||
predYPos = currYPos;
|
||||
}
|
||||
currYPos = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (predYPos >= 0 && mIns[predYPos].MayBeChangedOnAddress(ins))
|
||||
predYPos = -1;
|
||||
if (predXPos >= 0 && mIns[predXPos].MayBeChangedOnAddress(ins))
|
||||
predXPos = -1;
|
||||
if (currYPos >= 0 && mIns[currYPos].MayBeChangedOnAddress(ins))
|
||||
currYPos = -1;
|
||||
if (currXPos >= 0 && mIns[currXPos].MayBeChangedOnAddress(ins))
|
||||
currYPos = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->AlternateXYUsage())
|
||||
changed = true;
|
||||
|
||||
if (mFalseJump && mFalseJump->AlternateXYUsage())
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::ReduceLocalXPressure(void)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -10599,7 +10861,7 @@ bool NativeCodeBasicBlock::FindImmediateStore(int at, int reg, const NativeCodeI
|
|||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains, int cycles)
|
||||
bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles)
|
||||
{
|
||||
if (!mPatched)
|
||||
{
|
||||
|
@ -10611,7 +10873,14 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(int reg, int at, const Nativ
|
|||
return true;
|
||||
|
||||
if (mNumEntries > 1)
|
||||
return false;
|
||||
{
|
||||
if (mLoopHead)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||
if (!mEntryBlocks[i]->IsDominatedBy(block))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
while (at < mIns.Size())
|
||||
|
@ -10664,16 +10933,16 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(int reg, int at, const Nativ
|
|||
at++;
|
||||
}
|
||||
|
||||
if (mTrueJump && !mTrueJump->CheckSingleUseGlobalLoad(reg, 0, ains, cycles))
|
||||
if (mTrueJump && !mTrueJump->CheckSingleUseGlobalLoad(block, reg, 0, ains, cycles))
|
||||
return false;
|
||||
if (mFalseJump && !mFalseJump->CheckSingleUseGlobalLoad(reg, 0, ains, cycles))
|
||||
if (mFalseJump && !mFalseJump->CheckSingleUseGlobalLoad(block, reg, 0, ains, cycles))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::PatchSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains)
|
||||
bool NativeCodeBasicBlock::PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
|
@ -10703,16 +10972,16 @@ bool NativeCodeBasicBlock::PatchSingleUseGlobalLoad(int reg, int at, const Nativ
|
|||
at++;
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->PatchSingleUseGlobalLoad(reg, 0, ains))
|
||||
if (mTrueJump && mTrueJump->PatchSingleUseGlobalLoad(block, reg, 0, ains))
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->PatchSingleUseGlobalLoad(reg, 0, ains))
|
||||
if (mFalseJump && mFalseJump->PatchSingleUseGlobalLoad(block, reg, 0, ains))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CheckForwardSumYPointer(int reg, int base, int index, int at, int yval)
|
||||
bool NativeCodeBasicBlock::CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, int index, int at, int yval)
|
||||
{
|
||||
if (!mPatched)
|
||||
{
|
||||
|
@ -10724,7 +10993,12 @@ bool NativeCodeBasicBlock::CheckForwardSumYPointer(int reg, int base, int index,
|
|||
return true;
|
||||
|
||||
if (mNumEntries > 1)
|
||||
{
|
||||
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||
if (!mEntryBlocks[i]->IsDominatedBy(block))
|
||||
return false;
|
||||
yval = -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (at < mIns.Size())
|
||||
|
@ -10761,16 +11035,16 @@ bool NativeCodeBasicBlock::CheckForwardSumYPointer(int reg, int base, int index,
|
|||
at++;
|
||||
}
|
||||
|
||||
if (mTrueJump && !mTrueJump->CheckForwardSumYPointer(reg, base, index, 0, yval))
|
||||
if (mTrueJump && !mTrueJump->CheckForwardSumYPointer(block, reg, base, index, 0, yval))
|
||||
return false;
|
||||
if (mFalseJump && !mFalseJump->CheckForwardSumYPointer(reg, base, index, 0, yval))
|
||||
if (mFalseJump && !mFalseJump->CheckForwardSumYPointer(block, reg, base, index, 0, yval))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::PatchForwardSumYPointer(int reg, int base, int index, int at, int yval)
|
||||
bool NativeCodeBasicBlock::PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, int index, int at, int yval)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
|
@ -10821,16 +11095,36 @@ bool NativeCodeBasicBlock::PatchForwardSumYPointer(int reg, int base, int index,
|
|||
at++;
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->PatchForwardSumYPointer(reg, base, index, 0, yval))
|
||||
if (mTrueJump && mTrueJump->PatchForwardSumYPointer(block, reg, base, index, 0, yval))
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->PatchForwardSumYPointer(reg, base, index, 0, yval))
|
||||
if (mFalseJump && mFalseJump->PatchForwardSumYPointer(block, reg, base, index, 0, yval))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(int reg, int at, int yval)
|
||||
|
||||
|
||||
bool NativeCodeBasicBlock::IsDominatedBy(const NativeCodeBasicBlock* block) const
|
||||
{
|
||||
if (this == block)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* dom = mDominator;
|
||||
while (dom)
|
||||
{
|
||||
if (dom == block)
|
||||
return true;
|
||||
dom = dom->mDominator;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int at, int yval)
|
||||
{
|
||||
if (!mPatched)
|
||||
{
|
||||
|
@ -10842,7 +11136,12 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(int reg, int at, int yv
|
|||
return true;
|
||||
|
||||
if (mNumEntries > 1)
|
||||
{
|
||||
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||
if (!mEntryBlocks[i]->IsDominatedBy(block))
|
||||
return false;
|
||||
yval = -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (at < mIns.Size())
|
||||
|
@ -10877,16 +11176,16 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(int reg, int at, int yv
|
|||
at++;
|
||||
}
|
||||
|
||||
if (mTrueJump && !mTrueJump->CheckGlobalAddressSumYPointer(reg, 0, yval))
|
||||
if (mTrueJump && !mTrueJump->CheckGlobalAddressSumYPointer(block, reg, 0, yval))
|
||||
return false;
|
||||
if (mFalseJump && !mFalseJump->CheckGlobalAddressSumYPointer(reg, 0, yval))
|
||||
if (mFalseJump && !mFalseJump->CheckGlobalAddressSumYPointer(block, reg, 0, yval))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::PatchGlobalAddressSumYPointer(int reg, int at, int yval, LinkerObject* lobj, int address)
|
||||
bool NativeCodeBasicBlock::PatchGlobalAddressSumYPointer(const NativeCodeBasicBlock* block, int reg, int at, int yval, LinkerObject* lobj, int address)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
|
@ -10933,9 +11232,9 @@ bool NativeCodeBasicBlock::PatchGlobalAddressSumYPointer(int reg, int at, int yv
|
|||
at++;
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->PatchGlobalAddressSumYPointer(reg, 0, yval, lobj, address))
|
||||
if (mTrueJump && mTrueJump->PatchGlobalAddressSumYPointer(block, reg, 0, yval, lobj, address))
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->PatchGlobalAddressSumYPointer(reg, 0, yval, lobj, address))
|
||||
if (mFalseJump && mFalseJump->PatchGlobalAddressSumYPointer(block, reg, 0, yval, lobj, address))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
@ -18194,10 +18493,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (CheckSingleUseGlobalLoad(mIns[i + 1].mAddress, i + 2, mIns[i], 3))
|
||||
if (CheckSingleUseGlobalLoad(this, mIns[i + 1].mAddress, i + 2, mIns[i], 3))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (PatchSingleUseGlobalLoad(mIns[i + 1].mAddress, i + 2, mIns[i]))
|
||||
if (PatchSingleUseGlobalLoad(this, mIns[i + 1].mAddress, i + 2, mIns[i]))
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
@ -18206,10 +18505,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE)
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (CheckSingleUseGlobalLoad(mIns[i + 0].mAddress, i + 2, mIns[i + 1], 2))
|
||||
if (CheckSingleUseGlobalLoad(this, mIns[i + 0].mAddress, i + 2, mIns[i + 1], 2))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (PatchSingleUseGlobalLoad(mIns[i + 0].mAddress, i + 2, mIns[i + 1]))
|
||||
if (PatchSingleUseGlobalLoad(this, mIns[i + 0].mAddress, i + 2, mIns[i + 1]))
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
@ -18259,7 +18558,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
!(mIns[i + 5].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (CheckGlobalAddressSumYPointer(mIns[i + 2].mAddress, i + 6, -1))
|
||||
if (CheckGlobalAddressSumYPointer(this, mIns[i + 2].mAddress, i + 6, -1))
|
||||
{
|
||||
assert(mIns[i + 3].mAddress == mIns[i + 1].mAddress);
|
||||
|
||||
|
@ -18270,7 +18569,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
||||
|
||||
proc->ResetPatched();
|
||||
if (PatchGlobalAddressSumYPointer(mIns[i + 2].mAddress, i + 6, -1, mIns[i + 3].mLinkerObject, mIns[i + 3].mAddress))
|
||||
if (PatchGlobalAddressSumYPointer(this, mIns[i + 2].mAddress, i + 6, -1, mIns[i + 3].mLinkerObject, mIns[i + 3].mAddress))
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
@ -18286,14 +18585,14 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
!(mIns[i + 5].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (CheckGlobalAddressSumYPointer(mIns[i + 2].mAddress, i + 6, -1))
|
||||
if (CheckGlobalAddressSumYPointer(this, mIns[i + 2].mAddress, i + 6, -1))
|
||||
{
|
||||
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
||||
|
||||
proc->ResetPatched();
|
||||
if (PatchGlobalAddressSumYPointer(mIns[i + 2].mAddress, i + 6, -1, nullptr, 256 * mIns[i + 3].mAddress))
|
||||
if (PatchGlobalAddressSumYPointer(this, mIns[i + 2].mAddress, i + 6, -1, nullptr, 256 * mIns[i + 3].mAddress))
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
@ -18329,7 +18628,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
!(mIns[i + 6].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (CheckGlobalAddressSumYPointer(mIns[i + 3].mAddress, i + 7, -1))
|
||||
if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, i + 7, -1))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
|
@ -18339,7 +18638,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
|
||||
|
||||
proc->ResetPatched();
|
||||
if (PatchGlobalAddressSumYPointer(mIns[i + 3].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress))
|
||||
if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress))
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
@ -18357,7 +18656,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
!(mIns[i + 6].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (CheckForwardSumYPointer(mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 3].mAddress, i + 7, -1))
|
||||
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 3].mAddress, i + 7, -1))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
|
@ -18368,7 +18667,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
|
||||
|
||||
proc->ResetPatched();
|
||||
if (PatchForwardSumYPointer(mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 3].mAddress, i + 7, -1))
|
||||
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 3].mAddress, i + 7, -1))
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
@ -18385,7 +18684,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
!(mIns[i + 6].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (CheckForwardSumYPointer(mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, -1))
|
||||
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, -1))
|
||||
{
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
|
@ -18395,7 +18694,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
|
||||
|
||||
proc->ResetPatched();
|
||||
if (PatchForwardSumYPointer(mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, -1))
|
||||
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, mIns[i + 0].mAddress, i + 7, -1))
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
@ -19069,6 +19368,7 @@ NativeCodeBasicBlock::NativeCodeBasicBlock(void)
|
|||
mBypassed = false;
|
||||
mAssembled = false;
|
||||
mLocked = false;
|
||||
mDominator = nullptr;
|
||||
mLoopHeadBlock = nullptr;
|
||||
}
|
||||
|
||||
|
@ -19603,9 +19903,10 @@ void NativeCodeProcedure::Optimize(void)
|
|||
mBlocks[i]->mVisiting = false;
|
||||
mBlocks[i]->mLoopHead = false;
|
||||
mBlocks[i]->mFromJump = nullptr;
|
||||
mBlocks[i]->mDominator = nullptr;
|
||||
}
|
||||
mEntryBlock->CountEntries(nullptr);
|
||||
|
||||
mEntryBlock->BuildDominatorTree(nullptr);
|
||||
#if 1
|
||||
do
|
||||
{
|
||||
|
@ -19785,6 +20086,13 @@ void NativeCodeProcedure::Optimize(void)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
if (step == 5)
|
||||
{
|
||||
ResetVisited();
|
||||
if (mEntryBlock->AlternateXYUsage())
|
||||
changed = true;
|
||||
}
|
||||
|
||||
#if 1
|
||||
ResetVisited();
|
||||
if (mEntryBlock->ForwardZpYIndex(step >= 4))
|
||||
|
|
|
@ -114,8 +114,8 @@ public:
|
|||
bool IsCommutative(void) const;
|
||||
bool IsShift(void) const;
|
||||
|
||||
void ReplaceYRegWithXReg(void);
|
||||
void ReplaceXRegWithYReg(void);
|
||||
bool ReplaceYRegWithXReg(void);
|
||||
bool ReplaceXRegWithYReg(void);
|
||||
};
|
||||
|
||||
class NativeCodeBasicBlock
|
||||
|
@ -135,8 +135,10 @@ public:
|
|||
|
||||
GrowingArray<NativeCodeBasicBlock*> mEntryBlocks;
|
||||
|
||||
int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset;
|
||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched;
|
||||
int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset;
|
||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched;
|
||||
NativeCodeBasicBlock * mDominator;
|
||||
|
||||
NativeCodeBasicBlock* mLoopHeadBlock;
|
||||
|
||||
NativeRegisterDataSet mDataSet, mNDataSet;
|
||||
|
@ -220,6 +222,7 @@ public:
|
|||
void CountEntries(NativeCodeBasicBlock* fromJump);
|
||||
bool MergeBasicBlocks(void);
|
||||
void MarkLoopHead(void);
|
||||
void BuildDominatorTree(NativeCodeBasicBlock * from);
|
||||
|
||||
bool MoveLoadStoreUp(int at);
|
||||
bool MoveLoadStoreXUp(int at);
|
||||
|
@ -258,6 +261,9 @@ public:
|
|||
bool ReplaceYRegWithXReg(int start, int end);
|
||||
bool ReplaceXRegWithYReg(int start, int end);
|
||||
|
||||
bool CanReplaceYRegWithXReg(int start, int end);
|
||||
bool CanReplaceXRegWithYReg(int start, int end);
|
||||
|
||||
bool ForwardZpYIndex(bool full);
|
||||
bool ForwardZpXIndex(bool full);
|
||||
|
||||
|
@ -296,14 +302,19 @@ public:
|
|||
bool ReduceLocalYPressure(void);
|
||||
bool ReduceLocalXPressure(void);
|
||||
|
||||
bool CheckGlobalAddressSumYPointer(int reg, int at, int yval);
|
||||
bool PatchGlobalAddressSumYPointer(int reg, int at, int yval, LinkerObject * lobj, int address);
|
||||
bool AlternateXYUsage(void);
|
||||
bool ForwardAbsoluteLoadStores(void);
|
||||
|
||||
bool CheckSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains, int cycles);
|
||||
bool PatchSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains);
|
||||
bool CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int at, int yval);
|
||||
bool PatchGlobalAddressSumYPointer(const NativeCodeBasicBlock* block, int reg, int at, int yval, LinkerObject * lobj, int address);
|
||||
|
||||
bool CheckForwardSumYPointer(int reg, int base, int index, int at, int yval);
|
||||
bool PatchForwardSumYPointer(int reg, int base, int index, int at, int yval);
|
||||
bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles);
|
||||
bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains);
|
||||
|
||||
bool CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, int index, int at, int yval);
|
||||
bool PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, int index, int at, int yval);
|
||||
|
||||
bool IsDominatedBy(const NativeCodeBasicBlock* block) const;
|
||||
};
|
||||
|
||||
class NativeCodeProcedure
|
||||
|
|
Loading…
Reference in New Issue