Make loop head extraction explicit
This commit is contained in:
parent
5b4e0c2b55
commit
d6802f3cb9
|
@ -99,6 +99,61 @@ void IntegerValueRange::Restart(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IntegerValueRange::Weaker(const IntegerValueRange& range) const
|
||||||
|
{
|
||||||
|
bool minWeak = false, maxWeak = false;
|
||||||
|
|
||||||
|
if (range.mMinState == S_UNKNOWN)
|
||||||
|
minWeak = false;
|
||||||
|
else if (mMinState == S_UNKNOWN)
|
||||||
|
minWeak = true;
|
||||||
|
else if (mMinState == S_BOUND)
|
||||||
|
{
|
||||||
|
if (range.mMinState >= S_WEAK && mMinValue < range.mMinValue)
|
||||||
|
minWeak = true;
|
||||||
|
}
|
||||||
|
else if (mMinState == S_WEAK)
|
||||||
|
{
|
||||||
|
if (range.mMinState == S_BOUND)
|
||||||
|
minWeak = true;
|
||||||
|
if (range.mMinState == S_WEAK && mMinValue != range.mMinValue)
|
||||||
|
minWeak = true;
|
||||||
|
}
|
||||||
|
else if (mMinState == S_UNBOUND)
|
||||||
|
{
|
||||||
|
if (mMinExpanded >= 32 && range.mMinState == S_WEAK)
|
||||||
|
;
|
||||||
|
else if (range.mMinState != S_UNBOUND)
|
||||||
|
minWeak = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (range.mMaxState == S_UNKNOWN)
|
||||||
|
maxWeak = false;
|
||||||
|
else if (mMaxState == S_UNKNOWN)
|
||||||
|
maxWeak = true;
|
||||||
|
else if (mMaxState == S_BOUND)
|
||||||
|
{
|
||||||
|
if (range.mMaxState >= S_WEAK && mMaxValue > range.mMaxValue)
|
||||||
|
maxWeak = true;
|
||||||
|
}
|
||||||
|
else if (mMaxState == S_WEAK)
|
||||||
|
{
|
||||||
|
if (range.mMaxState == S_BOUND)
|
||||||
|
maxWeak = true;
|
||||||
|
if (range.mMaxState == S_WEAK && mMaxValue != range.mMaxValue)
|
||||||
|
maxWeak = true;
|
||||||
|
}
|
||||||
|
else if (mMaxState == S_UNBOUND)
|
||||||
|
{
|
||||||
|
if (mMaxExpanded >= 32 && range.mMaxState == S_WEAK)
|
||||||
|
;
|
||||||
|
else if (range.mMaxState != S_UNBOUND)
|
||||||
|
maxWeak = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return minWeak || maxWeak;
|
||||||
|
}
|
||||||
|
|
||||||
bool IntegerValueRange::Same(const IntegerValueRange& range) const
|
bool IntegerValueRange::Same(const IntegerValueRange& range) const
|
||||||
{
|
{
|
||||||
if (mMinState == range.mMinState && mMaxState == range.mMaxState)
|
if (mMinState == range.mMinState && mMaxState == range.mMaxState)
|
||||||
|
@ -266,6 +321,91 @@ void IntegerValueRange::SetBounds(State minState, int64 minValue, State maxState
|
||||||
|
|
||||||
void IntegerValueRange::Expand(const IntegerValueRange& range)
|
void IntegerValueRange::Expand(const IntegerValueRange& range)
|
||||||
{
|
{
|
||||||
|
if (mMinState == S_BOUND)
|
||||||
|
{
|
||||||
|
if (range.mMinState == S_BOUND)
|
||||||
|
{
|
||||||
|
if (range.mMinValue > mMinValue)
|
||||||
|
mMinValue = range.mMinValue;
|
||||||
|
}
|
||||||
|
else if (range.mMinState == S_WEAK)
|
||||||
|
{
|
||||||
|
if (range.mMinValue > mMinValue)
|
||||||
|
{
|
||||||
|
mMinValue = range.mMinValue;
|
||||||
|
mMinState = S_WEAK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mMinState == S_WEAK)
|
||||||
|
{
|
||||||
|
if (range.mMinState == S_BOUND)
|
||||||
|
{
|
||||||
|
mMinState = range.mMinState;
|
||||||
|
mMinValue = range.mMinValue;
|
||||||
|
}
|
||||||
|
else if (range.mMinState == S_WEAK)
|
||||||
|
{
|
||||||
|
if (range.mMinValue != mMinValue)
|
||||||
|
{
|
||||||
|
mMinExpanded++;
|
||||||
|
mMinValue = range.mMinValue;
|
||||||
|
if (mMinExpanded >= 32)
|
||||||
|
mMinState = S_UNBOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (range.mMinState == S_UNBOUND)
|
||||||
|
mMinState = S_UNBOUND;
|
||||||
|
}
|
||||||
|
else if (mMinState == S_UNKNOWN || range.mMinState != S_UNKNOWN)
|
||||||
|
{
|
||||||
|
mMinState = range.mMinState;
|
||||||
|
mMinValue = range.mMinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMaxState == S_BOUND)
|
||||||
|
{
|
||||||
|
if (range.mMaxState == S_BOUND)
|
||||||
|
{
|
||||||
|
if (range.mMaxValue < mMaxValue)
|
||||||
|
mMaxValue = range.mMaxValue;
|
||||||
|
}
|
||||||
|
else if (range.mMaxState == S_WEAK)
|
||||||
|
{
|
||||||
|
if (range.mMaxValue < mMaxValue)
|
||||||
|
{
|
||||||
|
mMaxValue = range.mMaxValue;
|
||||||
|
mMaxState = S_WEAK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mMaxState == S_WEAK)
|
||||||
|
{
|
||||||
|
if (range.mMaxState == S_BOUND)
|
||||||
|
{
|
||||||
|
mMaxValue = range.mMaxValue;
|
||||||
|
mMaxState = S_BOUND;
|
||||||
|
}
|
||||||
|
else if (range.mMaxState == S_WEAK)
|
||||||
|
{
|
||||||
|
if (range.mMaxValue != mMaxValue)
|
||||||
|
{
|
||||||
|
mMaxExpanded++;
|
||||||
|
mMaxValue = range.mMaxValue;
|
||||||
|
if (mMaxExpanded >= 32)
|
||||||
|
mMaxState = S_UNBOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (range.mMaxState == S_UNBOUND)
|
||||||
|
mMaxState = S_UNBOUND;
|
||||||
|
}
|
||||||
|
else if (mMaxState == S_UNKNOWN || range.mMaxState != S_UNKNOWN)
|
||||||
|
{
|
||||||
|
mMaxState = range.mMaxState;
|
||||||
|
mMaxValue = range.mMaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (range.mMinState == S_BOUND && mMinState == S_BOUND && range.mMinValue < mMinValue)
|
if (range.mMinState == S_BOUND && mMinState == S_BOUND && range.mMinValue < mMinValue)
|
||||||
{
|
{
|
||||||
mMinValue = range.mMinValue;
|
mMinValue = range.mMinValue;
|
||||||
|
@ -292,6 +432,7 @@ void IntegerValueRange::Expand(const IntegerValueRange& range)
|
||||||
mMaxState = range.mMaxState;
|
mMaxState = range.mMaxState;
|
||||||
mMaxValue = range.mMaxValue;
|
mMaxValue = range.mMaxValue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntegerValueRange::Union(const IntegerValueRange& range)
|
void IntegerValueRange::Union(const IntegerValueRange& range)
|
||||||
|
@ -6103,13 +6244,20 @@ bool InterCodeBasicBlock::IsDominator(InterCodeBasicBlock* block)
|
||||||
|
|
||||||
void InterCodeBasicBlock::CollectEntries(void)
|
void InterCodeBasicBlock::CollectEntries(void)
|
||||||
{
|
{
|
||||||
|
if (mInPath)
|
||||||
|
{
|
||||||
|
mLoopDebug = true;
|
||||||
|
mLoopHead = true;
|
||||||
|
}
|
||||||
mNumEntries++;
|
mNumEntries++;
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
{
|
{
|
||||||
mVisited = true;
|
mVisited = true;
|
||||||
|
|
||||||
|
mInPath = true;
|
||||||
if (mTrueJump) mTrueJump->CollectEntries();
|
if (mTrueJump) mTrueJump->CollectEntries();
|
||||||
if (mFalseJump) mFalseJump->CollectEntries();
|
if (mFalseJump) mFalseJump->CollectEntries();
|
||||||
|
mInPath = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6133,6 +6281,61 @@ static bool IsInfiniteLoop(InterCodeBasicBlock* head, InterCodeBasicBlock* block
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::StripLoopHead(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
if (mLoopHead && mFalseJump && mTrueJump != this && mFalseJump != this && mLoopPrefix && mInstructions.Size() < 10)
|
||||||
|
{
|
||||||
|
// printf("StripA %s %d\n", mProc->mIdent->mString, mIndex);
|
||||||
|
|
||||||
|
ExpandingArray<InterCodeBasicBlock*> lblocks;
|
||||||
|
if (CollectSingleEntryGenericLoop(lblocks))
|
||||||
|
{
|
||||||
|
// printf("StripB %s %d\n", mProc->mIdent->mString, mIndex);
|
||||||
|
|
||||||
|
mLoopPrefix->mInstructions.SetSize(0);
|
||||||
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
|
mLoopPrefix->mInstructions.Push(mInstructions[i]->Clone());
|
||||||
|
|
||||||
|
mLoopPrefix->mFalseJump = mFalseJump;
|
||||||
|
mLoopPrefix->mTrueJump = mTrueJump;
|
||||||
|
|
||||||
|
mEntryBlocks.RemoveAll(mLoopPrefix);
|
||||||
|
mNumEntries--;
|
||||||
|
mLoopHead = false;
|
||||||
|
|
||||||
|
mTrueJump->mEntryBlocks.Push(mLoopPrefix);
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
mFalseJump->mEntryBlocks.Push(mLoopPrefix);
|
||||||
|
mFalseJump->mNumEntries++;
|
||||||
|
|
||||||
|
if (!lblocks.Contains(mTrueJump))
|
||||||
|
{
|
||||||
|
mFalseJump->mLoopHead = true;
|
||||||
|
}
|
||||||
|
else if (!lblocks.Contains(mFalseJump))
|
||||||
|
{
|
||||||
|
mTrueJump->mLoopHead = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->StripLoopHead())
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->StripLoopHead())
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::GenerateTraces(int expand, bool compact)
|
void InterCodeBasicBlock::GenerateTraces(int expand, bool compact)
|
||||||
{
|
{
|
||||||
if (mInPath)
|
if (mInPath)
|
||||||
|
@ -6237,6 +6440,9 @@ void InterCodeBasicBlock::GenerateTraces(int expand, bool compact)
|
||||||
}
|
}
|
||||||
else if (mTrueJump && !mFalseJump && ((mTrueJump->mInstructions.Size() < expand && mTrueJump->mInstructions.Size() > 1 && !mLoopHead) || mTrueJump->mNumEntries == 1) && !mTrueJump->mLoopHead && !IsInfiniteLoop(mTrueJump, mTrueJump))
|
else if (mTrueJump && !mFalseJump && ((mTrueJump->mInstructions.Size() < expand && mTrueJump->mInstructions.Size() > 1 && !mLoopHead) || mTrueJump->mNumEntries == 1) && !mTrueJump->mLoopHead && !IsInfiniteLoop(mTrueJump, mTrueJump))
|
||||||
{
|
{
|
||||||
|
// if (mLoopDebug)
|
||||||
|
// printf("StripC %s %d %d\n", mProc->mIdent->mString, mTrueJump->mIndex, mTrueJump->mInstructions.Size());
|
||||||
|
|
||||||
mTrueJump->mNumEntries--;
|
mTrueJump->mNumEntries--;
|
||||||
int n = mTrueJump->mNumEntries;
|
int n = mTrueJump->mNumEntries;
|
||||||
|
|
||||||
|
@ -8189,11 +8395,11 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const Growin
|
||||||
assert(mLocalParamValueRange.Size() == paramVars.Size());
|
assert(mLocalParamValueRange.Size() == paramVars.Size());
|
||||||
|
|
||||||
for (int i = 0; i < mProc->mLocalValueRange.Size(); i++)
|
for (int i = 0; i < mProc->mLocalValueRange.Size(); i++)
|
||||||
if (!mProc->mLocalValueRange[i].Same(mEntryValueRange[i]))
|
if (mEntryValueRange[i].Weaker(mProc->mLocalValueRange[i]))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
for (int i = 0; i < mLocalParamValueRange.Size(); i++)
|
for (int i = 0; i < mLocalParamValueRange.Size(); i++)
|
||||||
if (!mLocalParamValueRange[i].Same(mEntryParamValueRange[i]))
|
if (mEntryParamValueRange[i].Weaker(mLocalParamValueRange[i]))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
if (mVisited && mNumEntered >= 2 * mEntryBlocks.Size())
|
if (mVisited && mNumEntered >= 2 * mEntryBlocks.Size())
|
||||||
|
@ -9551,6 +9757,15 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
||||||
mTrueValueRange[s].mMaxState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[s].mMaxState = IntegerValueRange::S_BOUND;
|
||||||
mTrueValueRange[s].mMaxValue = 1;
|
mTrueValueRange[s].mMaxValue = 1;
|
||||||
|
|
||||||
|
mFalseValueRange[s].mMinState = IntegerValueRange::S_BOUND;
|
||||||
|
mFalseValueRange[s].mMinValue = 0;
|
||||||
|
mFalseValueRange[s].mMaxState = IntegerValueRange::S_BOUND;
|
||||||
|
mFalseValueRange[s].mMaxValue = 0;
|
||||||
|
}
|
||||||
|
else if (mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 1]->mSrc[0].mTemp >= 0 && IsIntegerType(mInstructions[sz - 1]->mSrc[0].mType))
|
||||||
|
{
|
||||||
|
int s = mInstructions[sz - 1]->mSrc[0].mTemp;
|
||||||
|
|
||||||
mFalseValueRange[s].mMinState = IntegerValueRange::S_BOUND;
|
mFalseValueRange[s].mMinState = IntegerValueRange::S_BOUND;
|
||||||
mFalseValueRange[s].mMinValue = 0;
|
mFalseValueRange[s].mMinValue = 0;
|
||||||
mFalseValueRange[s].mMaxState = IntegerValueRange::S_BOUND;
|
mFalseValueRange[s].mMaxState = IntegerValueRange::S_BOUND;
|
||||||
|
@ -15520,8 +15735,76 @@ bool InterCodeBasicBlock::InvalidatedBy(const InterInstruction* ins, const Inter
|
||||||
return CollidingMem(by, ins);
|
return CollidingMem(by, ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::CollectReachable(ExpandingArray<InterCodeBasicBlock*>& lblock)
|
||||||
|
{
|
||||||
|
if (!mVisited && !mPatched)
|
||||||
|
{
|
||||||
|
lblock.Push(this);
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
bool InterCodeBasicBlock::CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body)
|
if (mTrueJump) mTrueJump->CollectReachable(lblock);
|
||||||
|
if (mFalseJump) mFalseJump->CollectReachable(lblock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::CollectGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks)
|
||||||
|
{
|
||||||
|
ExpandingArray<InterCodeBasicBlock*> rblocks;
|
||||||
|
|
||||||
|
mProc->ResetPatched();
|
||||||
|
CollectReachable(rblocks);
|
||||||
|
|
||||||
|
mProc->ResetPatched();
|
||||||
|
|
||||||
|
bool changed;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
changed = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < rblocks.Size(); i++)
|
||||||
|
{
|
||||||
|
InterCodeBasicBlock* block(rblocks[i]);
|
||||||
|
|
||||||
|
if (!block->mPatched &&
|
||||||
|
(block->mTrueJump && (block->mTrueJump->mPatched || block->mTrueJump == this) ||
|
||||||
|
block->mFalseJump && (block->mFalseJump->mPatched || block->mFalseJump == this)))
|
||||||
|
{
|
||||||
|
lblocks.Push(block);
|
||||||
|
block->mPatched = true;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (changed);
|
||||||
|
|
||||||
|
return lblocks.Size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::CollectSingleEntryGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks)
|
||||||
|
{
|
||||||
|
if (CollectGenericLoop(lblocks))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < lblocks.Size(); i++)
|
||||||
|
{
|
||||||
|
InterCodeBasicBlock* block = lblocks[i];
|
||||||
|
|
||||||
|
if (block != this)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < block->mEntryBlocks.Size(); j++)
|
||||||
|
if (!lblocks.Contains(block->mEntryBlocks[j]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, ExpandingArray<InterCodeBasicBlock*>& body)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
body.Push(head);
|
body.Push(head);
|
||||||
|
@ -16063,7 +16346,7 @@ bool InterCodeBasicBlock::MergeLoopTails(void)
|
||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSingleLoopAssign(int at, InterCodeBasicBlock* block, const GrowingArray<InterCodeBasicBlock*>& body)
|
bool IsSingleLoopAssign(int at, InterCodeBasicBlock* block, const ExpandingArray<InterCodeBasicBlock*>& body)
|
||||||
{
|
{
|
||||||
InterInstruction* ai = block->mInstructions[at];
|
InterInstruction* ai = block->mInstructions[at];
|
||||||
if (ai->mDst.mTemp < 0)
|
if (ai->mDst.mTemp < 0)
|
||||||
|
@ -16078,7 +16361,7 @@ bool IsSingleLoopAssign(int at, InterCodeBasicBlock* block, const GrowingArray<I
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsLoopInvariantTemp(int tmp, const GrowingArray<InterCodeBasicBlock*>& body)
|
bool IsLoopInvariantTemp(int tmp, const ExpandingArray<InterCodeBasicBlock*>& body)
|
||||||
{
|
{
|
||||||
if (tmp < 0)
|
if (tmp < 0)
|
||||||
return true;
|
return true;
|
||||||
|
@ -16118,7 +16401,7 @@ bool InterCodeBasicBlock::SingleTailLoopOptimization(const NumberSet& aliasedPar
|
||||||
|
|
||||||
if (post && post->mNumEntries == 1)
|
if (post && post->mNumEntries == 1)
|
||||||
{
|
{
|
||||||
GrowingArray<InterCodeBasicBlock*> body(nullptr);
|
ExpandingArray<InterCodeBasicBlock*> body;
|
||||||
|
|
||||||
if (tail->CollectSingleHeadLoopBody(this, tail, body))
|
if (tail->CollectSingleHeadLoopBody(this, tail, body))
|
||||||
{
|
{
|
||||||
|
@ -17927,6 +18210,44 @@ void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
else if (loops)
|
||||||
|
{
|
||||||
|
ExpandingArray<InterCodeBasicBlock*> lblocks;
|
||||||
|
|
||||||
|
if (CollectSingleEntryGenericLoop(lblocks))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ltvalue.Size(); i++)
|
||||||
|
{
|
||||||
|
if (ltvalue[i])
|
||||||
|
{
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
for (int k = 0; k < lblocks.Size() && !fail; k++)
|
||||||
|
{
|
||||||
|
InterCodeBasicBlock* b = lblocks[k];
|
||||||
|
for (int j = 0; j < b->mInstructions.Size() && !fail; j++)
|
||||||
|
{
|
||||||
|
InterInstruction* ins = b->mInstructions[j];
|
||||||
|
if (ins->mDst.mTemp == i)
|
||||||
|
{
|
||||||
|
if (ins->mCode == IC_LEA && ins->mSrc[1].mTemp == i)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fail)
|
||||||
|
ltvalue[i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ltvalue.Clear();
|
||||||
|
}
|
||||||
|
#else
|
||||||
else if (loops && mNumEntries == 2)
|
else if (loops && mNumEntries == 2)
|
||||||
{
|
{
|
||||||
InterCodeBasicBlock* tail, * post;
|
InterCodeBasicBlock* tail, * post;
|
||||||
|
@ -17943,7 +18264,7 @@ void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPt
|
||||||
|
|
||||||
if (post && post->mNumEntries == 1)
|
if (post && post->mNumEntries == 1)
|
||||||
{
|
{
|
||||||
GrowingArray<InterCodeBasicBlock*> body(nullptr);
|
ExpandingArray<InterCodeBasicBlock*> body;
|
||||||
|
|
||||||
if (tail->CollectSingleHeadLoopBody(this, tail, body))
|
if (tail->CollectSingleHeadLoopBody(this, tail, body))
|
||||||
{
|
{
|
||||||
|
@ -17978,6 +18299,7 @@ void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
ltvalue.Clear();
|
ltvalue.Clear();
|
||||||
}
|
}
|
||||||
|
@ -18387,7 +18709,7 @@ bool InterCodeBasicBlock::MoveConditionOutOfLoop(void)
|
||||||
|
|
||||||
if (post && post->mNumEntries == 1)
|
if (post && post->mNumEntries == 1)
|
||||||
{
|
{
|
||||||
GrowingArray<InterCodeBasicBlock*> lbody(nullptr);
|
ExpandingArray<InterCodeBasicBlock*> lbody;
|
||||||
|
|
||||||
if (tail->CollectSingleHeadLoopBody(this, tail, lbody))
|
if (tail->CollectSingleHeadLoopBody(this, tail, lbody))
|
||||||
{
|
{
|
||||||
|
@ -21255,6 +21577,7 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
|
||||||
{
|
{
|
||||||
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mSrc[1];
|
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mSrc[1];
|
||||||
mInstructions[i + 2]->mSrc[1].mIntConst += mInstructions[i + 0]->mSrc[0].mIntConst << mInstructions[i + 1]->mSrc[0].mIntConst;
|
mInstructions[i + 2]->mSrc[1].mIntConst += mInstructions[i + 0]->mSrc[0].mIntConst << mInstructions[i + 1]->mSrc[0].mIntConst;
|
||||||
|
mInstructions[i + 2]->mSrc[0].mRange.AddConstValue(IT_INT16, - (mInstructions[i + 0]->mSrc[0].mIntConst << mInstructions[i + 1]->mSrc[0].mIntConst));
|
||||||
|
|
||||||
mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0;
|
mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -23081,6 +23404,12 @@ void InterCodeProcedure::ResetEntryBlocks(void)
|
||||||
mBlocks[i]->mEntryBlocks.SetSize(0);
|
mBlocks[i]->mEntryBlocks.SetSize(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeProcedure::ResetPatched(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mBlocks.Size(); i++)
|
||||||
|
mBlocks[i]->mPatched = false;
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::ResetVisited(void)
|
void InterCodeProcedure::ResetVisited(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -23216,6 +23545,7 @@ void InterCodeProcedure::BuildTraces(int expand, bool dominators, bool compact)
|
||||||
{
|
{
|
||||||
mBlocks[i]->mNumEntries = 0;
|
mBlocks[i]->mNumEntries = 0;
|
||||||
mBlocks[i]->mLoopHead = false;
|
mBlocks[i]->mLoopHead = false;
|
||||||
|
mBlocks[i]->mLoopDebug = false;
|
||||||
mBlocks[i]->mTraceIndex = -1;
|
mBlocks[i]->mTraceIndex = -1;
|
||||||
}
|
}
|
||||||
mEntryBlock->CollectEntries();
|
mEntryBlock->CollectEntries();
|
||||||
|
@ -24238,7 +24568,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "trench_init");
|
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||||
CheckCase = false;
|
CheckCase = false;
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
@ -24246,12 +24576,28 @@ void InterCodeProcedure::Close(void)
|
||||||
DisassembleDebug("start");
|
DisassembleDebug("start");
|
||||||
|
|
||||||
BuildTraces(10);
|
BuildTraces(10);
|
||||||
|
|
||||||
DisassembleDebug("traces");
|
DisassembleDebug("traces");
|
||||||
|
|
||||||
EarlyBranchElimination();
|
EarlyBranchElimination();
|
||||||
|
BuildTraces(0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
BuildLoopPrefix();
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->StripLoopHead());
|
||||||
|
DisassembleDebug("Loop Head");
|
||||||
|
BuildTraces(0);
|
||||||
|
|
||||||
|
|
||||||
DisassembleDebug("branch elimination");
|
DisassembleDebug("branch elimination");
|
||||||
|
#if 0
|
||||||
|
do {
|
||||||
|
BuildLoopPrefix();
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->StripLoopHead());
|
||||||
|
DisassembleDebug("Loop Head");
|
||||||
|
BuildTraces(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mLeafProcedure = mEntryBlock->IsLeafProcedure();
|
mLeafProcedure = mEntryBlock->IsLeafProcedure();
|
||||||
|
|
|
@ -169,6 +169,7 @@ public:
|
||||||
} mMinState, mMaxState;
|
} mMinState, mMaxState;
|
||||||
|
|
||||||
bool Same(const IntegerValueRange& range) const;
|
bool Same(const IntegerValueRange& range) const;
|
||||||
|
bool Weaker(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 Union(const IntegerValueRange& range);
|
||||||
|
@ -380,7 +381,7 @@ public:
|
||||||
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
|
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
|
||||||
GrowingInstructionArray mInstructions;
|
GrowingInstructionArray mInstructions;
|
||||||
|
|
||||||
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid;
|
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid, mPatched, mLoopDebug;
|
||||||
mutable int mMark;
|
mutable int mMark;
|
||||||
|
|
||||||
NumberSet mLocalUsedTemps, mLocalModifiedTemps;
|
NumberSet mLocalUsedTemps, mLocalModifiedTemps;
|
||||||
|
@ -431,6 +432,7 @@ public:
|
||||||
void CollectEntryBlocks(InterCodeBasicBlock* from);
|
void CollectEntryBlocks(InterCodeBasicBlock* from);
|
||||||
void GenerateTraces(int expand, bool compact);
|
void GenerateTraces(int expand, bool compact);
|
||||||
void BuildDominatorTree(InterCodeBasicBlock * from);
|
void BuildDominatorTree(InterCodeBasicBlock * from);
|
||||||
|
bool StripLoopHead(void);
|
||||||
|
|
||||||
bool MergeSameConditionTraces(void);
|
bool MergeSameConditionTraces(void);
|
||||||
|
|
||||||
|
@ -648,7 +650,11 @@ public:
|
||||||
|
|
||||||
bool PullStoreUpToConstAddress(void);
|
bool PullStoreUpToConstAddress(void);
|
||||||
|
|
||||||
bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body);
|
bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, ExpandingArray<InterCodeBasicBlock*>& body);
|
||||||
|
|
||||||
|
bool CollectGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks);
|
||||||
|
bool CollectSingleEntryGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks);
|
||||||
|
void CollectReachable(ExpandingArray<InterCodeBasicBlock*>& lblock);
|
||||||
|
|
||||||
bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
|
bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
|
||||||
bool MergeLoopTails(void);
|
bool MergeLoopTails(void);
|
||||||
|
@ -707,6 +713,7 @@ protected:
|
||||||
GrowingIntegerValueRangeArray mLocalValueRange, mReverseValueRange;
|
GrowingIntegerValueRangeArray mLocalValueRange, mReverseValueRange;
|
||||||
|
|
||||||
void ResetVisited(void);
|
void ResetVisited(void);
|
||||||
|
void ResetPatched(void);
|
||||||
void ResetEntryBlocks(void);
|
void ResetEntryBlocks(void);
|
||||||
public:
|
public:
|
||||||
InterCodeBasicBlock * mEntryBlock;
|
InterCodeBasicBlock * mEntryBlock;
|
||||||
|
|
|
@ -26516,7 +26516,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
|
||||||
mTrueJump->mIns.Remove(0);
|
mTrueJump->mIns.Remove(0);
|
||||||
mTrueJump->mEntryRequiredRegs += CPU_REG_A;
|
mTrueJump->mEntryRequiredRegs += CPU_REG_A;
|
||||||
|
|
||||||
if (mTrueJump->mIns.Size() > 0 && (mTrueJump->mIns[0].mLive & LIVE_CPU_REG_Z))
|
if (zlive)
|
||||||
mTrueJump->mEntryRequiredRegs += CPU_REG_Z;
|
mTrueJump->mEntryRequiredRegs += CPU_REG_Z;
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -37083,15 +37083,12 @@ bool NativeCodeBasicBlock::OffsetValueForwarding(const ValueNumberingDataSet& da
|
||||||
bool NativeCodeBasicBlock::CheckLoopIndexXRegisters(NativeCodeBasicBlock* head, int xreg)
|
bool NativeCodeBasicBlock::CheckLoopIndexXRegisters(NativeCodeBasicBlock* head, int xreg)
|
||||||
{
|
{
|
||||||
for (int i = mIns.Size() - 1; i >= 0; i--)
|
for (int i = mIns.Size() - 1; i >= 0; i--)
|
||||||
{
|
|
||||||
if (mIns[i].ChangesXReg())
|
|
||||||
{
|
{
|
||||||
if ((mIns[i].mType == ASMIT_LDX || mIns[i].mType == ASMIT_STX) && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == xreg)
|
if ((mIns[i].mType == ASMIT_LDX || mIns[i].mType == ASMIT_STX) && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == xreg)
|
||||||
return true;
|
return true;
|
||||||
else if (mIns[i].ChangesXReg() || mIns[i].ChangesZeroPage(xreg))
|
else if (mIns[i].ChangesXReg() || mIns[i].ChangesZeroPage(xreg))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (this == head)
|
if (this == head)
|
||||||
return true;
|
return true;
|
||||||
|
@ -37111,15 +37108,12 @@ bool NativeCodeBasicBlock::CheckLoopIndexXRegisters(NativeCodeBasicBlock* head,
|
||||||
bool NativeCodeBasicBlock::CheckLoopIndexYRegisters(NativeCodeBasicBlock* head, int yreg)
|
bool NativeCodeBasicBlock::CheckLoopIndexYRegisters(NativeCodeBasicBlock* head, int yreg)
|
||||||
{
|
{
|
||||||
for (int i = mIns.Size() - 1; i >= 0; i--)
|
for (int i = mIns.Size() - 1; i >= 0; i--)
|
||||||
{
|
|
||||||
if (mIns[i].ChangesYReg())
|
|
||||||
{
|
{
|
||||||
if ((mIns[i].mType == ASMIT_LDY || mIns[i].mType == ASMIT_STY) && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == yreg)
|
if ((mIns[i].mType == ASMIT_LDY || mIns[i].mType == ASMIT_STY) && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == yreg)
|
||||||
return true;
|
return true;
|
||||||
else if (mIns[i].ChangesYReg() || mIns[i].ChangesZeroPage(yreg))
|
else if (mIns[i].ChangesYReg() || mIns[i].ChangesZeroPage(yreg))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (this == head)
|
if (this == head)
|
||||||
return true;
|
return true;
|
||||||
|
@ -38922,8 +38916,17 @@ bool NativeCodeBasicBlock::OptimizeLoopRegisterWrapAround(void)
|
||||||
mIns[j].mLive |= LIVE_CPU_REG_X;
|
mIns[j].mLive |= LIVE_CPU_REG_X;
|
||||||
for (int j = 0; j < i; j++)
|
for (int j = 0; j < i; j++)
|
||||||
hblock->mIns[j].mLive |= LIVE_CPU_REG_X;
|
hblock->mIns[j].mLive |= LIVE_CPU_REG_X;
|
||||||
|
if (ins.mLive & LIVE_CPU_REG_Z)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_CPX;
|
||||||
|
ins.mMode = ASMIM_IMMEDIATE;
|
||||||
|
ins.mAddress = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ins.mType = ASMIT_NOP;
|
ins.mType = ASMIT_NOP;
|
||||||
ins.mMode = ASMIM_IMPLIED;
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
}
|
||||||
|
|
||||||
mExitRequiredRegs += CPU_REG_X;
|
mExitRequiredRegs += CPU_REG_X;
|
||||||
pblock->mExitRequiredRegs += CPU_REG_X;
|
pblock->mExitRequiredRegs += CPU_REG_X;
|
||||||
|
@ -43110,6 +43113,44 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BuildSingleExit(NativeCodeProcedure*
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NativeCodeBasicBlock::CorrectXOffset(const InterInstruction * ins, int xoffset, int at)
|
||||||
|
{
|
||||||
|
while (xoffset > 0)
|
||||||
|
{
|
||||||
|
mIns.Insert(at, NativeCodeInstruction(ins, ASMIT_DEX));
|
||||||
|
at++;
|
||||||
|
xoffset--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (xoffset < 0)
|
||||||
|
{
|
||||||
|
mIns.Insert(at, NativeCodeInstruction(ins, ASMIT_INX));
|
||||||
|
at++;
|
||||||
|
xoffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return at;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NativeCodeBasicBlock::CorrectYOffset(const InterInstruction * ins, int yoffset, int at)
|
||||||
|
{
|
||||||
|
while (yoffset > 0)
|
||||||
|
{
|
||||||
|
mIns.Insert(at, NativeCodeInstruction(ins, ASMIT_DEY));
|
||||||
|
at++;
|
||||||
|
yoffset--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (yoffset < 0)
|
||||||
|
{
|
||||||
|
mIns.Insert(at, NativeCodeInstruction(ins, ASMIT_INY));
|
||||||
|
at++;
|
||||||
|
yoffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return at;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::OptimizeGenericLoop(void)
|
bool NativeCodeBasicBlock::OptimizeGenericLoop(void)
|
||||||
{
|
{
|
||||||
|
@ -43642,19 +43683,14 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(void)
|
||||||
|
|
||||||
if (yoffset && yreg >= 0 && !(ins.mLive & LIVE_CPU_REG_Y))
|
if (yoffset && yreg >= 0 && !(ins.mLive & LIVE_CPU_REG_Y))
|
||||||
{
|
{
|
||||||
while (yoffset > 0)
|
if (j + 1 == block->mIns.Size() && (ins.mLive & LIVE_CPU_REG_Z) && ins.mType == ASMIT_CMP)
|
||||||
{
|
{
|
||||||
j++;
|
printf("oopsie Y\n");
|
||||||
block->mIns.Insert(j, NativeCodeInstruction(ins.mIns, ASMIT_DEY));
|
|
||||||
yoffset--;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
while (yoffset < 0)
|
|
||||||
{
|
{
|
||||||
j++;
|
j = block->CorrectYOffset(ins.mIns, yoffset, j + 1) - 1;
|
||||||
block->mIns.Insert(j, NativeCodeInstruction(ins.mIns, ASMIT_INY));
|
yoffset = 0;
|
||||||
yoffset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j + 1 == block->mIns.Size() && (ins.mLive & LIVE_CPU_REG_Z) && ins.ChangesAccuAndFlag())
|
if (j + 1 == block->mIns.Size() && (ins.mLive & LIVE_CPU_REG_Z) && ins.ChangesAccuAndFlag())
|
||||||
{
|
{
|
||||||
|
@ -43662,22 +43698,18 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(void)
|
||||||
block->mIns.Push(NativeCodeInstruction(ins.mIns, ASMIT_ORA, ASMIM_IMMEDIATE, 0));
|
block->mIns.Push(NativeCodeInstruction(ins.mIns, ASMIT_ORA, ASMIM_IMMEDIATE, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (xoffset && xreg >= 0 && !(ins.mLive & LIVE_CPU_REG_X))
|
if (xoffset && xreg >= 0 && !(ins.mLive & LIVE_CPU_REG_X))
|
||||||
{
|
{
|
||||||
while (xoffset > 0)
|
if (j + 1 == block->mIns.Size() && (ins.mLive & LIVE_CPU_REG_Z) && ins.mType == ASMIT_CMP)
|
||||||
{
|
{
|
||||||
j++;
|
printf("oopsie X\n");
|
||||||
block->mIns.Insert(j, NativeCodeInstruction(ins.mIns, ASMIT_DEX));
|
|
||||||
xoffset--;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
while (xoffset < 0)
|
|
||||||
{
|
{
|
||||||
j++;
|
j = block->CorrectXOffset(ins.mIns, xoffset, j + 1) - 1;
|
||||||
block->mIns.Insert(j, NativeCodeInstruction(ins.mIns, ASMIT_INX));
|
xoffset = 0;
|
||||||
xoffset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j + 1 == block->mIns.Size() && (ins.mLive & LIVE_CPU_REG_Z) && ins.ChangesAccuAndFlag())
|
if (j + 1 == block->mIns.Size() && (ins.mLive & LIVE_CPU_REG_Z) && ins.ChangesAccuAndFlag())
|
||||||
{
|
{
|
||||||
|
@ -43685,6 +43717,7 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(void)
|
||||||
block->mIns.Push(NativeCodeInstruction(ins.mIns, ASMIT_ORA, ASMIM_IMMEDIATE, 0));
|
block->mIns.Push(NativeCodeInstruction(ins.mIns, ASMIT_ORA, ASMIM_IMMEDIATE, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (yreg >= 0)
|
if (yreg >= 0)
|
||||||
ins.mLive |= LIVE_CPU_REG_Y;
|
ins.mLive |= LIVE_CPU_REG_Y;
|
||||||
|
@ -43695,7 +43728,9 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block->mTrueJump && !lblocks.Contains(block->mTrueJump))
|
if (block->mTrueJump)
|
||||||
|
{
|
||||||
|
if (!lblocks.Contains(block->mTrueJump))
|
||||||
{
|
{
|
||||||
block->mTrueJump = block->BuildSingleEntry(mProc, block->mTrueJump);
|
block->mTrueJump = block->BuildSingleEntry(mProc, block->mTrueJump);
|
||||||
if (areg >= 0 && block->mTrueJump->mEntryRequiredRegs[areg])
|
if (areg >= 0 && block->mTrueJump->mEntryRequiredRegs[areg])
|
||||||
|
@ -43707,18 +43742,32 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(void)
|
||||||
}
|
}
|
||||||
if (yreg >= 0 && block->mTrueJump->mEntryRequiredRegs[yreg])
|
if (yreg >= 0 && block->mTrueJump->mEntryRequiredRegs[yreg])
|
||||||
{
|
{
|
||||||
block->mTrueJump->mIns.Insert(0, NativeCodeInstruction(block->mBranchIns, ASMIT_STY, ASMIM_ZERO_PAGE, yreg));
|
int j = block->mTrueJump->CorrectYOffset(block->mBranchIns, yoffset, 0);
|
||||||
|
block->mTrueJump->mIns.Insert(j, NativeCodeInstruction(block->mBranchIns, ASMIT_STY, ASMIM_ZERO_PAGE, yreg));
|
||||||
|
|
||||||
block->mExitRequiredRegs += CPU_REG_Y;
|
block->mExitRequiredRegs += CPU_REG_Y;
|
||||||
block->mTrueJump->mEntryRequiredRegs += CPU_REG_Y;
|
block->mTrueJump->mEntryRequiredRegs += CPU_REG_Y;
|
||||||
}
|
}
|
||||||
if (xreg >= 0 && block->mTrueJump->mEntryRequiredRegs[xreg])
|
if (xreg >= 0 && block->mTrueJump->mEntryRequiredRegs[xreg])
|
||||||
{
|
{
|
||||||
block->mTrueJump->mIns.Insert(0, NativeCodeInstruction(block->mBranchIns, ASMIT_STX, ASMIM_ZERO_PAGE, xreg));
|
int j = block->mTrueJump->CorrectXOffset(block->mBranchIns, xoffset, 0);
|
||||||
|
|
||||||
|
block->mTrueJump->mIns.Insert(j, NativeCodeInstruction(block->mBranchIns, ASMIT_STX, ASMIM_ZERO_PAGE, xreg));
|
||||||
block->mExitRequiredRegs += CPU_REG_X;
|
block->mExitRequiredRegs += CPU_REG_X;
|
||||||
block->mTrueJump->mEntryRequiredRegs += CPU_REG_X;
|
block->mTrueJump->mEntryRequiredRegs += CPU_REG_X;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (block->mFalseJump && !lblocks.Contains(block->mFalseJump))
|
else
|
||||||
|
{
|
||||||
|
if (yreg >= 0 && yoffset != 0 && block->mFalseJump->mEntryRequiredRegs[yreg])
|
||||||
|
block->mTrueJump->CorrectYOffset(block->mBranchIns, yoffset, 0);
|
||||||
|
if (xreg >= 0 && xoffset != 0 && block->mFalseJump->mEntryRequiredRegs[xreg])
|
||||||
|
block->mTrueJump->CorrectXOffset(block->mBranchIns, xoffset, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (block->mFalseJump)
|
||||||
|
{
|
||||||
|
if (!lblocks.Contains(block->mFalseJump))
|
||||||
{
|
{
|
||||||
block->mFalseJump = block->BuildSingleEntry(mProc, block->mFalseJump);
|
block->mFalseJump = block->BuildSingleEntry(mProc, block->mFalseJump);
|
||||||
if (areg >= 0 && block->mFalseJump->mEntryRequiredRegs[areg])
|
if (areg >= 0 && block->mFalseJump->mEntryRequiredRegs[areg])
|
||||||
|
@ -43730,17 +43779,27 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(void)
|
||||||
}
|
}
|
||||||
if (yreg >= 0 && block->mFalseJump->mEntryRequiredRegs[yreg])
|
if (yreg >= 0 && block->mFalseJump->mEntryRequiredRegs[yreg])
|
||||||
{
|
{
|
||||||
block->mFalseJump->mIns.Insert(0, NativeCodeInstruction(block->mBranchIns, ASMIT_STY, ASMIM_ZERO_PAGE, yreg));
|
int j = block->mTrueJump->CorrectYOffset(block->mBranchIns, yoffset, 0);
|
||||||
|
block->mFalseJump->mIns.Insert(j, NativeCodeInstruction(block->mBranchIns, ASMIT_STY, ASMIM_ZERO_PAGE, yreg));
|
||||||
block->mExitRequiredRegs += CPU_REG_Y;
|
block->mExitRequiredRegs += CPU_REG_Y;
|
||||||
block->mFalseJump->mEntryRequiredRegs += CPU_REG_Y;
|
block->mFalseJump->mEntryRequiredRegs += CPU_REG_Y;
|
||||||
}
|
}
|
||||||
if (xreg >= 0 && block->mFalseJump->mEntryRequiredRegs[xreg])
|
if (xreg >= 0 && block->mFalseJump->mEntryRequiredRegs[xreg])
|
||||||
{
|
{
|
||||||
block->mFalseJump->mIns.Insert(0, NativeCodeInstruction(block->mBranchIns, ASMIT_STX, ASMIM_ZERO_PAGE, xreg));
|
int j = block->mTrueJump->CorrectXOffset(block->mBranchIns, xoffset, 0);
|
||||||
|
block->mFalseJump->mIns.Insert(j, NativeCodeInstruction(block->mBranchIns, ASMIT_STX, ASMIM_ZERO_PAGE, xreg));
|
||||||
block->mExitRequiredRegs += CPU_REG_X;
|
block->mExitRequiredRegs += CPU_REG_X;
|
||||||
block->mFalseJump->mEntryRequiredRegs += CPU_REG_X;
|
block->mFalseJump->mEntryRequiredRegs += CPU_REG_X;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (yreg >= 0 && yoffset != 0 && block->mFalseJump->mEntryRequiredRegs[yreg])
|
||||||
|
block->mFalseJump->CorrectYOffset(block->mBranchIns, yoffset, 0);
|
||||||
|
if (xreg >= 0 && xoffset != 0 && block->mFalseJump->mEntryRequiredRegs[xreg])
|
||||||
|
block->mFalseJump->CorrectXOffset(block->mBranchIns, xoffset, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
block->CheckLive();
|
block->CheckLive();
|
||||||
}
|
}
|
||||||
|
@ -44275,7 +44334,8 @@ bool NativeCodeBasicBlock::BlockSizeCopyReduction(NativeCodeProcedure* proc, int
|
||||||
#if 1
|
#if 1
|
||||||
if (si + 5 < mIns.Size() &&
|
if (si + 5 < mIns.Size() &&
|
||||||
mIns[si + 0].mType == ASMIT_LDY && mIns[si + 0].mMode == ASMIM_IMMEDIATE &&
|
mIns[si + 0].mType == ASMIT_LDY && mIns[si + 0].mMode == ASMIM_IMMEDIATE &&
|
||||||
mIns[si + 1].mType == ASMIT_STA && mIns[si + 1].mMode == ASMIM_INDIRECT_Y)
|
mIns[si + 1].mType == ASMIT_STA && mIns[si + 1].mMode == ASMIM_INDIRECT_Y &&
|
||||||
|
!(mIns[si + 1].mLive & LIVE_CPU_REG_C))
|
||||||
{
|
{
|
||||||
int i = 1;
|
int i = 1;
|
||||||
while (si + 2 * i + 1 < mIns.Size() &&
|
while (si + 2 * i + 1 < mIns.Size() &&
|
||||||
|
@ -48956,6 +49016,28 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate3(int i, int pass)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 0].mMode) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_TAX &&
|
||||||
|
mIns[i + 2].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPX, mIns[i + 2].mMode) && !(mIns[i + 2].mLive & LIVE_CPU_REG_A))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_CPX;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDY, mIns[i + 0].mMode) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_TAY &&
|
||||||
|
mIns[i + 2].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPY, mIns[i + 2].mMode) && !(mIns[i + 2].mLive & LIVE_CPU_REG_A))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_CPY;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
mIns[i + 0].mType == ASMIT_LDA && !mIns[i + 0].RequiresXReg() &&
|
mIns[i + 0].mType == ASMIT_LDA && !mIns[i + 0].RequiresXReg() &&
|
||||||
mIns[i + 1].mType == ASMIT_LDX &&
|
mIns[i + 1].mType == ASMIT_LDX &&
|
||||||
|
@ -55848,7 +55930,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
|
|
||||||
mInterProc->mLinkerObject->mNativeProc = this;
|
mInterProc->mLinkerObject->mNativeProc = this;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "sidfx_loop");
|
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
@ -57915,8 +57997,8 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
if (mEntryBlock->ApplyEntryDataSet())
|
if (mEntryBlock->ApplyEntryDataSet())
|
||||||
changed = true;
|
changed = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->BlockSizeReduction(this, -1, -1, -1);
|
mEntryBlock->BlockSizeReduction(this, -1, -1, -1);
|
||||||
|
|
||||||
|
|
|
@ -373,6 +373,8 @@ public:
|
||||||
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
||||||
NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||||
|
|
||||||
|
int CorrectXOffset(const InterInstruction * ins, int yoffset, int at);
|
||||||
|
int CorrectYOffset(const InterInstruction * ins, int yoffset, int at);
|
||||||
bool OptimizeGenericLoop(void);
|
bool OptimizeGenericLoop(void);
|
||||||
bool CollectGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
bool CollectGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||||
bool CollectSingleEntryGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
bool CollectSingleEntryGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||||
|
|
|
@ -515,6 +515,12 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mdec->mBits == 24 && mdec->mOffset > 0 && mdec->mShift == 0)
|
||||||
|
{
|
||||||
|
mdec->mOffset--;
|
||||||
|
mdec->mShift = 8;
|
||||||
|
}
|
||||||
|
|
||||||
if (mdec->mShift == 0 && mdec->mBits == 8 * mdec->mSize)
|
if (mdec->mShift == 0 && mdec->mBits == 8 * mdec->mSize)
|
||||||
mdec->mBits = 0;
|
mdec->mBits = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue