Optimize array access and value propagation across simple loops

This commit is contained in:
drmortalwombat 2022-06-21 20:57:58 +02:00
parent 3cdc9032b4
commit 002c10ad13
8 changed files with 190 additions and 35 deletions

View File

@ -431,6 +431,16 @@ static bool CollidingMem(const InterOperand& op, const InterInstruction* ins, co
return false; return false;
} }
static bool CollidingMem(const InterInstruction* ins1, const InterInstruction* ins2, const GrowingVariableArray& staticVars)
{
if (ins1->mCode == IC_LOAD)
return CollidingMem(ins1->mSrc[0], ins2, staticVars);
else if (ins1->mCode == IC_STORE)
return CollidingMem(ins1->mSrc[1], ins2, staticVars);
else
return false;
}
static bool SameMem(const InterOperand& op1, const InterOperand& op2) static bool SameMem(const InterOperand& op1, const InterOperand& op2)
{ {
if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst) if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst)
@ -534,8 +544,11 @@ static bool SameMem(const InterOperand& op, const InterInstruction* ins)
static bool SameInstruction(const InterInstruction* ins1, const InterInstruction* ins2) static bool SameInstruction(const InterInstruction* ins1, const InterInstruction* ins2)
{ {
if (ins1->mCode == ins2->mCode && ins1->mNumOperands == ins2->mNumOperands && ins1->mOperator == ins2->mOperator) if (ins1->mCode == ins2->mCode && ins1->mNumOperands == ins2->mNumOperands)
{ {
if ((ins1->mCode == IC_BINARY_OPERATOR || ins1->mCode == IC_UNARY_OPERATOR || ins1->mCode == IC_RELATIONAL_OPERATOR || ins1->mCode == IC_CONVERSION_OPERATOR) && ins1->mOperator != ins2->mOperator)
return false;
if (ins1->mCode == IC_BINARY_OPERATOR && IsCommutative(ins1->mOperator)) if (ins1->mCode == IC_BINARY_OPERATOR && IsCommutative(ins1->mOperator))
{ {
return return
@ -3299,6 +3312,7 @@ bool InterInstruction::ConstantFolding(void)
mSrc[0] = mSrc[1]; mSrc[0] = mSrc[1];
mSrc[1].mTemp = -1; mSrc[1].mTemp = -1;
mNumOperands = 1; mNumOperands = 1;
assert(mSrc[0].mTemp >= 0);
return true; return true;
} }
else if (mOperator == IA_MODU && (mSrc[0].mIntConst & (mSrc[0].mIntConst - 1)) == 0) else if (mOperator == IA_MODU && (mSrc[0].mIntConst & (mSrc[0].mIntConst - 1)) == 0)
@ -3334,6 +3348,7 @@ bool InterInstruction::ConstantFolding(void)
mCode = IC_LOAD_TEMPORARY; mCode = IC_LOAD_TEMPORARY;
mSrc[1].mTemp = -1; mSrc[1].mTemp = -1;
mNumOperands = 1; mNumOperands = 1;
assert(mSrc[0].mTemp >= 0);
return true; return true;
} }
else if ((mOperator == IA_AND || mOperator == IA_MUL || mOperator == IA_SHL || mOperator == IA_SHR || mOperator == IA_SAR) && mSrc[1].mIntConst == 0) else if ((mOperator == IA_AND || mOperator == IA_MUL || mOperator == IA_SHL || mOperator == IA_SHR || mOperator == IA_SAR) && mSrc[1].mIntConst == 0)
@ -3382,6 +3397,7 @@ bool InterInstruction::ConstantFolding(void)
mCode = IC_CONSTANT; mCode = IC_CONSTANT;
mConst = mSrc[1]; mConst = mSrc[1];
mConst.mIntConst += mSrc[0].mIntConst; mConst.mIntConst += mSrc[0].mIntConst;
mConst.mRange.Reset();
mNumOperands = 0; mNumOperands = 0;
return true; return true;
} }
@ -3391,6 +3407,7 @@ bool InterInstruction::ConstantFolding(void)
mSrc[0] = mSrc[1]; mSrc[0] = mSrc[1];
mSrc[1].mTemp = -1; mSrc[1].mTemp = -1;
mNumOperands = 1; mNumOperands = 1;
assert(mSrc[0].mTemp >= 0);
return true; return true;
} }
break; break;
@ -5112,6 +5129,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
InterInstruction* ins(mInstructions[i]); InterInstruction* ins(mInstructions[i]);
for (int i = 0; i < ins->mNumOperands; i++) for (int i = 0; i < ins->mNumOperands; i++)
{
if (IsIntegerType(ins->mSrc[i].mType) || ins->mSrc[i].mType == IT_BOOL)
{ {
if (ins->mSrc[i].mTemp >= 0) if (ins->mSrc[i].mTemp >= 0)
{ {
@ -5124,12 +5143,13 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
} }
#endif #endif
} }
else if (IsIntegerType(ins->mSrc[i].mType)) else
{ {
ins->mSrc[i].mRange.mMaxState = ins->mSrc[i].mRange.mMinState = IntegerValueRange::S_BOUND; ins->mSrc[i].mRange.mMaxState = ins->mSrc[i].mRange.mMinState = IntegerValueRange::S_BOUND;
ins->mSrc[i].mRange.mMinValue = ins->mSrc[i].mRange.mMaxValue = ins->mSrc[i].mIntConst; ins->mSrc[i].mRange.mMinValue = ins->mSrc[i].mRange.mMaxValue = ins->mSrc[i].mIntConst;
} }
} }
}
ins->ConstantFolding(); ins->ConstantFolding();
@ -6247,6 +6267,7 @@ bool InterCodeBasicBlock::SingleAssignmentTempForwarding(const GrowingInstructio
ins->mSrc[0].mTemp = ntvalues[j]->mDst.mTemp; ins->mSrc[0].mTemp = ntvalues[j]->mDst.mTemp;
ins->mSrc[0].mType = ntvalues[j]->mDst.mType; ins->mSrc[0].mType = ntvalues[j]->mDst.mType;
ins->mNumOperands = 1; ins->mNumOperands = 1;
assert(ins->mSrc[0].mTemp >= 0);
} }
changed = true; changed = true;
ntunified[ins->mDst.mTemp] = ntvalues[j]; ntunified[ins->mDst.mTemp] = ntvalues[j];
@ -7065,6 +7086,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
{ {
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0].mType = IT_INT16; ins->mSrc[0].mType = IT_INT16;
assert(ins->mSrc[0].mTemp >= 0);
changed = true; changed = true;
} }
} }
@ -7074,12 +7096,29 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
{ {
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0].mType = IT_INT16; ins->mSrc[0].mType = IT_INT16;
assert(ins->mSrc[0].mTemp >= 0);
changed = true; changed = true;
} }
} }
break; break;
#endif #endif
#if 1
case IC_STORE:
if (ins->mSrc[1].mTemp >= 0 && ltvalue[ins->mSrc[1].mTemp])
{
InterInstruction* pins = ltvalue[ins->mSrc[1].mTemp];
if (pins->mCode == IC_LEA && pins->mSrc[0].mTemp < 0)
{
ins->mSrc[1].Forward(pins->mSrc[1]);
pins->mSrc[1].mFinal = false;
ins->mSrc[1].mIntConst += pins->mSrc[0].mIntConst;
changed = true;
}
}
break;
#endif
} }
// Now kill all instructions that referenced the current destination as source, they are // Now kill all instructions that referenced the current destination as source, they are
@ -7100,6 +7139,14 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
} }
} }
#if _DEBUG
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins = mInstructions[i];
assert(ins->mCode != IC_LOAD_TEMPORARY || ins->mSrc[0].mTemp >= 0);
}
#endif
if (mTrueJump && mTrueJump->SimplifyIntegerNumeric(ltvalue, spareTemps)) if (mTrueJump && mTrueJump->SimplifyIntegerNumeric(ltvalue, spareTemps))
changed = true; changed = true;
@ -7641,6 +7688,27 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
} }
} }
} }
#if 1
else if (mNumEntries == 2 && (mTrueJump == this || mFalseJump == this))
{
mLoadStoreInstructions = tvalue;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins(mInstructions[i]);
if (ins->mDst.mTemp >= 0)
{
int j = 0;
while (j < mLoadStoreInstructions.Size())
{
if (mLoadStoreInstructions[j]->ReferencesTemp(ins->mDst.mTemp) || CollidingMem(ins, mLoadStoreInstructions[j], staticVars))
mLoadStoreInstructions.Remove(j);
else
j++;
}
}
}
}
#endif
else else
mLoadStoreInstructions.SetSize(0); mLoadStoreInstructions.SetSize(0);
@ -7668,6 +7736,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mDst; ins->mSrc[0] = lins->mDst;
ins->mNumOperands = 1; ins->mNumOperands = 1;
assert(ins->mSrc[0].mTemp >= 0);
changed = true; changed = true;
} }
else if (lins->mCode == IC_STORE) else if (lins->mCode == IC_STORE)
@ -7683,6 +7752,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mSrc[0]; ins->mSrc[0] = lins->mSrc[0];
ins->mNumOperands = 1; ins->mNumOperands = 1;
assert(ins->mSrc[0].mTemp >= 0);
changed = true; changed = true;
} }
} }
@ -7729,6 +7799,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
if (j < mLoadStoreInstructions.Size()) if (j < mLoadStoreInstructions.Size())
{ {
InterInstruction* lins = mLoadStoreInstructions[j]; InterInstruction* lins = mLoadStoreInstructions[j];
assert(lins->mDst.mTemp >= 0);
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mDst; ins->mSrc[0] = lins->mDst;
ins->mNumOperands = 1; ins->mNumOperands = 1;
@ -8117,6 +8188,7 @@ bool InterCodeBasicBlock::MergeCommonPathInstructions(void)
nins->mDst.mType = fins->mDst.mType; nins->mDst.mType = fins->mDst.mType;
nins->mSrc[0].mTemp = tins->mDst.mTemp; nins->mSrc[0].mTemp = tins->mDst.mTemp;
nins->mSrc[0].mType = tins->mDst.mType; nins->mSrc[0].mType = tins->mDst.mType;
assert(nins->mSrc[0].mTemp >= 0);
mInstructions.Insert(tindex, nins); mInstructions.Insert(tindex, nins);
} }
} }
@ -8240,6 +8312,7 @@ bool InterCodeBasicBlock::ForwardDiamondMovedTemp(void)
nins->mDst.mType = mins->mDst.mType; nins->mDst.mType = mins->mDst.mType;
nins->mSrc[0].mTemp = stemp; nins->mSrc[0].mTemp = stemp;
nins->mSrc[0].mType = mins->mDst.mType; nins->mSrc[0].mType = mins->mDst.mType;
assert(nins->mSrc[0].mTemp >= 0);
fblock->mInstructions.Insert(0, nins); fblock->mInstructions.Insert(0, nins);
tblock->mExitRequiredTemps += stemp; tblock->mExitRequiredTemps += stemp;
@ -9413,6 +9486,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
nins->mSrc[0].Forward(sins->mSrc[0]); nins->mSrc[0].Forward(sins->mSrc[0]);
ins->mDst.Forward(sins->mSrc[0]); ins->mDst.Forward(sins->mSrc[0]);
sins->mSrc[0].mFinal = false; sins->mSrc[0].mFinal = false;
assert(nins->mSrc[0].mTemp >= 0);
// Move store behind loop // Move store behind loop
if (mTrueJump == this) if (mTrueJump == this)
@ -10366,6 +10440,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
mInstructions[i + 0]->mCode = IC_LOAD_TEMPORARY; mInstructions[i + 0]->mCode = IC_LOAD_TEMPORARY;
mInstructions[i + 0]->mSrc[0] = mInstructions[i + 0]->mSrc[1]; mInstructions[i + 0]->mSrc[0] = mInstructions[i + 0]->mSrc[1];
mInstructions[i + 0]->mSrc[1].mTemp = -1; mInstructions[i + 0]->mSrc[1].mTemp = -1;
assert(mInstructions[i + 0]->mSrc[0].mTemp >= 0);
mInstructions[i + 1]->mSrc[1].mIntConst = 255ULL >> shift << shift; mInstructions[i + 1]->mSrc[1].mIntConst = 255ULL >> shift << shift;
mInstructions[i + 2]->mSrc[0].mIntConst >>= shift; mInstructions[i + 2]->mSrc[0].mIntConst >>= shift;
@ -10428,8 +10503,11 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
mInstructions[i + 0]->mCode = IC_LEA; mInstructions[i + 0]->mCode = IC_LEA;
mInstructions[i + 0]->mSrc[1] = mInstructions[i + 1]->mSrc[1]; mInstructions[i + 0]->mSrc[1] = mInstructions[i + 1]->mSrc[1];
mInstructions[i + 0]->mDst.mType = IT_POINTER; mInstructions[i + 0]->mDst.mType = IT_POINTER;
mInstructions[i + 0]->mDst.mRange.Reset();
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mDst; mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mDst;
mInstructions[i + 1]->mSrc[1].mMemory = IM_INDIRECT;
changed = true; changed = true;
} }
else if ( else if (
@ -10443,10 +10521,30 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
mInstructions[i + 0]->mSrc[0] = mInstructions[i + 0]->mSrc[1]; mInstructions[i + 0]->mSrc[0] = mInstructions[i + 0]->mSrc[1];
mInstructions[i + 0]->mSrc[1] = mInstructions[i + 1]->mSrc[1]; mInstructions[i + 0]->mSrc[1] = mInstructions[i + 1]->mSrc[1];
mInstructions[i + 0]->mDst.mType = IT_POINTER; mInstructions[i + 0]->mDst.mType = IT_POINTER;
mInstructions[i + 0]->mDst.mRange.Reset();
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mDst; mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mDst;
mInstructions[i + 1]->mSrc[1].mMemory = IM_INDIRECT;
changed = true; changed = true;
} }
#if 1
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[0].mIntConst >= 0 && mInstructions[i + 0]->mSrc[0].mIntConst <= 16 &&
mInstructions[i + 1]->mCode == IC_LEA && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal)
{
mInstructions[i + 1]->mSrc[0] = mInstructions[i + 0]->mSrc[0];
mInstructions[i + 0]->mCode = IC_LEA;
mInstructions[i + 0]->mSrc[0] = mInstructions[i + 0]->mSrc[1];
mInstructions[i + 0]->mSrc[1] = mInstructions[i + 1]->mSrc[1];
mInstructions[i + 0]->mDst.mType = IT_POINTER;
mInstructions[i + 0]->mDst.mRange.Reset();
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mDst;
mInstructions[i + 1]->mSrc[1].mMemory = IM_INDIRECT;
changed = true;
}
#endif
else if ( 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 + 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]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i + 1]->mOperator == IA_EXT8TO16U &&
@ -10898,6 +10996,15 @@ void InterCodeProcedure::ResetVisited(void)
for (i = 0; i < mBlocks.Size(); i++) for (i = 0; i < mBlocks.Size(); i++)
{ {
#if _DEBUG
for (int j = 0; j < mBlocks[i]->mInstructions.Size(); j++)
{
InterInstruction* ins = mBlocks[i]->mInstructions[j];
assert(!ins || ins->mCode != IC_LOAD_TEMPORARY || ins->mSrc[0].mTemp >= 0);
}
#endif
#if 0 #if 0
if (mBlocks[i]->mInstructions.Size() > 0) if (mBlocks[i]->mInstructions.Size() > 0)
{ {
@ -11884,6 +11991,11 @@ void InterCodeProcedure::Close(void)
#endif #endif
#if 1
SimplifyIntegerNumeric(activeSet);
#endif
#if 1 #if 1
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
@ -12352,6 +12464,7 @@ void InterCodeProcedure::MapCallerSavedTemps(void)
} }
callerSavedTemps = freeCallerSavedTemps; callerSavedTemps = freeCallerSavedTemps;
mFreeCallerSavedTemps = freeCallerSavedTemps;
int maxCallerSavedTemps = mCallerSavedTemps; int maxCallerSavedTemps = mCallerSavedTemps;

View File

@ -508,7 +508,7 @@ public:
GrowingInterCodeBasicBlockPtrArray mBlocks; GrowingInterCodeBasicBlockPtrArray mBlocks;
GrowingTypeArray mTemporaries; GrowingTypeArray mTemporaries;
GrowingIntArray mTempOffset, mTempSizes; GrowingIntArray mTempOffset, mTempSizes;
int mTempSize, mCommonFrameSize, mCallerSavedTemps; int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps;
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure; bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure;
bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled; bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled;
GrowingInterCodeProcedurePtrArray mCalledFunctions; GrowingInterCodeProcedurePtrArray mCalledFunctions;

View File

@ -1642,6 +1642,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (ttype == IT_POINTER) if (ttype == IT_POINTER)
{ {
ains->mCode = IC_LEA; ains->mCode = IC_LEA;
ains->mSrc[1].mMemory = IM_INDIRECT;
} }
else else
{ {
@ -1702,6 +1703,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (ttype == IT_POINTER) if (ttype == IT_POINTER)
{ {
ains->mCode = IC_LEA; ains->mCode = IC_LEA;
ains->mSrc[1].mMemory = IM_INDIRECT;
} }
else else
{ {

View File

@ -6278,6 +6278,20 @@ void NativeCodeBasicBlock::ShiftRegisterLeftFromByte(InterCodeProcedure* proc, i
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
} }
else if (shift >= 5 && shift < 8 && (max << shift) >= 512)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LSR, ASMIM_IMPLIED));
for (int i = shift; i < 7; i++)
mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_TAX));
mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, (0xff << shift) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_TXA));
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, (0xff >> (8 - shift)) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
}
else else
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg));
@ -11158,6 +11172,13 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
{ {
yoffset = (yoffset - 1) & 255; yoffset = (yoffset - 1) & 255;
} }
else if (i + 1 < mIns.Size() && mIns[i].mType == ASMIT_TAY && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
{
i++;
yreg = mIns[i].mAddress;
yoffset = 0;
ypred = i;
}
else if (mIns[i].ChangesYReg()) else if (mIns[i].ChangesYReg())
{ {
if (full && yreg >= 0 && !mIns[i].RequiresYReg()) if (full && yreg >= 0 && !mIns[i].RequiresYReg())
@ -13738,7 +13759,7 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(const NativeCodeBasicBlock*
} }
else if (ins.mType == ASMIT_JSR) else if (ins.mType == ASMIT_JSR)
{ {
if (ains.mMode == ASMIM_ABSOLUTE_X || ains.mMode == ASMIM_ABSOLUTE_Y) if (ains.mMode == ASMIM_ABSOLUTE_X || ains.mMode == ASMIM_ABSOLUTE_Y || ains.mMode == ASMIM_INDIRECT_Y)
return false; return false;
else if (ins.mFlags & NCIF_RUNTIME) else if (ins.mFlags & NCIF_RUNTIME)
{ {
@ -13752,6 +13773,8 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(const NativeCodeBasicBlock*
return false; return false;
else if (ains.mMode == ASMIM_ABSOLUTE_Y && ins.ChangesYReg()) else if (ains.mMode == ASMIM_ABSOLUTE_Y && ins.ChangesYReg())
return false; return false;
else if (ains.mMode == ASMIM_INDIRECT_Y && (ins.ChangesYReg() || ins.ChangesZeroPage(ains.mAddress) || ins.ChangesZeroPage(ains.mAddress + 1)))
return false;
else if (ins.mMode == ASMIM_INDIRECT_Y && (ins.mAddress == reg || ins.mAddress + 1 == reg)) else if (ins.mMode == ASMIM_INDIRECT_Y && (ins.mAddress == reg || ins.mAddress + 1 == reg))
return false; return false;
else if (ins.ChangesZeroPage(reg)) else if (ins.ChangesZeroPage(reg))
@ -13801,7 +13824,7 @@ bool NativeCodeBasicBlock::PatchSingleUseGlobalLoad(const NativeCodeBasicBlock*
if (ains.mMode == ASMIM_ABSOLUTE_X) if (ains.mMode == ASMIM_ABSOLUTE_X)
ins.mLive |= LIVE_CPU_REG_X; ins.mLive |= LIVE_CPU_REG_X;
if (ains.mMode == ASMIM_ABSOLUTE_Y) if (ains.mMode == ASMIM_ABSOLUTE_Y || ains.mMode == ASMIM_INDIRECT_Y)
ins.mLive |= LIVE_CPU_REG_Y; ins.mLive |= LIVE_CPU_REG_Y;
at++; at++;
@ -23088,6 +23111,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED; mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
progress = true; progress = true;
} }
else if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y &&
mIns[i + 2].mType == ASMIT_LDY && mIns[i + 2].mMode == ASMIM_IMMEDIATE &&
mIns[i + 3].IsCommutative() && mIns[i + 3].mMode == ASMIM_INDIRECT_Y &&
mIns[i + 4].mType == ASMIT_LDY && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == mIns[i + 0].mAddress)
{
int addr = mIns[i + 1].mAddress;
mIns[i + 1].mAddress = mIns[i + 3].mAddress;
mIns[i + 3].mAddress = addr;
mIns[i + 0].mAddress = mIns[i + 2].mAddress;
mIns[i + 2].mAddress = mIns[i + 4].mAddress;
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
mIns[i + 3].mLive |= LIVE_CPU_REG_Y;
progress = true;
}
else if ( else if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y &&
@ -23305,7 +23344,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (i + 1 < mIns.Size()) if (i + 1 < mIns.Size())
{ {
if ( if (
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X || mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y) && mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X || mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y || mIns[i + 0].mMode == ASMIM_INDIRECT_Y) &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE) mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
{ {
int n = 3; int n = 3;
@ -23314,7 +23353,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) if (mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))
n--; n--;
if (n > 0) if (n > 0 && (mIns[i + 0].mMode != ASMIM_INDIRECT_Y || (mIns[i + 1].mAddress != mIns[i + 0].mAddress && mIns[i + 1].mAddress != mIns[i + 0].mAddress + 1)))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (CheckSingleUseGlobalLoad(this, mIns[i + 1].mAddress, i + 2, mIns[i], n)) if (CheckSingleUseGlobalLoad(this, mIns[i + 1].mAddress, i + 2, mIns[i], n))
@ -23327,7 +23366,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 0].mLive |= LIVE_CPU_REG_X; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mLive |= LIVE_CPU_REG_X; mIns[i + 1].mLive |= LIVE_CPU_REG_X;
} }
else if (mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y) else if (mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y || mIns[i + 0].mMode == ASMIM_INDIRECT_Y)
{ {
mIns[i + 0].mLive |= LIVE_CPU_REG_Y; mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mLive |= LIVE_CPU_REG_Y; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
@ -23615,7 +23654,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (mIns[i + 0].mType == ASMIT_CLC && if (mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_ADC && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) && mIns[i + 2].mType == ASMIT_ADC && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && /*mIns[i + 3].mAddress != mIns[i + 1].mAddress &&*/ mIns[i + 3].mAddress != mIns[i + 2].mAddress && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && /*mIns[i + 3].mAddress != mIns[i + 1].mAddress && mIns[i + 3].mAddress != mIns[i + 2].mAddress && */
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 1].mAddress + 1 && mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 1].mAddress + 1 &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 && mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
@ -23629,7 +23668,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 7, yval)) if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 2], i + 7, yval))
progress = true; progress = true;
if (mIns[i + 3].mAddress == mIns[i + 1].mAddress) if (mIns[i + 3].mAddress == mIns[i + 1].mAddress || mIns[i + 3].mAddress == mIns[i + 2].mAddress)
{ {
for (int j = 0; j < 7; j++) for (int j = 0; j < 7; j++)
{ {
@ -24494,16 +24533,18 @@ void NativeCodeProcedure::CompressTemporaries(void)
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
remap[i] = i; remap[i] = i;
int tpos = BC_REG_TMP_SAVED; int tpos = BC_REG_TMP + mInterProc->mFreeCallerSavedTemps;
if (mInterProc->mLeafProcedure) // BC_REG_TMP_SAVED;
tpos = BC_REG_TMP; // if (mInterProc->mLeafProcedure)
// tpos = BC_REG_TMP;
for (int i = 0; i < mInterProc->mTempOffset.Size(); i++) for (int i = 0; i < mInterProc->mTempOffset.Size(); i++)
{ {
bool tused = false; bool tused = false;
int reg = BC_REG_TMP + mInterProc->mTempOffset[i]; int reg = BC_REG_TMP + mInterProc->mTempOffset[i];
if (mInterProc->mLeafProcedure || reg >= BC_REG_TMP_SAVED) // if (mInterProc->mLeafProcedure || reg >= BC_REG_TMP_SAVED)
if (reg >= BC_REG_TMP + mInterProc->mFreeCallerSavedTemps)
{ {
int size = mInterProc->mTempSizes[i]; int size = mInterProc->mTempSizes[i];
int usize = 0; int usize = 0;
@ -25145,7 +25186,6 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
#endif #endif
#if 1 #if 1
if (step < 6) if (step < 6)
{ {
@ -25700,7 +25740,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
} }
else if (i + 1 < iblock->mInstructions.Size() && else if (i + 1 < iblock->mInstructions.Size() &&
iblock->mInstructions[i + 1]->mCode == IC_STORE && iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal && iblock->mInstructions[i + 1]->mCode == IC_STORE && iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal &&
iblock->mInstructions[i + 0]->mSrc[1].mTemp >= 0 && iblock->mInstructions[i + 0]->mSrc[0].IsUByte() && ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].IsUByte() && ins->mSrc[0].mTemp >= 0 &&
iblock->mInstructions[i + 1]->mSrc[1].mIntConst == 0 && iblock->mInstructions[i + 1]->mSrc[0].mTemp >= 0) iblock->mInstructions[i + 1]->mSrc[1].mIntConst == 0 && iblock->mInstructions[i + 1]->mSrc[0].mTemp >= 0)
{ {
block->StoreByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]); block->StoreByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);

View File

@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
#else #else
strcpy(strProductName, "oscar64"); strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.7.137"); strcpy(strProductVersion, "1.7.138");
#ifdef __APPLE__ #ifdef __APPLE__
uint32_t length = sizeof(basePath); uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,7,137,0 FILEVERSION 1,7,138,0
PRODUCTVERSION 1,7,137,0 PRODUCTVERSION 1,7,138,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "oscar64" VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler" VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.7.137.0" VALUE "FileVersion", "1.7.138.0"
VALUE "InternalName", "oscar64.exe" VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe" VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64" VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.7.137.0" VALUE "ProductVersion", "1.7.138.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -4127,15 +4127,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{FD2A310E-C047-46DB-BC3A-E4704ECC3697}" "ProductCode" = "8:{E214603B-3BF1-4E04-B292-06713A9F4416}"
"PackageCode" = "8:{C415E608-4EAB-4BF9-9990-83BC094DFF07}" "PackageCode" = "8:{7DE71653-0886-4676-BB6F-04F6F2CF8206}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0" "AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE" "RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE" "InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.7.137" "ProductVersion" = "8:1.7.138"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"

Binary file not shown.