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;
}
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)
{
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)
{
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))
{
return
@ -3299,6 +3312,7 @@ bool InterInstruction::ConstantFolding(void)
mSrc[0] = mSrc[1];
mSrc[1].mTemp = -1;
mNumOperands = 1;
assert(mSrc[0].mTemp >= 0);
return true;
}
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;
mSrc[1].mTemp = -1;
mNumOperands = 1;
assert(mSrc[0].mTemp >= 0);
return true;
}
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;
mConst = mSrc[1];
mConst.mIntConst += mSrc[0].mIntConst;
mConst.mRange.Reset();
mNumOperands = 0;
return true;
}
@ -3391,6 +3407,7 @@ bool InterInstruction::ConstantFolding(void)
mSrc[0] = mSrc[1];
mSrc[1].mTemp = -1;
mNumOperands = 1;
assert(mSrc[0].mTemp >= 0);
return true;
}
break;
@ -5113,21 +5130,24 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
for (int i = 0; i < ins->mNumOperands; i++)
{
if (ins->mSrc[i].mTemp >= 0)
if (IsIntegerType(ins->mSrc[i].mType) || ins->mSrc[i].mType == IT_BOOL)
{
ins->mSrc[i].mRange = mLocalValueRange[ins->mSrc[i].mTemp];
#if 1
if (ins->mSrc[i].mRange.mMinState == IntegerValueRange::S_BOUND && ins->mSrc[i].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[i].mRange.mMinValue == ins->mSrc[i].mRange.mMaxValue)
if (ins->mSrc[i].mTemp >= 0)
{
ins->mSrc[i].mTemp = -1;
ins->mSrc[i].mIntConst = ins->mSrc[i].mRange.mMinValue;
}
ins->mSrc[i].mRange = mLocalValueRange[ins->mSrc[i].mTemp];
#if 1
if (ins->mSrc[i].mRange.mMinState == IntegerValueRange::S_BOUND && ins->mSrc[i].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[i].mRange.mMinValue == ins->mSrc[i].mRange.mMaxValue)
{
ins->mSrc[i].mTemp = -1;
ins->mSrc[i].mIntConst = ins->mSrc[i].mRange.mMinValue;
}
#endif
}
else if (IsIntegerType(ins->mSrc[i].mType))
{
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;
}
else
{
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;
}
}
}
@ -6247,6 +6267,7 @@ bool InterCodeBasicBlock::SingleAssignmentTempForwarding(const GrowingInstructio
ins->mSrc[0].mTemp = ntvalues[j]->mDst.mTemp;
ins->mSrc[0].mType = ntvalues[j]->mDst.mType;
ins->mNumOperands = 1;
assert(ins->mSrc[0].mTemp >= 0);
}
changed = true;
ntunified[ins->mDst.mTemp] = ntvalues[j];
@ -7065,6 +7086,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
{
ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0].mType = IT_INT16;
assert(ins->mSrc[0].mTemp >= 0);
changed = true;
}
}
@ -7074,12 +7096,29 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
{
ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0].mType = IT_INT16;
assert(ins->mSrc[0].mTemp >= 0);
changed = true;
}
}
break;
#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
@ -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))
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
mLoadStoreInstructions.SetSize(0);
@ -7668,6 +7736,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mDst;
ins->mNumOperands = 1;
assert(ins->mSrc[0].mTemp >= 0);
changed = true;
}
else if (lins->mCode == IC_STORE)
@ -7683,6 +7752,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mSrc[0];
ins->mNumOperands = 1;
assert(ins->mSrc[0].mTemp >= 0);
changed = true;
}
}
@ -7729,6 +7799,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
if (j < mLoadStoreInstructions.Size())
{
InterInstruction* lins = mLoadStoreInstructions[j];
assert(lins->mDst.mTemp >= 0);
ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mDst;
ins->mNumOperands = 1;
@ -8117,6 +8188,7 @@ bool InterCodeBasicBlock::MergeCommonPathInstructions(void)
nins->mDst.mType = fins->mDst.mType;
nins->mSrc[0].mTemp = tins->mDst.mTemp;
nins->mSrc[0].mType = tins->mDst.mType;
assert(nins->mSrc[0].mTemp >= 0);
mInstructions.Insert(tindex, nins);
}
}
@ -8240,6 +8312,7 @@ bool InterCodeBasicBlock::ForwardDiamondMovedTemp(void)
nins->mDst.mType = mins->mDst.mType;
nins->mSrc[0].mTemp = stemp;
nins->mSrc[0].mType = mins->mDst.mType;
assert(nins->mSrc[0].mTemp >= 0);
fblock->mInstructions.Insert(0, nins);
tblock->mExitRequiredTemps += stemp;
@ -9413,6 +9486,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
nins->mSrc[0].Forward(sins->mSrc[0]);
ins->mDst.Forward(sins->mSrc[0]);
sins->mSrc[0].mFinal = false;
assert(nins->mSrc[0].mTemp >= 0);
// Move store behind loop
if (mTrueJump == this)
@ -10366,6 +10440,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
mInstructions[i + 0]->mCode = IC_LOAD_TEMPORARY;
mInstructions[i + 0]->mSrc[0] = mInstructions[i + 0]->mSrc[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 + 2]->mSrc[0].mIntConst >>= shift;
@ -10428,8 +10503,11 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
mInstructions[i + 0]->mCode = IC_LEA;
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;
}
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[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;
}
#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 (
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 &&
@ -10898,6 +10996,15 @@ void InterCodeProcedure::ResetVisited(void)
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 (mBlocks[i]->mInstructions.Size() > 0)
{
@ -11884,6 +11991,11 @@ void InterCodeProcedure::Close(void)
#endif
#if 1
SimplifyIntegerNumeric(activeSet);
#endif
#if 1
for (int i = 0; i < 4; i++)
{
@ -12352,6 +12464,7 @@ void InterCodeProcedure::MapCallerSavedTemps(void)
}
callerSavedTemps = freeCallerSavedTemps;
mFreeCallerSavedTemps = freeCallerSavedTemps;
int maxCallerSavedTemps = mCallerSavedTemps;

View File

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

View File

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

View File

@ -6278,6 +6278,20 @@ void NativeCodeBasicBlock::ShiftRegisterLeftFromByte(InterCodeProcedure* proc, i
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
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
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg));
@ -11158,6 +11172,13 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
{
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())
{
if (full && yreg >= 0 && !mIns[i].RequiresYReg())
@ -13738,7 +13759,7 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(const NativeCodeBasicBlock*
}
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;
else if (ins.mFlags & NCIF_RUNTIME)
{
@ -13752,6 +13773,8 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(const NativeCodeBasicBlock*
return false;
else if (ains.mMode == ASMIM_ABSOLUTE_Y && ins.ChangesYReg())
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))
return false;
else if (ins.ChangesZeroPage(reg))
@ -13801,7 +13824,7 @@ bool NativeCodeBasicBlock::PatchSingleUseGlobalLoad(const NativeCodeBasicBlock*
if (ains.mMode == ASMIM_ABSOLUTE_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;
at++;
@ -23088,6 +23111,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
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 (
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 &&
@ -23305,7 +23344,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (i + 1 < mIns.Size())
{
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)
{
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))
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();
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 + 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 + 1].mLive |= LIVE_CPU_REG_Y;
@ -23615,7 +23654,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (mIns[i + 0].mType == ASMIT_CLC &&
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 + 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 + 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 &&
@ -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))
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++)
{
@ -24494,16 +24533,18 @@ void NativeCodeProcedure::CompressTemporaries(void)
for (int i = 0; i < 256; i++)
remap[i] = i;
int tpos = BC_REG_TMP_SAVED;
if (mInterProc->mLeafProcedure)
tpos = BC_REG_TMP;
int tpos = BC_REG_TMP + mInterProc->mFreeCallerSavedTemps;
// BC_REG_TMP_SAVED;
// if (mInterProc->mLeafProcedure)
// tpos = BC_REG_TMP;
for (int i = 0; i < mInterProc->mTempOffset.Size(); i++)
{
bool tused = false;
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 usize = 0;
@ -25145,7 +25186,6 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
#endif
#if 1
if (step < 6)
{
@ -25700,7 +25740,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
}
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 + 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)
{
block->StoreByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);

View File

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

View File

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

View File

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

Binary file not shown.