Optimize select statement
This commit is contained in:
parent
3e59f47748
commit
4daecdc51a
|
@ -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
|
bool Expression::IsSame(const Expression* exp) const
|
||||||
{
|
{
|
||||||
if (!exp || mType != exp->mType)
|
if (!exp || mType != exp->mType)
|
||||||
|
|
|
@ -165,6 +165,7 @@ public:
|
||||||
|
|
||||||
Expression* LogicInvertExpression(void);
|
Expression* LogicInvertExpression(void);
|
||||||
Expression* ConstantFold(Errors * errors);
|
Expression* ConstantFold(Errors * errors);
|
||||||
|
bool HasSideEffects(void) const;
|
||||||
|
|
||||||
bool IsSame(const Expression* exp) const;
|
bool IsSame(const Expression* exp) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2659,6 +2659,37 @@ void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, Nu
|
||||||
requiredParams += mSrc[0].mVarIndex;
|
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)
|
else if (mCode == IC_STORE)
|
||||||
{
|
{
|
||||||
if (mSrc[1].mMemory == IM_LOCAL)
|
if (mSrc[1].mMemory == IM_LOCAL)
|
||||||
|
@ -2828,7 +2859,7 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
|
||||||
this->ConstantFolding();
|
this->ConstantFolding();
|
||||||
return true;
|
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];
|
InterInstruction* ains = ctemps[mSrc[1].mTemp];
|
||||||
mSrc[1] = ains->mConst;
|
mSrc[1] = ains->mConst;
|
||||||
|
@ -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
|
mVisited = true;
|
||||||
case 2: // SHR 2
|
|
||||||
case 4: // SHR 1
|
if (mTrueJump && mFalseJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump && mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1)
|
||||||
case 8:
|
{
|
||||||
case 16: // * 2
|
// we have a diamond situation
|
||||||
case 32: // * 4
|
InterCodeBasicBlock* mb0 = mTrueJump->mTrueJump;
|
||||||
case 64: // * 8
|
if (mb0 && mb0->mNumEntries == 2)
|
||||||
case 128: // LEA r * 2, * 8
|
{
|
||||||
case 192: // LEA r, r * 2, * 8
|
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)
|
||||||
case 256: // LEA r * 4, * 8
|
{
|
||||||
case 512: // LEA r * 8, * 8
|
// we have a dual diamond
|
||||||
return true;
|
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)
|
static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, int offset)
|
||||||
|
@ -7522,15 +7603,46 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
|
||||||
{
|
{
|
||||||
InterInstruction* pins = ltvalue[ins->mSrc[1].mTemp];
|
InterInstruction* pins = ltvalue[ins->mSrc[1].mTemp];
|
||||||
|
|
||||||
if (ins->mSrc[1].mMemory == IM_INDIRECT && pins->mCode == IC_LEA)
|
if (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)
|
|
||||||
{
|
{
|
||||||
ins->mSrc[1].Forward(pins->mSrc[1]);
|
if (ins->mSrc[1].mMemory == IM_INDIRECT)
|
||||||
pins->mSrc[1].mFinal = false;
|
{
|
||||||
ins->mSrc[1].mIntConst += pins->mSrc[0].mIntConst;
|
ins->mSrc[1].mLinkerObject = pins->mSrc[1].mLinkerObject;
|
||||||
changed = true;
|
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;
|
break;
|
||||||
|
@ -7544,7 +7656,10 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
|
||||||
if (pins->mCode == IC_LEA)
|
if (pins->mCode == IC_LEA)
|
||||||
{
|
{
|
||||||
if (ins->mSrc[0].mMemory == IM_INDIRECT)
|
if (ins->mSrc[0].mMemory == IM_INDIRECT)
|
||||||
|
{
|
||||||
ins->mSrc[0].mLinkerObject = pins->mSrc[1].mLinkerObject;
|
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)
|
if (pins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst + pins->mSrc[0].mIntConst >= 0)
|
||||||
{
|
{
|
||||||
|
@ -9119,8 +9234,10 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
|
||||||
{
|
{
|
||||||
trueExitRequiredTemps += ins->mSrc[j].mTemp;
|
trueExitRequiredTemps += ins->mSrc[j].mTemp;
|
||||||
mTrueJump->mEntryRequiredTemps += ins->mSrc[j].mTemp;
|
mTrueJump->mEntryRequiredTemps += ins->mSrc[j].mTemp;
|
||||||
|
mTrueJump->mLocalUsedTemps += ins->mSrc[j].mTemp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mTrueJump->mLocalModifiedTemps += dtemp;
|
||||||
mTrueJump->mInstructions.Insert(0, ins);
|
mTrueJump->mInstructions.Insert(0, ins);
|
||||||
mInstructions.Remove(i);
|
mInstructions.Remove(i);
|
||||||
moved = true;
|
moved = true;
|
||||||
|
@ -9134,8 +9251,10 @@ bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
|
||||||
{
|
{
|
||||||
falseExitRequiredTems += ins->mSrc[j].mTemp;
|
falseExitRequiredTems += ins->mSrc[j].mTemp;
|
||||||
mFalseJump->mEntryRequiredTemps += ins->mSrc[j].mTemp;
|
mFalseJump->mEntryRequiredTemps += ins->mSrc[j].mTemp;
|
||||||
|
mFalseJump->mLocalUsedTemps += ins->mSrc[j].mTemp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mFalseJump->mLocalModifiedTemps += dtemp;
|
||||||
mFalseJump->mInstructions.Insert(0, ins);
|
mFalseJump->mInstructions.Insert(0, ins);
|
||||||
mInstructions.Remove(i);
|
mInstructions.Remove(i);
|
||||||
moved = true;
|
moved = true;
|
||||||
|
@ -12032,6 +12151,31 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
|
||||||
}
|
}
|
||||||
break;
|
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_STORE:
|
||||||
case IC_LOAD:
|
case IC_LOAD:
|
||||||
case IC_COPY:
|
case IC_COPY:
|
||||||
|
@ -13334,6 +13478,22 @@ void InterCodeProcedure::Close(void)
|
||||||
CheckUsedDefinedTemps();
|
CheckUsedDefinedTemps();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
BuildTraces(false);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
if (mEntryBlock->MergeSameConditionTraces())
|
||||||
|
{
|
||||||
|
ResetEntryBlocks();
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CollectEntryBlocks(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildDataFlowSets();
|
||||||
|
|
||||||
|
CheckUsedDefinedTemps();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
RebuildIntegerRangeSet();
|
RebuildIntegerRangeSet();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -379,6 +379,8 @@ public:
|
||||||
void GenerateTraces(bool expand, bool compact);
|
void GenerateTraces(bool expand, bool compact);
|
||||||
void BuildDominatorTree(InterCodeBasicBlock * from);
|
void BuildDominatorTree(InterCodeBasicBlock * from);
|
||||||
|
|
||||||
|
bool MergeSameConditionTraces(void);
|
||||||
|
|
||||||
void LocalToTemp(int vindex, int temp);
|
void LocalToTemp(int vindex, int temp);
|
||||||
|
|
||||||
void CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used);
|
void CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used);
|
||||||
|
|
|
@ -2850,8 +2850,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
case EX_CONDITIONAL:
|
case EX_CONDITIONAL:
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
if ((exp->mRight->mLeft->mType == EX_CONSTANT || exp->mRight->mLeft->mType == EX_VARIABLE) &&
|
if (!exp->mRight->mLeft->HasSideEffects() && !exp->mRight->mRight->HasSideEffects())
|
||||||
(exp->mRight->mRight->mType == EX_CONSTANT || exp->mRight->mRight->mType == EX_VARIABLE))
|
|
||||||
{
|
{
|
||||||
ExValue vc = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper);
|
ExValue vc = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue