Restart integer range estimation from full state
This commit is contained in:
parent
ecf8e69cf2
commit
9156db9c32
|
@ -45,6 +45,14 @@ void IntegerValueRange::Reset(void)
|
||||||
mMaxExpanded = 0;
|
mMaxExpanded = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntegerValueRange::Restart(void)
|
||||||
|
{
|
||||||
|
if (mMinState == IntegerValueRange::S_UNBOUND)
|
||||||
|
mMinState = IntegerValueRange::S_UNKNOWN;
|
||||||
|
if (mMaxState == IntegerValueRange::S_UNBOUND)
|
||||||
|
mMaxState = IntegerValueRange::S_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IntegerValueRange::Same(const IntegerValueRange& range) const
|
bool IntegerValueRange::Same(const IntegerValueRange& range) const
|
||||||
{
|
{
|
||||||
|
@ -115,6 +123,26 @@ bool IntegerValueRange::IsConstant(void) const
|
||||||
return mMinState == S_BOUND && mMaxState == S_BOUND && mMinValue == mMaxValue;
|
return mMinState == S_BOUND && mMaxState == S_BOUND && mMinValue == mMaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntegerValueRange::MergeUnknown(const IntegerValueRange& range)
|
||||||
|
{
|
||||||
|
if (mMinState != S_BOUND)
|
||||||
|
{
|
||||||
|
mMinState = range.mMinState;
|
||||||
|
mMinValue = range.mMinValue;
|
||||||
|
}
|
||||||
|
else if (range.mMinState == S_BOUND && mMinValue < range.mMinValue)
|
||||||
|
mMinValue = range.mMinValue;
|
||||||
|
|
||||||
|
if (mMaxState != S_BOUND)
|
||||||
|
{
|
||||||
|
mMaxState = range.mMaxState;
|
||||||
|
mMaxValue = range.mMaxValue;
|
||||||
|
}
|
||||||
|
else if (range.mMaxState == S_BOUND && mMaxValue > range.mMaxValue)
|
||||||
|
mMaxValue = range.mMaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void IntegerValueRange::Limit(const IntegerValueRange& range)
|
void IntegerValueRange::Limit(const IntegerValueRange& range)
|
||||||
{
|
{
|
||||||
if (range.mMinState == S_BOUND)
|
if (range.mMinState == S_BOUND)
|
||||||
|
@ -160,6 +188,30 @@ void IntegerValueRange::Expand(const IntegerValueRange& range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntegerValueRange::Union(const IntegerValueRange& range)
|
||||||
|
{
|
||||||
|
if (range.mMinState == S_UNBOUND || mMinState == S_UNBOUND)
|
||||||
|
mMinState = S_UNBOUND;
|
||||||
|
else if (range.mMinState == S_UNKNOWN || mMinState == S_UNKNOWN)
|
||||||
|
mMinState = S_UNKNOWN;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMinValue = int64min(mMinValue, range.mMinValue);
|
||||||
|
if (range.mMinState == S_WEAK)
|
||||||
|
mMinState = S_WEAK;
|
||||||
|
}
|
||||||
|
if (range.mMaxState == S_UNBOUND || mMaxState == S_UNBOUND)
|
||||||
|
mMaxState = S_UNBOUND;
|
||||||
|
else if (range.mMaxState == S_UNKNOWN || mMaxState == S_UNKNOWN)
|
||||||
|
mMaxState = S_UNKNOWN;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMaxValue = int64max(mMaxValue, range.mMaxValue);
|
||||||
|
if (range.mMaxState == S_WEAK)
|
||||||
|
mMaxState = S_WEAK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IntegerValueRange::Merge(const IntegerValueRange& range, bool head, bool initial)
|
bool IntegerValueRange::Merge(const IntegerValueRange& range, bool head, bool initial)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -3231,6 +3283,44 @@ void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticV
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterInstruction::FilterStaticVarsByteUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars)
|
||||||
|
{
|
||||||
|
if (mCode == IC_LOAD)
|
||||||
|
{
|
||||||
|
if (mSrc[0].mMemory == IM_INDIRECT)
|
||||||
|
{
|
||||||
|
if (!mSrc[0].mRestricted)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < staticVars.Size(); i++)
|
||||||
|
{
|
||||||
|
if (staticVars[i]->mAliased && !providedVars[i])
|
||||||
|
requiredVars.AddRange(staticVars[i]->mByteIndex, staticVars[i]->mSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mSrc[0].mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
if (mSrc[0].mVarIndex >= 0 && !providedVars.RangeFilled(staticVars[mSrc[0].mVarIndex]->mByteIndex + int(mSrc[0].mIntConst), InterTypeSize[mDst.mType]))
|
||||||
|
requiredVars.AddRange(staticVars[mSrc[0].mVarIndex]->mByteIndex + int(mSrc[0].mIntConst), InterTypeSize[mDst.mType]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mCode == IC_STORE)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mMemory == IM_INDIRECT)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (mSrc[1].mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mVarIndex >= 0)
|
||||||
|
providedVars.AddRange(staticVars[mSrc[1].mVarIndex]->mByteIndex + int(mSrc[1].mIntConst), InterTypeSize[mSrc[0].mType]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_STRCPY || mCode == IC_DISPATCH)
|
||||||
|
{
|
||||||
|
requiredVars.OrNot(providedVars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory)
|
void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory)
|
||||||
{
|
{
|
||||||
if (mCode == IC_LOAD)
|
if (mCode == IC_LOAD)
|
||||||
|
@ -3878,6 +3968,57 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock*
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterInstruction::RemoveUnusedStaticStoreByteInstructions(InterCodeBasicBlock* block, const GrowingVariableArray& staticVars, NumberSet& requiredVars)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (mCode == IC_LOAD)
|
||||||
|
{
|
||||||
|
if (mSrc[0].mMemory == IM_INDIRECT)
|
||||||
|
{
|
||||||
|
if (!mSrc[0].mRestricted)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < staticVars.Size(); i++)
|
||||||
|
{
|
||||||
|
if (staticVars[i]->mAliased)
|
||||||
|
requiredVars.AddRange(staticVars[i]->mByteIndex, staticVars[i]->mSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mSrc[0].mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
if (mSrc[0].mVarIndex >= 0)
|
||||||
|
requiredVars.AddRange(staticVars[mSrc[0].mVarIndex]->mByteIndex + int(mSrc[0].mIntConst), InterTypeSize[mDst.mType]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mCode == IC_STORE)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mMemory == IM_GLOBAL && mSrc[1].mVarIndex >= 0)
|
||||||
|
{
|
||||||
|
if (!requiredVars.RangeClear(staticVars[mSrc[1].mVarIndex]->mByteIndex + int(mSrc[1].mIntConst), InterTypeSize[mSrc[0].mType]))
|
||||||
|
{
|
||||||
|
requiredVars.SubRange(staticVars[mSrc[1].mVarIndex]->mByteIndex + int(mSrc[1].mIntConst), InterTypeSize[mSrc[0].mType]);
|
||||||
|
}
|
||||||
|
else if (!mVolatile)
|
||||||
|
{
|
||||||
|
mSrc[0].mTemp = -1;
|
||||||
|
mCode = IC_NONE;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mCode == IC_COPY || mCode == IC_STRCPY)
|
||||||
|
{
|
||||||
|
requiredVars.Fill();
|
||||||
|
}
|
||||||
|
else if (mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_DISPATCH)
|
||||||
|
{
|
||||||
|
requiredVars.Fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
int InterInstruction::NumUsedTemps(void) const
|
int InterInstruction::NumUsedTemps(void) const
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
@ -4112,6 +4253,13 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterInstruction::UnionRanges(InterInstruction* ins)
|
||||||
|
{
|
||||||
|
mDst.mRange.Union(ins->mDst.mRange);
|
||||||
|
for(int i=0; i<mNumOperands; i++)
|
||||||
|
mSrc[i].mRange.Union(ins->mSrc[i].mRange);
|
||||||
|
}
|
||||||
|
|
||||||
void InterInstruction::SimpleLocalToTemp(int vindex, int temp)
|
void InterInstruction::SimpleLocalToTemp(int vindex, int temp)
|
||||||
{
|
{
|
||||||
switch (mCode)
|
switch (mCode)
|
||||||
|
@ -4644,7 +4792,7 @@ InterCodeBasicBlock::InterCodeBasicBlock(InterCodeProcedure * proc)
|
||||||
mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mMergeAValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr),
|
mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mMergeAValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr),
|
||||||
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()),
|
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()),
|
||||||
mEntryParamValueRange(IntegerValueRange()), mTrueParamValueRange(IntegerValueRange()), mFalseParamValueRange(IntegerValueRange()), mLocalParamValueRange(IntegerValueRange()),
|
mEntryParamValueRange(IntegerValueRange()), mTrueParamValueRange(IntegerValueRange()), mFalseParamValueRange(IntegerValueRange()), mLocalParamValueRange(IntegerValueRange()),
|
||||||
mReverseValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr), mLoopPathBlocks(nullptr), mMemoryValueSize(0), mEntryMemoryValueSize(0)
|
mReverseValueRange(IntegerValueRange()), mLoadStoreInstructions(nullptr), mMemoryValueSize(0), mEntryMemoryValueSize(0)
|
||||||
{
|
{
|
||||||
mVisited = false;
|
mVisited = false;
|
||||||
mInPath = false;
|
mInPath = false;
|
||||||
|
@ -4816,6 +4964,8 @@ void InterCodeBasicBlock::GenerateTraces(bool expand, bool compact)
|
||||||
if (mInPath)
|
if (mInPath)
|
||||||
mLoopHead = true;
|
mLoopHead = true;
|
||||||
|
|
||||||
|
assert(mIndex != 0 || !mLoopHead);
|
||||||
|
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
{
|
{
|
||||||
mVisited = true;
|
mVisited = true;
|
||||||
|
@ -6559,6 +6709,29 @@ static int64 BuildLowerBitsMask(int64 v)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::UnionIntegerRanges(const InterCodeBasicBlock* block)
|
||||||
|
{
|
||||||
|
if (mEntryValueRange.Size() > 0)
|
||||||
|
{
|
||||||
|
if (block->mEntryValueRange.Size())
|
||||||
|
{
|
||||||
|
assert(mEntryValueRange.Size() == block->mEntryValueRange.Size());
|
||||||
|
|
||||||
|
for (int i = 0; i < mEntryValueRange.Size(); i++)
|
||||||
|
mEntryValueRange[i].Union(block->mEntryValueRange[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mEntryValueRange.SetSize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
|
{
|
||||||
|
assert(mInstructions[i]->IsEqual(block->mInstructions[i]));
|
||||||
|
mInstructions[i]->UnionRanges(block->mInstructions[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::MarkIntegerRangeBoundUp(int temp, int64 value, GrowingIntegerValueRangeArray& range)
|
void InterCodeBasicBlock::MarkIntegerRangeBoundUp(int temp, int64 value, GrowingIntegerValueRangeArray& range)
|
||||||
{
|
{
|
||||||
range[temp].SetLimit(value, value);
|
range[temp].SetLimit(value, value);
|
||||||
|
@ -6675,7 +6848,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
||||||
{
|
{
|
||||||
if (ins->mSrc[i].mTemp >= 0)
|
if (ins->mSrc[i].mTemp >= 0)
|
||||||
{
|
{
|
||||||
ins->mSrc[i].mRange = mLocalValueRange[ins->mSrc[i].mTemp];
|
ins->mSrc[i].mRange.MergeUnknown(mLocalValueRange[ins->mSrc[i].mTemp]);
|
||||||
#if 1
|
#if 1
|
||||||
if (ins->mCode != IC_ASSEMBLER&& 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->mCode != IC_ASSEMBLER&& 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)
|
||||||
{
|
{
|
||||||
|
@ -7324,7 +7497,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
||||||
vr.LimitMaxBound(65535);
|
vr.LimitMaxBound(65535);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ins->mDst.mRange = vr;
|
ins->mDst.mRange.MergeUnknown(vr);
|
||||||
#if 1
|
#if 1
|
||||||
if (vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMinState == IntegerValueRange::S_BOUND && vr.mMaxValue == vr.mMinValue)
|
if (vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMinState == IntegerValueRange::S_BOUND && vr.mMaxValue == vr.mMinValue)
|
||||||
{
|
{
|
||||||
|
@ -7850,21 +8023,16 @@ void InterCodeBasicBlock::RestartLocalIntegerRangeSets(int num, const GrowingVar
|
||||||
mLocalParamValueRange.SetSize(paramVars.Size(), false);
|
mLocalParamValueRange.SetSize(paramVars.Size(), false);
|
||||||
|
|
||||||
for (int i = 0; i < mEntryValueRange.Size(); i++)
|
for (int i = 0; i < mEntryValueRange.Size(); i++)
|
||||||
{
|
mEntryValueRange[i].Restart();
|
||||||
IntegerValueRange& vr(mEntryValueRange[i]);
|
|
||||||
if (vr.mMinState == IntegerValueRange::S_UNBOUND)
|
|
||||||
vr.mMinState = IntegerValueRange::S_UNKNOWN;
|
|
||||||
if (vr.mMaxState == IntegerValueRange::S_UNBOUND)
|
|
||||||
vr.mMaxState = IntegerValueRange::S_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < mEntryParamValueRange.Size(); i++)
|
for (int i = 0; i < mEntryParamValueRange.Size(); i++)
|
||||||
|
mEntryParamValueRange[i].Restart();
|
||||||
|
|
||||||
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
{
|
{
|
||||||
IntegerValueRange& vr(mEntryParamValueRange[i]);
|
mInstructions[i]->mDst.mRange.Restart();
|
||||||
if (vr.mMinState == IntegerValueRange::S_UNBOUND)
|
for (int j = 0; j < mInstructions[i]->mNumOperands; j++)
|
||||||
vr.mMinState = IntegerValueRange::S_UNKNOWN;
|
mInstructions[i]->mSrc[j].mRange.Restart();
|
||||||
if (vr.mMaxState == IntegerValueRange::S_UNBOUND)
|
|
||||||
vr.mMaxState = IntegerValueRange::S_UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateLocalIntegerRangeSets(localVars, paramVars);
|
UpdateLocalIntegerRangeSets(localVars, paramVars);
|
||||||
|
@ -8335,7 +8503,7 @@ void InterCodeBasicBlock::PerformTempForwarding(const TempForwardingTable& forwa
|
||||||
}
|
}
|
||||||
else if (mLoopPrefix && checkloops)
|
else if (mLoopPrefix && checkloops)
|
||||||
{
|
{
|
||||||
GrowingArray<InterCodeBasicBlock*> body(nullptr);
|
ExpandingArray<InterCodeBasicBlock*> body;
|
||||||
body.Push(this);
|
body.Push(this);
|
||||||
bool innerLoop = true;
|
bool innerLoop = true;
|
||||||
|
|
||||||
|
@ -8619,6 +8787,67 @@ bool InterCodeBasicBlock::RemoveUnusedStaticStoreInstructions(const GrowingVaria
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::BuildStaticVariableByteSet(const GrowingVariableArray& staticVars, int bsize)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
mLocalRequiredStatics = NumberSet(bsize);
|
||||||
|
mLocalProvidedStatics = NumberSet(bsize);
|
||||||
|
|
||||||
|
mEntryRequiredStatics = NumberSet(bsize);
|
||||||
|
mEntryProvidedStatics = NumberSet(bsize);
|
||||||
|
mExitRequiredStatics = NumberSet(bsize);
|
||||||
|
mExitProvidedStatics = NumberSet(bsize);
|
||||||
|
|
||||||
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
|
mInstructions[i]->FilterStaticVarsByteUsage(staticVars, mLocalRequiredStatics, mLocalProvidedStatics);
|
||||||
|
|
||||||
|
mEntryRequiredStatics = mLocalRequiredStatics;
|
||||||
|
mExitProvidedStatics = mLocalProvidedStatics;
|
||||||
|
|
||||||
|
if (mTrueJump) mTrueJump->BuildStaticVariableByteSet(staticVars, bsize);
|
||||||
|
if (mFalseJump) mFalseJump->BuildStaticVariableByteSet(staticVars, bsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::RemoveUnusedStaticStoreByteInstructions(const GrowingVariableArray& staticVars, int bsize)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
NumberSet requiredVars(mExitRequiredStatics);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = mInstructions.Size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (mInstructions[i]->RemoveUnusedStaticStoreByteInstructions(this, staticVars, requiredVars))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump)
|
||||||
|
{
|
||||||
|
if (mTrueJump->RemoveUnusedStaticStoreByteInstructions(staticVars, bsize))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (mFalseJump)
|
||||||
|
{
|
||||||
|
if (mFalseJump->RemoveUnusedStaticStoreByteInstructions(staticVars, bsize))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void InterCodeBasicBlock::BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory)
|
void InterCodeBasicBlock::BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -11145,7 +11374,7 @@ bool InterCodeBasicBlock::ForwardLoopMovedTemp(void)
|
||||||
else if (mTrueJump->mFalseJump == mTrueJump)
|
else if (mTrueJump->mFalseJump == mTrueJump)
|
||||||
eblock = mTrueJump->mTrueJump;
|
eblock = mTrueJump->mTrueJump;
|
||||||
|
|
||||||
if (eblock)
|
if (eblock && eblock->mNumEntries == 1)
|
||||||
{
|
{
|
||||||
int i = mInstructions.Size() - 1;
|
int i = mInstructions.Size() - 1;
|
||||||
while (i >= 0)
|
while (i >= 0)
|
||||||
|
@ -12277,7 +12506,7 @@ InterCodeBasicBlock* InterCodeBasicBlock::BuildLoopPrefix(void)
|
||||||
return mLoopPrefix ? mLoopPrefix : this;
|
return mLoopPrefix ? mLoopPrefix : this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InterCodeBasicBlock::CollectLoopBody(InterCodeBasicBlock* head, GrowingArray<InterCodeBasicBlock*> & body)
|
bool InterCodeBasicBlock::CollectLoopBody(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*> & body)
|
||||||
{
|
{
|
||||||
if (mLoopHead)
|
if (mLoopHead)
|
||||||
return this == head;
|
return this == head;
|
||||||
|
@ -12293,7 +12522,7 @@ bool InterCodeBasicBlock::CollectLoopBody(InterCodeBasicBlock* head, GrowingArra
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InterCodeBasicBlock::CollectLoopBodyRecursive(InterCodeBasicBlock* head, GrowingArray<InterCodeBasicBlock*>& body)
|
bool InterCodeBasicBlock::CollectLoopBodyRecursive(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*>& body)
|
||||||
{
|
{
|
||||||
if (this == head)
|
if (this == head)
|
||||||
return true;
|
return true;
|
||||||
|
@ -12309,7 +12538,7 @@ bool InterCodeBasicBlock::CollectLoopBodyRecursive(InterCodeBasicBlock* head, Gr
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::CollectLoopPath(const GrowingArray<InterCodeBasicBlock*>& body, GrowingArray<InterCodeBasicBlock*>& path)
|
void InterCodeBasicBlock::CollectLoopPath(const ExpandingArray<InterCodeBasicBlock*>& body, ExpandingArray<InterCodeBasicBlock*>& path)
|
||||||
{
|
{
|
||||||
if (body.IndexOf(this) >= 0)
|
if (body.IndexOf(this) >= 0)
|
||||||
{
|
{
|
||||||
|
@ -12320,7 +12549,7 @@ void InterCodeBasicBlock::CollectLoopPath(const GrowingArray<InterCodeBasicBlock
|
||||||
mTrueJump->CollectLoopPath(body, mLoopPathBlocks);
|
mTrueJump->CollectLoopPath(body, mLoopPathBlocks);
|
||||||
if (mFalseJump)
|
if (mFalseJump)
|
||||||
{
|
{
|
||||||
GrowingArray<InterCodeBasicBlock*> fpath(nullptr);
|
ExpandingArray<InterCodeBasicBlock*> fpath;
|
||||||
|
|
||||||
if (!mFalseJump->mLoopHead)
|
if (!mFalseJump->mLoopHead)
|
||||||
mFalseJump->CollectLoopPath(body, fpath);
|
mFalseJump->CollectLoopPath(body, fpath);
|
||||||
|
@ -12526,8 +12755,12 @@ bool InterCodeBasicBlock::SingleTailLoopOptimization(const NumberSet& aliasedPar
|
||||||
mins->mConst.mType = ai->mDst.mType;
|
mins->mConst.mType = ai->mDst.mType;
|
||||||
mins->mConst.mIntConst = num;
|
mins->mConst.mIntConst = num;
|
||||||
mins->mDst = ai->mDst;
|
mins->mDst = ai->mDst;
|
||||||
|
mins->mDst.mRange.SetLimit(num, num);
|
||||||
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, mins);
|
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, mins);
|
||||||
|
|
||||||
|
if (mEntryValueRange.Size())
|
||||||
|
mEntryValueRange[ai->mSrc[1].mTemp].SetLimit(1, num);
|
||||||
|
|
||||||
ai->mSrc[1].mRange.SetLimit(1, num);
|
ai->mSrc[1].mRange.SetLimit(1, num);
|
||||||
ai->mDst.mRange.SetLimit(0, num - 1);
|
ai->mDst.mRange.SetLimit(0, num - 1);
|
||||||
ci->mSrc[1].mRange.SetLimit(0, num - 1);
|
ci->mSrc[1].mRange.SetLimit(0, num - 1);
|
||||||
|
@ -12731,7 +12964,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
|
||||||
|
|
||||||
if (mLoopHead)
|
if (mLoopHead)
|
||||||
{
|
{
|
||||||
GrowingArray<InterCodeBasicBlock*> body(nullptr), path(nullptr);
|
ExpandingArray<InterCodeBasicBlock*> body, path;
|
||||||
body.Push(this);
|
body.Push(this);
|
||||||
bool innerLoop = true;
|
bool innerLoop = true;
|
||||||
|
|
||||||
|
@ -13541,7 +13774,7 @@ void InterCodeBasicBlock::PushMoveOutOfLoop(void)
|
||||||
|
|
||||||
bool InterCodeBasicBlock::CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pblock, int64& nloop)
|
bool InterCodeBasicBlock::CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pblock, int64& nloop)
|
||||||
{
|
{
|
||||||
if (mLoopHead && mNumEntries == 2 && mFalseJump && (mTrueJump == this || mFalseJump == this) && mInstructions.Size() > 3)
|
if (mLoopHead && mEntryBlocks.Size() == 2 && mFalseJump && (mTrueJump == this || mFalseJump == this) && mInstructions.Size() > 3)
|
||||||
{
|
{
|
||||||
int nins = mInstructions.Size();
|
int nins = mInstructions.Size();
|
||||||
|
|
||||||
|
@ -14858,6 +15091,9 @@ void InterCodeBasicBlock::CheckBlocks(void)
|
||||||
for (int i = 0; i < mInstructions.Size(); i++)
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
assert(mInstructions[i] != nullptr);
|
assert(mInstructions[i] != nullptr);
|
||||||
|
|
||||||
|
assert(!mTrueJump || mTrueJump->mIndex > 0);
|
||||||
|
assert(!mFalseJump || mFalseJump->mIndex > 0);
|
||||||
|
|
||||||
if (mTrueJump) mTrueJump->CheckBlocks();
|
if (mTrueJump) mTrueJump->CheckBlocks();
|
||||||
if (mFalseJump) mFalseJump->CheckBlocks();
|
if (mFalseJump) mFalseJump->CheckBlocks();
|
||||||
}
|
}
|
||||||
|
@ -17163,6 +17399,43 @@ void InterCodeProcedure::RemoveUnusedLocalStoreInstructions(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeProcedure::RemoveUnusedPartialStoreInstructions(void)
|
||||||
|
{
|
||||||
|
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
|
||||||
|
{
|
||||||
|
if (mModule->mGlobalVars.Size())
|
||||||
|
{
|
||||||
|
int byteIndex = 0;
|
||||||
|
for (int i = 0; i < mModule->mGlobalVars.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mModule->mGlobalVars[i])
|
||||||
|
{
|
||||||
|
mModule->mGlobalVars[i]->mByteIndex = byteIndex;
|
||||||
|
byteIndex += mModule->mGlobalVars[i]->mSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->BuildStaticVariableByteSet(mModule->mGlobalVars, byteIndex);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->BuildGlobalProvidedStaticVariableSet(mModule->mGlobalVars, NumberSet(byteIndex));
|
||||||
|
|
||||||
|
NumberSet totalRequired2(byteIndex);
|
||||||
|
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->BuildGlobalRequiredStaticVariableSet(mModule->mGlobalVars, totalRequired2));
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->RemoveUnusedStaticStoreByteInstructions(mModule->mGlobalVars, byteIndex));
|
||||||
|
|
||||||
|
DisassembleDebug("removed unused static byte stores");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::RemoveUnusedStoreInstructions(InterMemory paramMemory)
|
void InterCodeProcedure::RemoveUnusedStoreInstructions(InterMemory paramMemory)
|
||||||
{
|
{
|
||||||
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
|
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
|
||||||
|
@ -17652,7 +17925,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "atoi");
|
CheckFunc = !strcmp(mIdent->mString, "ftoa");
|
||||||
CheckCase = false;
|
CheckCase = false;
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
@ -18136,6 +18409,8 @@ void InterCodeProcedure::Close(void)
|
||||||
Disassemble("gcp-");
|
Disassemble("gcp-");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CheckCase = true;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
RebuildIntegerRangeSet();
|
RebuildIntegerRangeSet();
|
||||||
#endif
|
#endif
|
||||||
|
@ -18349,17 +18624,27 @@ void InterCodeProcedure::Close(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DisassembleDebug("PreLoopTemp");
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->ForwardLoopMovedTemp();
|
mEntryBlock->ForwardLoopMovedTemp();
|
||||||
|
DisassembleDebug("PostLoopTemp");
|
||||||
|
|
||||||
|
CheckFinal();
|
||||||
|
DisassembleDebug("PreConstP");
|
||||||
#if 1
|
#if 1
|
||||||
do {
|
do {
|
||||||
|
DisassembleDebug("InConstP");
|
||||||
|
CheckFinal();
|
||||||
TempForwarding();
|
TempForwarding();
|
||||||
|
CheckFinal();
|
||||||
} while (GlobalConstantPropagation());
|
} while (GlobalConstantPropagation());
|
||||||
|
CheckFinal();
|
||||||
|
|
||||||
BuildTraces(false);
|
BuildTraces(false);
|
||||||
DisassembleDebug("Rebuilt traces");
|
DisassembleDebug("Rebuilt traces");
|
||||||
|
CheckFinal();
|
||||||
|
|
||||||
|
|
||||||
PeepholeOptimization();
|
PeepholeOptimization();
|
||||||
TempForwarding();
|
TempForwarding();
|
||||||
|
@ -18404,8 +18689,12 @@ void InterCodeProcedure::Close(void)
|
||||||
|
|
||||||
ReduceTemporaries();
|
ReduceTemporaries();
|
||||||
|
|
||||||
|
CheckBlocks();
|
||||||
|
|
||||||
MergeBasicBlocks();
|
MergeBasicBlocks();
|
||||||
|
|
||||||
|
CheckBlocks();
|
||||||
|
|
||||||
DisassembleDebug("TempForward Rev 1");
|
DisassembleDebug("TempForward Rev 1");
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
@ -18414,6 +18703,8 @@ void InterCodeProcedure::Close(void)
|
||||||
|
|
||||||
RemoveUnusedInstructions();
|
RemoveUnusedInstructions();
|
||||||
|
|
||||||
|
CheckBlocks();
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
|
||||||
DisassembleDebug("TempForward Rev 2");
|
DisassembleDebug("TempForward Rev 2");
|
||||||
|
@ -18422,6 +18713,8 @@ void InterCodeProcedure::Close(void)
|
||||||
|
|
||||||
DisassembleDebug("TempForward Rev 3");
|
DisassembleDebug("TempForward Rev 3");
|
||||||
|
|
||||||
|
CheckBlocks();
|
||||||
|
|
||||||
BuildLoopPrefix();
|
BuildLoopPrefix();
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
@ -18467,6 +18760,8 @@ void InterCodeProcedure::Close(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RemoveUnusedPartialStoreInstructions();
|
||||||
|
|
||||||
MapVariables();
|
MapVariables();
|
||||||
|
|
||||||
DisassembleDebug("mapped variabled");
|
DisassembleDebug("mapped variabled");
|
||||||
|
@ -18824,9 +19119,11 @@ void InterCodeProcedure::MergeBasicBlocks(void)
|
||||||
if (block->mNumEntries)
|
if (block->mNumEntries)
|
||||||
{
|
{
|
||||||
int j = 0;
|
int j = 0;
|
||||||
while (j < i && !(mBlocks[j]->mNumEntries && mBlocks[j]->IsEqual(block)))
|
while (j < i && !(mBlocks[j]->mNumEntries && mBlocks[j]->IsEqual(block) && mBlocks[j]->mIndex != 0))
|
||||||
j++;
|
j++;
|
||||||
blockMap[i] = mBlocks[j];
|
blockMap[i] = mBlocks[j];
|
||||||
|
if (i != j)
|
||||||
|
mBlocks[j]->UnionIntegerRanges(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18935,6 +19232,8 @@ void InterCodeProcedure::MergeBasicBlocks(void)
|
||||||
assert(mblocks[j]->mInstructions[mblocks[j]->mInstructions.Size() - 1]->mCode == IC_JUMP);
|
assert(mblocks[j]->mInstructions[mblocks[j]->mInstructions.Size() - 1]->mCode == IC_JUMP);
|
||||||
assert(mblocks[j]->mInstructions[mblocks[j]->mInstructions.Size() - 2]->IsEqual(ins));
|
assert(mblocks[j]->mInstructions[mblocks[j]->mInstructions.Size() - 2]->IsEqual(ins));
|
||||||
|
|
||||||
|
ins->UnionRanges(mblocks[j]->mInstructions[mblocks[j]->mInstructions.Size() - 2]);
|
||||||
|
|
||||||
mblocks[j]->mInstructions.Remove(mblocks[j]->mInstructions.Size() - 2);
|
mblocks[j]->mInstructions.Remove(mblocks[j]->mInstructions.Size() - 2);
|
||||||
}
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
|
@ -148,6 +148,7 @@ public:
|
||||||
~IntegerValueRange(void);
|
~IntegerValueRange(void);
|
||||||
|
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
|
void Restart(void);
|
||||||
|
|
||||||
int64 mMinValue, mMaxValue;
|
int64 mMinValue, mMaxValue;
|
||||||
int mMinExpanded, mMaxExpanded;
|
int mMinExpanded, mMaxExpanded;
|
||||||
|
@ -163,8 +164,10 @@ public:
|
||||||
bool Same(const IntegerValueRange& range) const;
|
bool Same(const IntegerValueRange& range) const;
|
||||||
bool Merge(const IntegerValueRange& range, bool head, bool initial);
|
bool Merge(const IntegerValueRange& range, bool head, bool initial);
|
||||||
void Expand(const IntegerValueRange& range);
|
void Expand(const IntegerValueRange& range);
|
||||||
|
void Union(const IntegerValueRange& range);
|
||||||
|
|
||||||
void Limit(const IntegerValueRange& range);
|
void Limit(const IntegerValueRange& range);
|
||||||
|
void MergeUnknown(const IntegerValueRange& range);
|
||||||
void SetLimit(int64 minValue, int64 maxValue);
|
void SetLimit(int64 minValue, int64 maxValue);
|
||||||
|
|
||||||
bool IsConstant(void) const;
|
bool IsConstant(void) const;
|
||||||
|
@ -245,7 +248,7 @@ class InterVariable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool mUsed, mAliased, mTemp;
|
bool mUsed, mAliased, mTemp;
|
||||||
int mIndex, mSize, mOffset, mTempIndex;
|
int mIndex, mSize, mOffset, mTempIndex, mByteIndex;
|
||||||
int mNumReferences;
|
int mNumReferences;
|
||||||
const Ident * mIdent;
|
const Ident * mIdent;
|
||||||
LinkerObject * mLinkerObject;
|
LinkerObject * mLinkerObject;
|
||||||
|
@ -318,10 +321,12 @@ public:
|
||||||
void FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
void FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||||
void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory);
|
void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory);
|
||||||
void FilterStaticVarsUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars);
|
void FilterStaticVarsUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars);
|
||||||
|
void FilterStaticVarsByteUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars);
|
||||||
|
|
||||||
bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps);
|
bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps);
|
||||||
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory);
|
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory);
|
||||||
bool RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock * block, const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns);
|
bool RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock * block, const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns);
|
||||||
|
bool RemoveUnusedStaticStoreByteInstructions(InterCodeBasicBlock* block, const GrowingVariableArray& staticVars, NumberSet& requiredVars);
|
||||||
void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
||||||
void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps);
|
void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps);
|
||||||
|
|
||||||
|
@ -343,6 +348,8 @@ public:
|
||||||
bool ConstantFolding(void);
|
bool ConstantFolding(void);
|
||||||
bool ConstantFoldingRelationRange(void);
|
bool ConstantFoldingRelationRange(void);
|
||||||
|
|
||||||
|
void UnionRanges(InterInstruction* ins);
|
||||||
|
|
||||||
void Disassemble(FILE* file, InterCodeProcedure * proc);
|
void Disassemble(FILE* file, InterCodeProcedure * proc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -381,7 +388,7 @@ public:
|
||||||
|
|
||||||
GrowingArray<int64> mMemoryValueSize, mEntryMemoryValueSize;
|
GrowingArray<int64> mMemoryValueSize, mEntryMemoryValueSize;
|
||||||
|
|
||||||
GrowingArray<InterCodeBasicBlock*> mEntryBlocks, mLoopPathBlocks;
|
ExpandingArray<InterCodeBasicBlock*> mEntryBlocks, mLoopPathBlocks;
|
||||||
|
|
||||||
GrowingInstructionPtrArray mMergeTValues, mMergeAValues;
|
GrowingInstructionPtrArray mMergeTValues, mMergeAValues;
|
||||||
ValueSet mMergeValues;
|
ValueSet mMergeValues;
|
||||||
|
@ -435,6 +442,9 @@ public:
|
||||||
bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars);
|
bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars);
|
||||||
bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars);
|
bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars);
|
||||||
|
|
||||||
|
void BuildStaticVariableByteSet(const GrowingVariableArray& staticVars, int bsize);
|
||||||
|
bool RemoveUnusedStaticStoreByteInstructions(const GrowingVariableArray& staticVars, int bsize);
|
||||||
|
|
||||||
bool CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pblock, int64 & nloop);
|
bool CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pblock, int64 & nloop);
|
||||||
|
|
||||||
void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
||||||
|
@ -443,6 +453,7 @@ public:
|
||||||
bool BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
bool BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
||||||
void SimplifyIntegerRangeRelops(void);
|
void SimplifyIntegerRangeRelops(void);
|
||||||
void MarkIntegerRangeBoundUp(int temp, int64 value, GrowingIntegerValueRangeArray& range);
|
void MarkIntegerRangeBoundUp(int temp, int64 value, GrowingIntegerValueRangeArray& range);
|
||||||
|
void UnionIntegerRanges(const InterCodeBasicBlock* block);
|
||||||
|
|
||||||
bool CombineIndirectAddressing(void);
|
bool CombineIndirectAddressing(void);
|
||||||
|
|
||||||
|
@ -551,9 +562,9 @@ public:
|
||||||
void SingleBlockLoopUnrolling(void);
|
void SingleBlockLoopUnrolling(void);
|
||||||
bool SingleBlockLoopPointerSplit(int& spareTemps);
|
bool SingleBlockLoopPointerSplit(int& spareTemps);
|
||||||
bool SingleBlockLoopPointerToByte(int& spareTemps);
|
bool SingleBlockLoopPointerToByte(int& spareTemps);
|
||||||
bool CollectLoopBody(InterCodeBasicBlock* head, GrowingArray<InterCodeBasicBlock*> & body);
|
bool CollectLoopBody(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*> & body);
|
||||||
bool CollectLoopBodyRecursive(InterCodeBasicBlock* head, GrowingArray<InterCodeBasicBlock*>& body);
|
bool CollectLoopBodyRecursive(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*>& body);
|
||||||
void CollectLoopPath(const GrowingArray<InterCodeBasicBlock*>& body, GrowingArray<InterCodeBasicBlock*>& path);
|
void CollectLoopPath(const ExpandingArray<InterCodeBasicBlock*>& body, ExpandingArray<InterCodeBasicBlock*>& path);
|
||||||
void InnerLoopOptimization(const NumberSet& aliasedParams);
|
void InnerLoopOptimization(const NumberSet& aliasedParams);
|
||||||
void PushMoveOutOfLoop(void);
|
void PushMoveOutOfLoop(void);
|
||||||
|
|
||||||
|
@ -670,6 +681,7 @@ protected:
|
||||||
void BuildLoopPrefix(void);
|
void BuildLoopPrefix(void);
|
||||||
void SingleAssignmentForwarding(void);
|
void SingleAssignmentForwarding(void);
|
||||||
void RemoveUnusedStoreInstructions(InterMemory paramMemory);
|
void RemoveUnusedStoreInstructions(InterMemory paramMemory);
|
||||||
|
void RemoveUnusedPartialStoreInstructions(void);
|
||||||
void RemoveUnusedLocalStoreInstructions(void);
|
void RemoveUnusedLocalStoreInstructions(void);
|
||||||
void MergeCommonPathInstructions(void);
|
void MergeCommonPathInstructions(void);
|
||||||
void PushSinglePathResultInstructions(void);
|
void PushSinglePathResultInstructions(void);
|
||||||
|
|
|
@ -17948,6 +17948,183 @@ bool NativeCodeBasicBlock::RemoveDoubleZPStore(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ValueNumbers
|
||||||
|
{
|
||||||
|
int zvalues[256], avalue, xvalue, yvalue;
|
||||||
|
int ivalue = 0;
|
||||||
|
|
||||||
|
void Reset(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
zvalues[i] = ivalue++;
|
||||||
|
avalue = ivalue++;
|
||||||
|
xvalue = ivalue++;
|
||||||
|
yvalue = ivalue++;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::LocalZeroPageValueNumbering(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
ValueNumbers vn;
|
||||||
|
vn.Reset();
|
||||||
|
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins = mIns[i];
|
||||||
|
|
||||||
|
if (ins.mType == ASMIT_LDA && ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (vn.avalue == vn.zvalues[ins.mAddress])
|
||||||
|
{
|
||||||
|
if (ins.mLive & LIVE_CPU_REG_Z)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_ORA;
|
||||||
|
ins.mMode = ASMIM_IMMEDIATE;
|
||||||
|
ins.mAddress = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.avalue = vn.zvalues[ins.mAddress];
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_LDX && ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (vn.xvalue == vn.zvalues[ins.mAddress] && !(ins.mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.xvalue = vn.zvalues[ins.mAddress];
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_LDY && ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (vn.yvalue == vn.zvalues[ins.mAddress] && !(ins.mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.yvalue = vn.zvalues[ins.mAddress];
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STA && ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (vn.avalue == vn.zvalues[ins.mAddress])
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.zvalues[ins.mAddress] = vn.avalue;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STX && ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (vn.xvalue == vn.zvalues[ins.mAddress])
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.zvalues[ins.mAddress] = vn.xvalue;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STY && ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (vn.yvalue == vn.zvalues[ins.mAddress])
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.zvalues[ins.mAddress] = vn.yvalue;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_TAX)
|
||||||
|
{
|
||||||
|
if (vn.avalue == vn.xvalue && !(ins.mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.xvalue = vn.avalue;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_TAY)
|
||||||
|
{
|
||||||
|
if (vn.avalue == vn.yvalue && !(ins.mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.yvalue = vn.avalue;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_TXA)
|
||||||
|
{
|
||||||
|
if (vn.xvalue == vn.avalue && !(ins.mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.avalue = vn.xvalue;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_TYA)
|
||||||
|
{
|
||||||
|
if (vn.yvalue == vn.avalue && !(ins.mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vn.avalue = vn.yvalue;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_JSR)
|
||||||
|
vn.Reset();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ins.ChangesAccu())
|
||||||
|
vn.avalue = vn.ivalue++;
|
||||||
|
if (ins.ChangesXReg())
|
||||||
|
vn.xvalue = vn.ivalue++;
|
||||||
|
if (ins.ChangesYReg())
|
||||||
|
vn.yvalue = vn.ivalue++;
|
||||||
|
if (ins.mMode == ASMIM_ZERO_PAGE && ins.ChangesAddress())
|
||||||
|
vn.zvalues[ins.mAddress] = vn.ivalue++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->LocalZeroPageValueNumbering())
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
if (mFalseJump && mFalseJump->LocalZeroPageValueNumbering())
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::LocalRegisterXYMap(void)
|
bool NativeCodeBasicBlock::LocalRegisterXYMap(void)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -27176,6 +27353,50 @@ bool NativeCodeBasicBlock::FoldShiftORAIntoLoadImmUp(int at)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TAX
|
||||||
|
// CLC
|
||||||
|
// ADC #1, 2, 3
|
||||||
|
// STA
|
||||||
|
//
|
||||||
|
// convert to INX/DEX/STX when X not needed anymore
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::MoveTAXADCSTADown(int at)
|
||||||
|
{
|
||||||
|
int n = mIns[at + 2].mAddress;
|
||||||
|
int addr = mIns[at + 3].mAddress;
|
||||||
|
|
||||||
|
int si = at + 4;
|
||||||
|
while (si < mIns.Size())
|
||||||
|
{
|
||||||
|
if (!(mIns[si].mLive & LIVE_CPU_REG_X))
|
||||||
|
{
|
||||||
|
if (mIns[si].mLive & LIVE_CPU_REG_Z)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mIns[si].mLive |= LIVE_CPU_REG_X;
|
||||||
|
si++;
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
mIns.Insert(si, NativeCodeInstruction(mIns[at].mIns, ASMIT_INX));
|
||||||
|
si++;
|
||||||
|
}
|
||||||
|
mIns.Insert(si, NativeCodeInstruction(mIns[at].mIns, ASMIT_STX, ASMIM_ZERO_PAGE, addr));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIns[si].ChangesXReg())
|
||||||
|
return false;
|
||||||
|
if (mIns[si].ReferencesZeroPage(addr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
si++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// CLC
|
// CLC
|
||||||
// LDA zp0
|
// LDA zp0
|
||||||
// ADC #1, 2, 3
|
// ADC #1, 2, 3
|
||||||
|
@ -31487,7 +31708,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool f
|
||||||
{
|
{
|
||||||
// check for usage of Y register
|
// check for usage of Y register
|
||||||
|
|
||||||
bool yother = false, yindex = false;
|
bool yother = false, yindex = false, xother = false, xindex = false;
|
||||||
int zreg = mIns[sz - 1].mAddress;
|
int zreg = mIns[sz - 1].mAddress;
|
||||||
int yinc = 0, xinc = 0;
|
int yinc = 0, xinc = 0;
|
||||||
|
|
||||||
|
@ -31495,6 +31716,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool f
|
||||||
|
|
||||||
if (mIns[sz - 1].mLive & LIVE_CPU_REG_Y)
|
if (mIns[sz - 1].mLive & LIVE_CPU_REG_Y)
|
||||||
yother = true;
|
yother = true;
|
||||||
|
if (mIns[sz - 1].mLive & LIVE_CPU_REG_X)
|
||||||
|
xother = true;
|
||||||
|
|
||||||
for (int i = 0; i < sz - 1; i++)
|
for (int i = 0; i < sz - 1; i++)
|
||||||
{
|
{
|
||||||
|
@ -31518,6 +31741,27 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool f
|
||||||
yother = true;
|
yother = true;
|
||||||
else if (mIns[i].mType != ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
else if (mIns[i].mType != ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
yother = true;
|
yother = true;
|
||||||
|
|
||||||
|
if (mIns[i].mType == ASMIT_TAX)
|
||||||
|
xother = true;
|
||||||
|
else if (mIns[i].mType == ASMIT_INX)
|
||||||
|
xinc++;
|
||||||
|
else if (mIns[i].mType == ASMIT_DEX)
|
||||||
|
xinc--;
|
||||||
|
else if (mIns[i].mType == ASMIT_LDX)
|
||||||
|
{
|
||||||
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg && xinc >= -1 && xinc <= 1)
|
||||||
|
{
|
||||||
|
xinc = 0;
|
||||||
|
xindex = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
xother = true;
|
||||||
|
}
|
||||||
|
else if (!xindex && (mIns[i].mType == ASMIT_STX || mIns[i].mType == ASMIT_TXA || mIns[i].mMode == ASMIM_ABSOLUTE_X))
|
||||||
|
xother = true;
|
||||||
|
else if (mIns[i].mType != ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
xother = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!yother)
|
if (!yother)
|
||||||
|
@ -31601,6 +31845,89 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool f
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
|
assert(mIns.Size() == 0 || mIns[0].mType != ASMIT_INV);
|
||||||
|
}
|
||||||
|
else if (!xother)
|
||||||
|
{
|
||||||
|
int linc = xinc + 1;
|
||||||
|
|
||||||
|
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
||||||
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
|
|
||||||
|
yinc = 0;
|
||||||
|
for (int i = 0; i + 1 < sz; i++)
|
||||||
|
{
|
||||||
|
mIns[i].mLive |= LIVE_CPU_REG_X;
|
||||||
|
|
||||||
|
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(mIns[i].mIns, ASMIT_TXA, ASMIM_IMPLIED));
|
||||||
|
else if (mIns[i].mType == ASMIT_LDX)
|
||||||
|
{
|
||||||
|
if (yinc > 0)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(mIns[i].mIns, ASMIT_DEX));
|
||||||
|
else if (yinc < 0)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(mIns[i].mIns, ASMIT_INX));
|
||||||
|
yinc = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblock->mIns.Push(mIns[i]);
|
||||||
|
if (mIns[i].mType == ASMIT_INX)
|
||||||
|
yinc++;
|
||||||
|
else if (mIns[i].mType == ASMIT_DEX)
|
||||||
|
yinc--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linc == 0)
|
||||||
|
{
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(iins, ASMIT_CPX, ASMIM_IMMEDIATE, 0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (linc < 0)
|
||||||
|
{
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(iins, ASMIT_INX, ASMIM_IMPLIED));
|
||||||
|
linc++;
|
||||||
|
}
|
||||||
|
while (linc > 0)
|
||||||
|
{
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(iins, ASMIT_DEX, ASMIM_IMPLIED));
|
||||||
|
linc--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lblock->mBranch = mBranch;
|
||||||
|
lblock->mTrueJump = lblock;
|
||||||
|
lblock->mFalseJump = eblock;
|
||||||
|
|
||||||
|
eblock->mIns.Push(NativeCodeInstruction(iins, ASMIT_STX, ASMIM_ZERO_PAGE, zreg));
|
||||||
|
eblock->mBranch = ASMIT_JMP;
|
||||||
|
eblock->mTrueJump = mFalseJump;
|
||||||
|
eblock->mFalseJump = nullptr;
|
||||||
|
|
||||||
|
lblock->mEntryRequiredRegs = mEntryRequiredRegs;
|
||||||
|
lblock->mExitRequiredRegs = mExitRequiredRegs;
|
||||||
|
eblock->mEntryRequiredRegs = mExitRequiredRegs;
|
||||||
|
eblock->mExitRequiredRegs = mExitRequiredRegs;
|
||||||
|
mExitRequiredRegs = mEntryRequiredRegs;
|
||||||
|
mExitRequiredRegs += CPU_REG_X;
|
||||||
|
lblock->mEntryRequiredRegs += CPU_REG_X;
|
||||||
|
lblock->mExitRequiredRegs += CPU_REG_X;
|
||||||
|
eblock->mEntryRequiredRegs += CPU_REG_X;
|
||||||
|
|
||||||
|
mIns.SetSize(0);
|
||||||
|
mIns.Push(NativeCodeInstruction(iins, ASMIT_LDX, ASMIM_ZERO_PAGE, zreg));
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump = lblock;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
|
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock, full);
|
||||||
|
|
||||||
|
lblock->CheckLive();
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
|
||||||
assert(mIns.Size() == 0 || mIns[0].mType != ASMIT_INV);
|
assert(mIns.Size() == 0 || mIns[0].mType != ASMIT_INV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34543,6 +34870,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
for (int i = 0; i + 3 < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mIns[i + 0].mType == ASMIT_TAX && mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
|
||||||
|
|
||||||
|
{
|
||||||
|
if (MoveTAXADCSTADown(i))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckLive();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
for (int i = 0; i < mIns.Size(); i++)
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -42138,6 +42481,12 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (step > 1)
|
||||||
|
{
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->LocalZeroPageValueNumbering();
|
||||||
|
}
|
||||||
|
|
||||||
int t = 0;
|
int t = 0;
|
||||||
#if 1
|
#if 1
|
||||||
do
|
do
|
||||||
|
|
|
@ -446,6 +446,8 @@ public:
|
||||||
bool FoldShiftORAIntoLoadImmUp(int at);
|
bool FoldShiftORAIntoLoadImmUp(int at);
|
||||||
|
|
||||||
bool MoveSimpleADCToINCDECDown(int at);
|
bool MoveSimpleADCToINCDECDown(int at);
|
||||||
|
bool MoveTAXADCSTADown(int at);
|
||||||
|
|
||||||
|
|
||||||
bool MoveZeroPageCrossBlockUp(int at, const NativeCodeInstruction & lins, const NativeCodeInstruction & sins);
|
bool MoveZeroPageCrossBlockUp(int at, const NativeCodeInstruction & lins, const NativeCodeInstruction & sins);
|
||||||
bool ShortcutCrossBlockMoves(NativeCodeProcedure* proc);
|
bool ShortcutCrossBlockMoves(NativeCodeProcedure* proc);
|
||||||
|
@ -570,6 +572,7 @@ public:
|
||||||
bool LocalRegisterXYMap(void);
|
bool LocalRegisterXYMap(void);
|
||||||
bool ReduceLocalYPressure(void);
|
bool ReduceLocalYPressure(void);
|
||||||
bool ReduceLocalXPressure(void);
|
bool ReduceLocalXPressure(void);
|
||||||
|
bool LocalZeroPageValueNumbering(void);
|
||||||
|
|
||||||
bool CombineZPPair(int at, int r0, int r1, bool use0, bool use1, bool & swap);
|
bool CombineZPPair(int at, int r0, int r1, bool use0, bool use1, bool & swap);
|
||||||
bool RemoveDoubleZPStore(void);
|
bool RemoveDoubleZPStore(void);
|
||||||
|
|
|
@ -73,6 +73,34 @@ void NumberSet::Reset(int size, bool set)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NumberSet::AddRange(int elem, int num)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
*this += elem + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NumberSet::SubRange(int elem, int num)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
*this -= elem + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NumberSet::RangeClear(int elem, int num) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
if ((*this)[elem + i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NumberSet::RangeFilled(int elem, int num) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
if (!(*this)[elem + i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void NumberSet::Fill(void)
|
void NumberSet::Fill(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -34,6 +34,10 @@ public:
|
||||||
|
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
void Fill(void);
|
void Fill(void);
|
||||||
|
void AddRange(int elem, int num);
|
||||||
|
void SubRange(int elem, int num);
|
||||||
|
bool RangeClear(int elem, int num) const;
|
||||||
|
bool RangeFilled(int elem, int num) const;
|
||||||
|
|
||||||
int Size(void) { return size; }
|
int Size(void) { return size; }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue