Skip to content

Commit

Permalink
Optimize select statement
Browse files Browse the repository at this point in the history
  • Loading branch information
drmortalwombat committed Oct 3, 2022
1 parent 3e59f47 commit 4daecdc
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 26 deletions.
24 changes: 24 additions & 0 deletions oscar64/Declaration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,30 @@ Expression::~Expression(void)

}

bool Expression::HasSideEffects(void) const
{
switch (mType)
{
case EX_VARIABLE:
case EX_CONSTANT:
return false;

case EX_BINARY:
case EX_RELATIONAL:
case EX_INDEX:
return mLeft->HasSideEffects() || mRight->HasSideEffects();

case EX_QUALIFY:
case EX_TYPECAST:
case EX_PREFIX:
case EX_POSTFIX:
return mLeft->HasSideEffects();

default:
return true;
}
}

bool Expression::IsSame(const Expression* exp) const
{
if (!exp || mType != exp->mType)
Expand Down
1 change: 1 addition & 0 deletions oscar64/Declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class Expression

Expression* LogicInvertExpression(void);
Expression* ConstantFold(Errors * errors);
bool HasSideEffects(void) const;

bool IsSame(const Expression* exp) const;
};
Expand Down
208 changes: 184 additions & 24 deletions oscar64/InterCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2659,6 +2659,37 @@ void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, Nu
requiredParams += mSrc[0].mVarIndex;
}
}
#if 0
else if (mCode == IC_LEA)
{
if (mSrc[1].mMemory == IM_LOCAL)
{
assert(mSrc[1].mTemp < 0);
if (!providedVars[mSrc[1].mVarIndex])
requiredVars += mSrc[1].mVarIndex;
}
else if (mSrc[1].mMemory == paramMemory)
{
assert(mSrc[1].mTemp < 0);
if (!providedParams[mSrc[1].mVarIndex])
requiredParams += mSrc[1].mVarIndex;
}
}
else if (mCode == IC_CONSTANT)
{
if (mConst.mMemory == IM_LOCAL)
{
if (!providedVars[mConst.mVarIndex])
requiredVars += mConst.mVarIndex;
}
else if (mConst.mMemory == paramMemory)
{
assert(mConst.mTemp < 0);
if (!providedParams[mConst.mVarIndex])
requiredParams += mConst.mVarIndex;
}
}
#endif
else if (mCode == IC_STORE)
{
if (mSrc[1].mMemory == IM_LOCAL)
Expand Down Expand Up @@ -2828,7 +2859,7 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
this->ConstantFolding();
return true;
}
else if (mSrc[0].mTemp < 0 && mSrc[1].mTemp >= 0 && ctemps[mSrc[1].mTemp])
else if (mSrc[1].mTemp >= 0 && ctemps[mSrc[1].mTemp])
{
InterInstruction* ains = ctemps[mSrc[1].mTemp];
mSrc[1] = ains->mConst;
Expand Down Expand Up @@ -3909,25 +3940,75 @@ void InterCodeBasicBlock::GenerateTraces(bool expand, bool compact)
}
}

static bool IsSimpleAddressMultiply(int val)
bool InterCodeBasicBlock::MergeSameConditionTraces(void)
{
switch (val)
bool changed = false;

if (!mVisited)
{
case 1: // SHR 3
case 2: // SHR 2
case 4: // SHR 1
case 8:
case 16: // * 2
case 32: // * 4
case 64: // * 8
case 128: // LEA r * 2, * 8
case 192: // LEA r, r * 2, * 8
case 256: // LEA r * 4, * 8
case 512: // LEA r * 8, * 8
return true;
mVisited = true;

if (mTrueJump && mFalseJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump && mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1)
{
// we have a diamond situation
InterCodeBasicBlock* mb0 = mTrueJump->mTrueJump;
if (mb0 && mb0->mNumEntries == 2)
{
if (mb0->mTrueJump && mb0->mFalseJump && !mb0->mTrueJump->mFalseJump && !mb0->mFalseJump->mFalseJump && mb0->mTrueJump->mTrueJump == mb0->mFalseJump->mTrueJump && mb0->mTrueJump->mNumEntries == 1 && mb0->mFalseJump->mNumEntries == 1)
{
// we have a dual diamond
InterCodeBasicBlock* mb1 = mb0->mTrueJump->mTrueJump;
if (mb1 && mb1->mNumEntries == 2 && mb0 != mb1)
{
int tc = mInstructions.Last()->mSrc[0].mTemp;
if (tc == mb0->mInstructions.Last()->mSrc[0].mTemp)
{
if (!mTrueJump->mLocalModifiedTemps[tc] && !mFalseJump->mLocalModifiedTemps[tc] && !mb0->mLocalModifiedTemps[tc])
{
// Same conditions in both diamonds
if (mb0->mInstructions.Size() < 8)
{
// Join blocks

mTrueJump->mInstructions.Remove(mTrueJump->mInstructions.Size() - 1);
mFalseJump->mInstructions.Remove(mFalseJump->mInstructions.Size() - 1);

for (int i = 0; i + 1 < mb0->mInstructions.Size(); i++)
{
mTrueJump->mInstructions.Push(mb0->mInstructions[i]->Clone());
mFalseJump->mInstructions.Push(mb0->mInstructions[i]->Clone());
}

for(int i=0; i<mb0->mTrueJump->mInstructions.Size(); i++)
mTrueJump->mInstructions.Push(mb0->mTrueJump->mInstructions[i]->Clone());
for (int i = 0; i < mb0->mFalseJump->mInstructions.Size(); i++)
mFalseJump->mInstructions.Push(mb0->mFalseJump->mInstructions[i]->Clone());

mTrueJump->mLocalModifiedTemps |= mb0->mLocalModifiedTemps;
mFalseJump->mLocalModifiedTemps |= mb0->mLocalModifiedTemps;
mTrueJump->mLocalModifiedTemps |= mb0->mTrueJump->mLocalModifiedTemps;
mFalseJump->mLocalModifiedTemps |= mb0->mFalseJump->mLocalModifiedTemps;

mTrueJump->mTrueJump = mb1;
mFalseJump->mTrueJump = mb1;

changed = true;
}
}
}
}

}
}
}

if (mTrueJump && mTrueJump->MergeSameConditionTraces())
changed = true;
if (mFalseJump && mFalseJump->MergeSameConditionTraces())
changed = true;
}

return false;
return changed;
}

static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, int offset)
Expand Down Expand Up @@ -7522,15 +7603,46 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
{
InterInstruction* pins = ltvalue[ins->mSrc[1].mTemp];

if (ins->mSrc[1].mMemory == IM_INDIRECT && pins->mCode == IC_LEA)
ins->mSrc[1].mLinkerObject = pins->mSrc[1].mLinkerObject;

if (pins->mCode == IC_LEA && pins->mSrc[0].mTemp < 0 && ins->mSrc[1].mIntConst + pins->mSrc[0].mIntConst >= 0)
if (pins->mCode == IC_LEA)
{
ins->mSrc[1].Forward(pins->mSrc[1]);
pins->mSrc[1].mFinal = false;
ins->mSrc[1].mIntConst += pins->mSrc[0].mIntConst;
changed = true;
if (ins->mSrc[1].mMemory == IM_INDIRECT)
{
ins->mSrc[1].mLinkerObject = pins->mSrc[1].mLinkerObject;
ins->mSrc[1].mVarIndex = pins->mSrc[1].mVarIndex;
}

if (pins->mSrc[0].mTemp < 0 && ins->mSrc[1].mIntConst + pins->mSrc[0].mIntConst >= 0)
{
ins->mSrc[1].Forward(pins->mSrc[1]);
pins->mSrc[1].mFinal = false;
ins->mSrc[1].mIntConst += pins->mSrc[0].mIntConst;
changed = true;
}
#if 1
else if (pins->mSrc[1].mTemp < 0 && pins->mSrc[0].mTemp >= 0 && ins->mSrc[1].mIntConst && (ins->mSrc[1].mIntConst >= 256 || pins->mSrc[0].IsUByte()))
{
int k = mInstructions.IndexOf(pins);
if (k >= 0)
{
if (spareTemps + 2 >= ltvalue.Size())
return true;

InterInstruction* nins = new InterInstruction();
nins->mCode = IC_LEA;
nins->mSrc[0].Forward(pins->mSrc[0]);
nins->mSrc[1].ForwardMem(pins->mSrc[1]);
nins->mSrc[1].mIntConst += ins->mSrc[1].mIntConst;
nins->mDst.mTemp = spareTemps++;
nins->mDst.mType = IT_POINTER;
nins->mDst.mRange = ins->mDst.mRange;
ins->mSrc[1].mIntConst = 0;
ins->mSrc[1].mTemp = nins->mDst.mTemp;

mInstructions.Insert(k + 1, nins);
changed = true;
}
}
#endif
}
}
break;
Expand All @@ -7544,7 +7656,10 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
if (pins->mCode == IC_LEA)
{
if (ins->mSrc[0].mMemory == IM_INDIRECT)
{
ins->mSrc[0].mLinkerObject = pins->mSrc[1].mLinkerObject;
ins->mSrc[0].mVarIndex = pins->mSrc[1].mVarIndex;
}

if (pins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst + pins->mSrc[0].mIntConst >= 0)
{
Expand Down Expand Up @@ -9119,8 +9234,10 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
{
trueExitRequiredTemps += ins->mSrc[j].mTemp;
mTrueJump->mEntryRequiredTemps += ins->mSrc[j].mTemp;
mTrueJump->mLocalUsedTemps += ins->mSrc[j].mTemp;
}
}
mTrueJump->mLocalModifiedTemps += dtemp;
mTrueJump->mInstructions.Insert(0, ins);
mInstructions.Remove(i);
moved = true;
Expand All @@ -9134,8 +9251,10 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
{
falseExitRequiredTems += ins->mSrc[j].mTemp;
mFalseJump->mEntryRequiredTemps += ins->mSrc[j].mTemp;
mFalseJump->mLocalUsedTemps += ins->mSrc[j].mTemp;
}
}
mFalseJump->mLocalModifiedTemps += dtemp;
mFalseJump->mInstructions.Insert(0, ins);
mInstructions.Remove(i);
moved = true;
Expand Down Expand Up @@ -12032,6 +12151,31 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
}
break;

case IC_LEA:
if (ins->mSrc[1].mMemory == IM_LOCAL)
{
int varIndex = ins->mSrc[1].mVarIndex;
if (!localVars[varIndex])
localVars[varIndex] = new InterVariable;

int size = ins->mSrc[1].mOperandSize + ins->mSrc[1].mIntConst;
if (size > localVars[varIndex]->mSize)
localVars[varIndex]->mSize = size;
localVars[varIndex]->mAliased = true;
}
else if (ins->mSrc[1].mMemory == paramMemory)
{
int varIndex = ins->mSrc[1].mVarIndex;
if (!paramVars[varIndex])
paramVars[varIndex] = new InterVariable;

int size = ins->mSrc[1].mOperandSize + ins->mSrc[1].mIntConst;
if (size > paramVars[varIndex]->mSize)
paramVars[varIndex]->mSize = size;
paramVars[varIndex]->mAliased = true;
}
break;

case IC_STORE:
case IC_LOAD:
case IC_COPY:
Expand Down Expand Up @@ -13334,6 +13478,22 @@ void InterCodeProcedure::Close(void)
CheckUsedDefinedTemps();
#endif

#if 1
BuildTraces(false);

ResetVisited();
if (mEntryBlock->MergeSameConditionTraces())
{
ResetEntryBlocks();
ResetVisited();
mEntryBlock->CollectEntryBlocks(nullptr);
}

BuildDataFlowSets();

CheckUsedDefinedTemps();
#endif

#if 1
RebuildIntegerRangeSet();
#endif
Expand Down
2 changes: 2 additions & 0 deletions oscar64/InterCode.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ class InterCodeBasicBlock
void GenerateTraces(bool expand, bool compact);
void BuildDominatorTree(InterCodeBasicBlock * from);

bool MergeSameConditionTraces(void);

void LocalToTemp(int vindex, int temp);

void CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used);
Expand Down
3 changes: 1 addition & 2 deletions oscar64/InterCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2850,8 +2850,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_CONDITIONAL:
{
#if 1
if ((exp->mRight->mLeft->mType == EX_CONSTANT || exp->mRight->mLeft->mType == EX_VARIABLE) &&
(exp->mRight->mRight->mType == EX_CONSTANT || exp->mRight->mRight->mType == EX_VARIABLE))
if (!exp->mRight->mLeft->HasSideEffects() && !exp->mRight->mRight->HasSideEffects())
{
ExValue vc = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper);

Expand Down

0 comments on commit 4daecdc

Please sign in to comment.