Optimize bitfields
This commit is contained in:
parent
4f76ffa311
commit
d160b2ae65
|
@ -232,9 +232,109 @@ void test_word_signed(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_inc_char_fit(void)
|
||||||
|
{
|
||||||
|
A ai;
|
||||||
|
ai.x = 7;
|
||||||
|
ai.y = 1;
|
||||||
|
ai.z = 2;
|
||||||
|
|
||||||
|
for(int i=0; i<16; i++)
|
||||||
|
{
|
||||||
|
assert(ai.x == ((7 + i) & 15));
|
||||||
|
assert(ai.y == ((1 + i) & 1));
|
||||||
|
assert(ai.z == ((2 + i) & 7));
|
||||||
|
ai.x++;
|
||||||
|
ai.y++;
|
||||||
|
ai.z++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_inc_char_cross(void)
|
||||||
|
{
|
||||||
|
B bi;
|
||||||
|
bi.x = 11;
|
||||||
|
bi.y = 22;
|
||||||
|
bi.z = 33;
|
||||||
|
bi.w = 44;
|
||||||
|
|
||||||
|
for(int i=0; i<64; i++)
|
||||||
|
{
|
||||||
|
assert(bi.x == ((11 + i) & 0x3f));
|
||||||
|
assert(bi.y == ((22 + i) & 0x3f));
|
||||||
|
assert(bi.z == ((33 + i) & 0x3f));
|
||||||
|
assert(bi.w == ((44 + i) & 0x3f));
|
||||||
|
bi.x++;
|
||||||
|
bi.y++;
|
||||||
|
bi.z++;
|
||||||
|
bi.w++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_add_char_cross(void)
|
||||||
|
{
|
||||||
|
B bi= {0};
|
||||||
|
bi.x = 11;
|
||||||
|
bi.y = 22;
|
||||||
|
bi.z = 33;
|
||||||
|
bi.w = 44;
|
||||||
|
|
||||||
|
for(int i=0; i<64; i++)
|
||||||
|
{
|
||||||
|
assert(bi.x == ((11 + 5 * i) & 0x3f));
|
||||||
|
assert(bi.y == ((22 + 21 * i) & 0x3f));
|
||||||
|
assert(bi.z == ((33 - 4 * i) & 0x3f));
|
||||||
|
assert(bi.w == ((44 - 11 * i) & 0x3f));
|
||||||
|
bi.x += 5;
|
||||||
|
bi.y += 21;
|
||||||
|
bi.z -= 4;
|
||||||
|
bi.w -= 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_add_word_fit(void)
|
||||||
|
{
|
||||||
|
C ci = {0};
|
||||||
|
|
||||||
|
ci.x = 7;
|
||||||
|
ci.y = 1;
|
||||||
|
ci.z = 2;
|
||||||
|
|
||||||
|
for(int i=0; i<16; i++)
|
||||||
|
{
|
||||||
|
assert(ci.x == ((7 + 5 * i) & 15));
|
||||||
|
assert(ci.y == ((1 + 21 * i) & 1));
|
||||||
|
assert(ci.z == ((2 - 4 * i) & 7));
|
||||||
|
ci.x += 5;
|
||||||
|
ci.y += 21;
|
||||||
|
ci.z -= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_add_word_cross(void)
|
||||||
|
{
|
||||||
|
D di = {0};
|
||||||
|
|
||||||
|
di.x = 111;
|
||||||
|
di.y = 222;
|
||||||
|
di.z = 333;
|
||||||
|
di.w = 444;
|
||||||
|
|
||||||
|
for(int i=0; i<1024; i++)
|
||||||
|
{
|
||||||
|
assert(di.x == ((111 + 5 * i) & 0x3ff));
|
||||||
|
assert(di.y == ((222 + 21 * i) & 0x3ff));
|
||||||
|
assert(di.z == ((333 - 4 * i) & 0x3ff));
|
||||||
|
assert(di.w == ((444 - 11 * i) & 0x3ff));
|
||||||
|
di.x += 5;
|
||||||
|
di.y += 21;
|
||||||
|
di.z -= 4;
|
||||||
|
di.w -= 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
test_char_fit();
|
test_char_fit();
|
||||||
test_char_cross();
|
test_char_cross();
|
||||||
test_word_fit();
|
test_word_fit();
|
||||||
|
@ -244,5 +344,12 @@ int main(void)
|
||||||
test_char_signed();
|
test_char_signed();
|
||||||
test_word_signed();
|
test_word_signed();
|
||||||
|
|
||||||
|
test_inc_char_fit();
|
||||||
|
test_inc_char_cross();
|
||||||
|
test_add_char_cross();
|
||||||
|
#endif
|
||||||
|
test_add_word_fit();
|
||||||
|
test_add_word_cross();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7150,16 +7150,21 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
||||||
else if (ins->mSrc[1].mTemp < 0)
|
else if (ins->mSrc[1].mTemp < 0)
|
||||||
{
|
{
|
||||||
vr = mLocalValueRange[ins->mSrc[0].mTemp];
|
vr = mLocalValueRange[ins->mSrc[0].mTemp];
|
||||||
|
|
||||||
|
IntegerValueRange::State s = vr.mMinState;
|
||||||
|
vr.mMinState = vr.mMaxState;
|
||||||
|
vr.mMaxState = s;
|
||||||
|
|
||||||
int64 maxv = vr.mMaxValue, minv = vr.mMinValue;
|
int64 maxv = vr.mMaxValue, minv = vr.mMinValue;
|
||||||
|
|
||||||
if (vr.mMaxState == IntegerValueRange::S_WEAK)
|
|
||||||
{
|
|
||||||
if (vr.mMinState == IntegerValueRange::S_WEAK)
|
|
||||||
vr.mMaxState = IntegerValueRange::S_UNBOUND;
|
|
||||||
vr.mMinState = IntegerValueRange::S_UNBOUND;
|
|
||||||
}
|
|
||||||
if (vr.mMinState == IntegerValueRange::S_WEAK)
|
if (vr.mMinState == IntegerValueRange::S_WEAK)
|
||||||
|
{
|
||||||
|
if (vr.mMaxState == IntegerValueRange::S_WEAK)
|
||||||
|
vr.mMinState = IntegerValueRange::S_UNBOUND;
|
||||||
vr.mMaxState = IntegerValueRange::S_UNBOUND;
|
vr.mMaxState = IntegerValueRange::S_UNBOUND;
|
||||||
|
}
|
||||||
|
if (vr.mMaxState == IntegerValueRange::S_WEAK)
|
||||||
|
vr.mMinState = IntegerValueRange::S_UNBOUND;
|
||||||
|
|
||||||
vr.mMaxValue = ins->mSrc[1].mIntConst - minv;
|
vr.mMaxValue = ins->mSrc[1].mIntConst - minv;
|
||||||
vr.mMinValue = ins->mSrc[1].mIntConst - maxv;
|
vr.mMinValue = ins->mSrc[1].mIntConst - maxv;
|
||||||
|
@ -9381,7 +9386,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
|
||||||
{
|
{
|
||||||
InterInstruction* ains = ltvalue[pins->mSrc[0].mTemp];
|
InterInstruction* ains = ltvalue[pins->mSrc[0].mTemp];
|
||||||
|
|
||||||
if (ains->mCode == IC_BINARY_OPERATOR && ains->mOperator == IA_ADD && ains->mSrc[0].mTemp < 0)
|
if (ains->mCode == IC_BINARY_OPERATOR && (ains->mOperator == IA_ADD || ains->mOperator == IA_SUB) && ains->mSrc[0].mTemp < 0)
|
||||||
{
|
{
|
||||||
if (spareTemps + 2 >= ltvalue.Size())
|
if (spareTemps + 2 >= ltvalue.Size())
|
||||||
return true;
|
return true;
|
||||||
|
@ -9404,7 +9409,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
|
||||||
nins->mDst.mRange = ins->mDst.mRange;
|
nins->mDst.mRange = ins->mDst.mRange;
|
||||||
mInstructions.Insert(i + 1, nins);
|
mInstructions.Insert(i + 1, nins);
|
||||||
|
|
||||||
ins->mOperator = IA_ADD;
|
ins->mOperator = ains->mOperator;
|
||||||
ins->mSrc[0] = ains->mSrc[0];
|
ins->mSrc[0] = ains->mSrc[0];
|
||||||
ins->mSrc[0].mIntConst <<= nins->mSrc[0].mIntConst;
|
ins->mSrc[0].mIntConst <<= nins->mSrc[0].mIntConst;
|
||||||
ins->mSrc[1] = nins->mDst;
|
ins->mSrc[1] = nins->mDst;
|
||||||
|
@ -15892,7 +15897,94 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
|
||||||
mInstructions[i + 2]->mSrc[0].mIntConst = 0;
|
mInstructions[i + 2]->mSrc[0].mIntConst = 0;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
if (i + 2 < mInstructions.Size() &&
|
||||||
|
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_AND &&
|
||||||
|
mInstructions[i + 0]->mSrc[0].mTemp < 0 &&
|
||||||
|
mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 1]->mOperator == IA_SHR &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].mTemp < 0 &&
|
||||||
|
mInstructions[i + 1]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[1].mFinal &&
|
||||||
|
mInstructions[i + 2]->mCode == IC_RELATIONAL_OPERATOR &&
|
||||||
|
mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal &&
|
||||||
|
mInstructions[i + 2]->mSrc[0].mTemp < 0)
|
||||||
|
{
|
||||||
|
mInstructions[i + 0]->mSrc[0].mIntConst &= ~((1 << mInstructions[i + 1]->mSrc[0].mIntConst) - 1);
|
||||||
|
mInstructions[i + 2]->mSrc[0].mIntConst <<= mInstructions[i + 1]->mSrc[0].mIntConst;
|
||||||
|
mInstructions[i + 2]->mSrc[1] = mInstructions[i + 0]->mDst;
|
||||||
|
mInstructions[i + 1]->mCode = IC_NONE;
|
||||||
|
mInstructions[i + 1]->mNumOperands = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i + 2 < mInstructions.Size() &&
|
||||||
|
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SHR &&
|
||||||
|
mInstructions[i + 0]->mSrc[0].mTemp < 0 &&
|
||||||
|
mInstructions[i + 1]->mCode == IC_RELATIONAL_OPERATOR &&
|
||||||
|
mInstructions[i + 1]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].mTemp < 0)
|
||||||
|
{
|
||||||
|
mInstructions[i + 1]->mSrc[0].mIntConst <<= mInstructions[i + 0]->mSrc[0].mIntConst;
|
||||||
|
|
||||||
|
mInstructions[i + 0]->mOperator = IA_AND;
|
||||||
|
mInstructions[i + 0]->mSrc[0].mIntConst = ~((1 << mInstructions[i + 0]->mSrc[0].mIntConst) - 1);
|
||||||
|
mInstructions[i + 0]->mDst.mRange.Reset();
|
||||||
|
mInstructions[i + 1]->mSrc[1].mRange.Reset();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i + 3 < mInstructions.Size() &&
|
||||||
|
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SHR &&
|
||||||
|
mInstructions[i + 0]->mSrc[0].mTemp < 0 &&
|
||||||
|
|
||||||
|
mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && (mInstructions[i + 1]->mOperator == IA_ADD || mInstructions[i + 1]->mOperator == IA_SUB) &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].mTemp < 0 &&
|
||||||
|
mInstructions[i + 1]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[1].mFinal &&
|
||||||
|
|
||||||
|
mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 2]->mOperator == IA_SHL &&
|
||||||
|
mInstructions[i + 2]->mSrc[0].mTemp < 0 &&
|
||||||
|
mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mFinal &&
|
||||||
|
|
||||||
|
mInstructions[i + 3]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 3]->mOperator == IA_AND &&
|
||||||
|
mInstructions[i + 3]->mSrc[0].mTemp < 0 &&
|
||||||
|
mInstructions[i + 3]->mSrc[1].mTemp == mInstructions[i + 2]->mDst.mTemp && mInstructions[i + 3]->mSrc[1].mFinal &&
|
||||||
|
|
||||||
|
mInstructions[i + 0]->mSrc[0].mIntConst == mInstructions[i + 2]->mSrc[0].mIntConst)
|
||||||
|
{
|
||||||
|
mInstructions[i + 3]->mSrc[0].mIntConst &= ~((1 << mInstructions[i + 0]->mSrc[0].mIntConst) - 1);
|
||||||
|
mInstructions[i + 1]->mSrc[0].mIntConst <<= mInstructions[i + 0]->mSrc[0].mIntConst;
|
||||||
|
|
||||||
|
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mSrc[1];
|
||||||
|
mInstructions[i + 1]->mDst = mInstructions[i + 2]->mDst;
|
||||||
|
|
||||||
|
mInstructions[i + 0]->mCode = IC_NONE;
|
||||||
|
mInstructions[i + 0]->mNumOperands = 0;
|
||||||
|
mInstructions[i + 2]->mCode = IC_NONE;
|
||||||
|
mInstructions[i + 2]->mNumOperands = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (i + 2 < mInstructions.Size() &&
|
||||||
|
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_AND &&
|
||||||
|
mInstructions[i + 0]->mSrc[0].mTemp < 0 &&
|
||||||
|
|
||||||
|
mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && (mInstructions[i + 1]->mOperator == IA_ADD || mInstructions[i + 1]->mOperator == IA_SUB) &&
|
||||||
|
mInstructions[i + 1]->mSrc[0].mTemp < 0 &&
|
||||||
|
mInstructions[i + 1]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[1].mFinal &&
|
||||||
|
|
||||||
|
mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 2]->mOperator == IA_AND &&
|
||||||
|
mInstructions[i + 2]->mSrc[0].mTemp < 0 &&
|
||||||
|
mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mFinal &&
|
||||||
|
|
||||||
|
(mInstructions[i + 0]->mSrc[0].mIntConst & (mInstructions[i + 0]->mSrc[0].mIntConst + 1)) == 0 && // Is power of two - 1
|
||||||
|
(~mInstructions[i + 0]->mSrc[0].mIntConst & mInstructions[i + 1]->mSrc[0].mIntConst) == 0 && // add is part of initial mask
|
||||||
|
(~mInstructions[i + 0]->mSrc[0].mIntConst & mInstructions[i + 2]->mSrc[0].mIntConst) == 0) // final mask is part of initial mask
|
||||||
|
{
|
||||||
|
mInstructions[i + 1]->mSrc[1] = mInstructions[i + 0]->mSrc[1];
|
||||||
|
|
||||||
|
mInstructions[i + 0]->mCode = IC_NONE;
|
||||||
|
mInstructions[i + 0]->mNumOperands = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
if (i + 2 < mInstructions.Size() &&
|
if (i + 2 < mInstructions.Size() &&
|
||||||
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR &&
|
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR &&
|
||||||
|
@ -17925,7 +18017,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "ftoa");
|
CheckFunc = !strcmp(mIdent->mString, "test_add_char_cross");
|
||||||
CheckCase = false;
|
CheckCase = false;
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
@ -18281,6 +18373,7 @@ void InterCodeProcedure::Close(void)
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
|
||||||
DisassembleDebug("Followed Jumps 2");
|
DisassembleDebug("Followed Jumps 2");
|
||||||
|
CheckCase = true;
|
||||||
|
|
||||||
RebuildIntegerRangeSet();
|
RebuildIntegerRangeSet();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue