diff --git a/README.md b/README.md index e5380b3..9d62e71 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The goal is to implement the actual C standard and not some subset for performan ## Limits and Errors -There are still several open areas, but most targets have been reached. The current Dhrystone performance is 61 iterations per second with byte code (11504) and 278 iterations with native code (12184 Bytes). +There are still several open areas, but most targets have been reached. The current Dhrystone performance is 68 iterations per second with byte code (11266) and 295 iterations with native code (11784 Bytes). ### Language @@ -119,7 +119,6 @@ A section of the file can be selected by providing a limit and or an offset into The compiler can be provided with additional information using the built in function __assume(cond). This can be useful to mark unreachable code using __assume(false) for e.g. the default of a switch statement. Another good option is to limit the value range of arguments to allow the compiler using byte operations without the need for integer promotion. - ## Inline Assembler Inline assembler can be embedded inside of any functions, regardles of their compilation target of byte code or native. diff --git a/autotest/autotest.bat b/autotest/autotest.bat index 252f1c9..42be630 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -60,6 +60,9 @@ rem @echo off @call :test testinterval.c @if %errorlevel% neq 0 goto :error +@call :test cmprangeshortcuttest.c +@if %errorlevel% neq 0 goto :error + @call :test floatstringtest.c @if %errorlevel% neq 0 goto :error diff --git a/autotest/cmprangeshortcuttest.c b/autotest/cmprangeshortcuttest.c new file mode 100644 index 0000000..624e544 --- /dev/null +++ b/autotest/cmprangeshortcuttest.c @@ -0,0 +1,298 @@ +#include + +void check_s_lt(void) +{ + int a5 = 0, a10 = 0, a15 = 0; + + for(int i=5; i<15; i++) + { + if (i < 5) + a5++; + if (i < 10) + a10++; + if (i < 15) + a15++; + } + + assert(a5 == 0); + assert(a10 == 5); + assert(a15 == 10); +} + +void check_s_le(void) +{ + int a4 = 0, a5 = 0, a10 = 0, a14 = 0, a15 = 0; + + for(int i=5; i<15; i++) + { + if (i <= 4) + a4++; + if (i <= 5) + a5++; + if (i <= 10) + a10++; + if (i <= 14) + a14++; + if (i <= 15) + a15++; + } + + assert(a4 == 0); + assert(a5 == 1); + assert(a10 == 6); + assert(a14 == 10); + assert(a15 == 10); +} + +void check_s_ge(void) +{ + int a5 = 0, a10 = 0, a15 = 0; + + for(int i=5; i<15; i++) + { + if (i >= 5) + a5++; + if (i >= 10) + a10++; + if (i >= 15) + a15++; + } + + assert(a5 == 10); + assert(a10 == 5); + assert(a15 == 0); +} + +void check_s_gt(void) +{ + int a4 = 0, a5 = 0, a10 = 0, a14 = 0, a15 = 0; + + for(int i=5; i<15; i++) + { + if (i > 4) + a4++; + if (i > 5) + a5++; + if (i > 10) + a10++; + if (i > 14) + a14++; + if (i > 15) + a15++; + } + + assert(a4 == 10); + assert(a5 == 9); + assert(a10 == 4); + assert(a14 == 0); + assert(a15 == 0); +} + +void check_s_eq(void) +{ + int a4 = 0, a5 = 0, a10 = 0, a14 = 0, a15 = 0; + + for(int i=5; i<15; i++) + { + if (i == 4) + a4++; + if (i == 5) + a5++; + if (i == 10) + a10++; + if (i == 14) + a14++; + if (i == 15) + a15++; + } + + assert(a4 == 0); + assert(a5 == 1); + assert(a10 == 1); + assert(a14 == 1); + assert(a15 == 0); +} + +void check_s_ne(void) +{ + int a4 = 0, a5 = 0, a10 = 0, a14 = 0, a15 = 0; + + for(int i=5; i<15; i++) + { + if (i != 4) + a4++; + if (i != 5) + a5++; + if (i != 10) + a10++; + if (i != 14) + a14++; + if (i != 15) + a15++; + } + + assert(a4 == 10); + assert(a5 == 9); + assert(a10 == 9); + assert(a14 == 9); + assert(a15 == 10); +} + +void check_u_lt(void) +{ + int a5 = 0, a10 = 0, a15 = 0; + + for(unsigned i=5; i<15; i++) + { + if (i < 5) + a5++; + if (i < 10) + a10++; + if (i < 15) + a15++; + } + + assert(a5 == 0); + assert(a10 == 5); + assert(a15 == 10); +} + +void check_u_le(void) +{ + int a4 = 0, a5 = 0, a10 = 0, a14 = 0, a15 = 0; + + for(unsigned i=5; i<15; i++) + { + if (i <= 4) + a4++; + if (i <= 5) + a5++; + if (i <= 10) + a10++; + if (i <= 14) + a14++; + if (i <= 15) + a15++; + } + + assert(a4 == 0); + assert(a5 == 1); + assert(a10 == 6); + assert(a14 == 10); + assert(a15 == 10); +} + +void check_u_ge(void) +{ + int a5 = 0, a10 = 0, a15 = 0; + + for(unsigned i=5; i<15; i++) + { + if (i >= 5) + a5++; + if (i >= 10) + a10++; + if (i >= 15) + a15++; + } + + assert(a5 == 10); + assert(a10 == 5); + assert(a15 == 0); +} + +void check_u_gt(void) +{ + int a4 = 0, a5 = 0, a10 = 0, a14 = 0, a15 = 0; + + for(unsigned i=5; i<15; i++) + { + if (i > 4) + a4++; + if (i > 5) + a5++; + if (i > 10) + a10++; + if (i > 14) + a14++; + if (i > 15) + a15++; + } + + assert(a4 == 10); + assert(a5 == 9); + assert(a10 == 4); + assert(a14 == 0); + assert(a15 == 0); +} + +void check_u_eq(void) +{ + int a4 = 0, a5 = 0, a10 = 0, a14 = 0, a15 = 0; + + for(unsigned i=5; i<15; i++) + { + if (i == 4) + a4++; + if (i == 5) + a5++; + if (i == 10) + a10++; + if (i == 14) + a14++; + if (i == 15) + a15++; + } + + assert(a4 == 0); + assert(a5 == 1); + assert(a10 == 1); + assert(a14 == 1); + assert(a15 == 0); +} + +void check_u_ne(void) +{ + int a4 = 0, a5 = 0, a10 = 0, a14 = 0, a15 = 0; + + for(unsigned i=5; i<15; i++) + { + if (i != 4) + a4++; + if (i != 5) + a5++; + if (i != 10) + a10++; + if (i != 14) + a14++; + if (i != 15) + a15++; + } + + assert(a4 == 10); + assert(a5 == 9); + assert(a10 == 9); + assert(a14 == 9); + assert(a15 == 10); +} + + +int main(void) +{ + check_s_ne(); + check_s_eq(); + check_s_lt(); + check_s_le(); + check_s_gt(); + check_s_ge(); + + check_u_ne(); + check_u_eq(); + check_u_lt(); + check_u_le(); + check_u_gt(); + check_u_ge(); + + return 0; +} + diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 3d7de73..5adec57 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -2409,6 +2409,44 @@ bool InterInstruction::ConstantFolding(void) mNumOperands = 0; return true; } +#if 1 + else if (mSrc[0].mTemp < 0) + { + if (mDst.mType == IT_FLOAT) + { + + } + else if (IsIntegerType(mDst.mType)) + { + if ((mOperator == IA_ADD || mOperator == IA_SUB || mOperator == IA_OR || mOperator == IA_XOR || mOperator == IA_SHL || mOperator == IA_SHR || mOperator == IA_SAR) && mSrc[0].mIntConst == 0 || + (mOperator == IA_MUL || mOperator == IA_DIVS || mOperator == IA_DIVU) && mSrc[0].mIntConst == 1) + { + mCode = IC_LOAD_TEMPORARY; + mSrc[0] = mSrc[1]; + mSrc[1].mTemp = -1; + mNumOperands = 1; + return true; + } + } + } + else if (mSrc[1].mTemp < 0) + { + if (mDst.mType == IT_FLOAT) + { + + } + else if (IsIntegerType(mDst.mType)) + { + if ((mOperator == IA_ADD || mOperator == IA_OR || mOperator == IA_XOR) && mSrc[1].mIntConst == 0 || (mOperator == IA_MUL) && mSrc[1].mIntConst == 1) + { + mCode = IC_LOAD_TEMPORARY; + mSrc[1].mTemp = -1; + mNumOperands = 1; + return true; + } + } + } +#endif break; case IC_UNARY_OPERATOR: if (mSrc[0].mTemp < 0) @@ -3472,32 +3510,134 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void) int sz = mInstructions.Size(); if (sz >= 2 && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_RELATIONAL_OPERATOR && mInstructions[sz - 2]->mDst.mTemp == mInstructions[sz - 1]->mSrc[0].mTemp) { - if (mInstructions[sz - 2]->mOperator == IA_CMPLS) + InterInstruction* cins = mInstructions[sz - 2]; + + bool constFalse = false, constTrue = false; + + if (cins->mSrc[1].mRange.mMaxState == IntegerValueRange::S_BOUND && cins->mSrc[1].mRange.mMinState == IntegerValueRange::S_BOUND && + cins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND && cins->mSrc[0].mRange.mMinState == IntegerValueRange::S_BOUND) { - if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) + switch (cins->mOperator) { - if (mInstructions[sz - 2]->mSrc[1].IsUnsigned()) - mInstructions[sz - 2]->mOperator = IA_CMPLU; - } - else if (mInstructions[sz - 2]->mSrc[0].IsUnsigned() && mInstructions[sz - 2]->mSrc[1].IsUnsigned()) - { - mInstructions[sz - 2]->mOperator = IA_CMPLU; + case IA_CMPEQ: + if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue || cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue) + constFalse = true; + break; + case IA_CMPNE: + if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue || cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue) + constTrue = true; + break; + case IA_CMPLS: + if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue) + constTrue = true; + else if (cins->mSrc[1].mRange.mMinValue >= cins->mSrc[0].mRange.mMaxValue) + constFalse = true; + break; + case IA_CMPLU: + if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned()) + { + if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue) + constTrue = true; + else if (cins->mSrc[1].mRange.mMinValue >= cins->mSrc[0].mRange.mMaxValue) + constFalse = true; + } + break; + case IA_CMPLES: + if (cins->mSrc[1].mRange.mMaxValue <= cins->mSrc[0].mRange.mMinValue) + constTrue = true; + else if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue) + constFalse = true; + break; + case IA_CMPLEU: + if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned()) + { + if (cins->mSrc[1].mRange.mMaxValue <= cins->mSrc[0].mRange.mMinValue) + constTrue = true; + else if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue) + constFalse = true; + } + break; + case IA_CMPGS: + if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue) + constTrue = true; + else if (cins->mSrc[1].mRange.mMaxValue <= cins->mSrc[0].mRange.mMinValue) + constFalse = true; + break; + case IA_CMPGU: + if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned()) + { + if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue) + constTrue = true; + else if (cins->mSrc[1].mRange.mMaxValue <= cins->mSrc[0].mRange.mMinValue) + constFalse = true; + } + break; + case IA_CMPGES: + if (cins->mSrc[1].mRange.mMinValue >= cins->mSrc[0].mRange.mMaxValue) + constTrue = true; + else if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue) + constFalse = true; + break; + case IA_CMPGEU: + if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned()) + { + if (cins->mSrc[1].mRange.mMinValue >= cins->mSrc[0].mRange.mMaxValue) + constTrue = true; + else if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue) + constFalse = true; + } + break; } } - else if (mInstructions[sz - 2]->mOperator == IA_CMPLES) + + + if (constTrue || constFalse) { - if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) + cins->mCode = IC_CONSTANT; + cins->mConst.mType = IT_BOOL; + cins->mConst.mIntConst = constTrue ? 1 : 0; + cins->mNumOperands = 0; + } + else + { + switch (cins->mOperator) { - if (mInstructions[sz - 2]->mSrc[1].IsUnsigned()) - mInstructions[sz - 2]->mOperator = IA_CMPLEU; - } - else if (mInstructions[sz - 2]->mSrc[0].IsUnsigned() && mInstructions[sz - 2]->mSrc[1].IsUnsigned()) - { - mInstructions[sz - 2]->mOperator = IA_CMPLEU; + case IA_CMPLS: + if (cins->mSrc[0].IsUnsigned() && cins->mSrc[1].IsUnsigned()) + cins->mOperator = IA_CMPLU; + break; + case IA_CMPLES: + if (cins->mSrc[0].IsUnsigned() && cins->mSrc[1].IsUnsigned()) + cins->mOperator = IA_CMPLEU; + break; } } } #endif + + if (sz >= 2 && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_CONSTANT && mInstructions[sz - 2]->mDst.mTemp == mInstructions[sz - 1]->mSrc[0].mTemp) + { + InterInstruction* bins = mInstructions[sz - 1]; + + if (mInstructions[sz - 2]->mConst.mIntConst) + { + mFalseJump->mNumEntries--; + mFalseJump = nullptr; + bins->mCode = IC_JUMP; + bins->mSrc[0].mTemp = -1; + bins->mNumOperands = 0; + } + else + { + mTrueJump->mNumEntries--; + mTrueJump = mFalseJump; + mFalseJump = nullptr; + bins->mCode = IC_JUMP; + bins->mSrc[0].mTemp = -1; + bins->mNumOperands = 0; + } + } + #if 1 for (int i = 0; i < sz; i++) { @@ -4100,10 +4240,11 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void) { if (mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_RELATIONAL_OPERATOR && mInstructions[sz - 1]->mSrc[0].mTemp == mInstructions[sz - 2]->mDst.mTemp) { - if (mInstructions[sz - 2]->mOperator == IA_CMPLS) - { - int s1 = mInstructions[sz - 2]->mSrc[1].mTemp, s0 = mInstructions[sz - 2]->mSrc[0].mTemp; + int s1 = mInstructions[sz - 2]->mSrc[1].mTemp, s0 = mInstructions[sz - 2]->mSrc[0].mTemp; + switch (mInstructions[sz - 2]->mOperator) + { + case IA_CMPLS: if (s0 < 0) { mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1); @@ -4125,107 +4266,111 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void) if (mLocalValueRange[s0].mMinState == IntegerValueRange::S_BOUND) mFalseValueRange[s1].LimitMin(mLocalValueRange[s0].mMinValue); } - } - else if (mInstructions[sz - 2]->mOperator == IA_CMPLES) - { - if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) + break; + case IA_CMPLES: + if (s0 < 0) { - int t = mInstructions[sz - 2]->mSrc[1].mTemp; - mTrueValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); - mFalseValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); + mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); + mFalseValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); } - } - else if (mInstructions[sz - 2]->mOperator == IA_CMPGS) - { - if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) + break; + case IA_CMPGS: + if (s0 < 0) { - int t = mInstructions[sz - 2]->mSrc[1].mTemp; - mTrueValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); - mFalseValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); + mTrueValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); + mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); } - } - else if (mInstructions[sz - 2]->mOperator == IA_CMPGES) - { - if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) + break; + case IA_CMPGES: + if (s0 < 0) { - int t = mInstructions[sz - 2]->mSrc[1].mTemp; - mTrueValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst); - mFalseValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1); + mTrueValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst); + mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1); } - } - else if (mInstructions[sz - 2]->mOperator == IA_CMPLU) - { - if (mInstructions[sz - 2]->mSrc[1].mTemp >= 0) - { - int t = mInstructions[sz - 2]->mSrc[1].mTemp; - if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) - { - mTrueValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1); - mTrueValueRange[t].LimitMin(0); + break; - if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0) + case IA_CMPLU: + if (s1 >= 0) + { + if (s0 < 0) + { + mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1); + mTrueValueRange[s1].LimitMin(0); + + if (mFalseValueRange[s1].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[s1].mMinValue >= 0) { - mFalseValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst); + mFalseValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst); } } else if (mInstructions[sz - 2]->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND) { - mTrueValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue - 1); - mTrueValueRange[t].LimitMin(0); + mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue - 1); + mTrueValueRange[s1].LimitMin(0); - if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0) + if (mFalseValueRange[s1].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[s1].mMinValue >= 0) { - mFalseValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue); + mFalseValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue); } } } - } - else if (mInstructions[sz - 2]->mOperator == IA_CMPLEU) - { - if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) + break; + case IA_CMPLEU: + if (s0 < 0) { - int t = mInstructions[sz - 2]->mSrc[1].mTemp; - mTrueValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); - mTrueValueRange[t].LimitMin(0); + mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); + mTrueValueRange[s1].LimitMin(0); - if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0) + if (mFalseValueRange[s1].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[s1].mMinValue >= 0) { - mFalseValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); + mFalseValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); } } - } - else if (mInstructions[sz - 2]->mOperator == IA_CMPGU) - { - if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) + break; + case IA_CMPGU: + if (s0 < 0) { - int t = mInstructions[sz - 2]->mSrc[1].mTemp; -// if (mTrueValueRange[t].mMinState == IntegerValueRange::S_BOUND && mTrueValueRange[t].mMinValue >= 0) - { - mTrueValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); - } - - mFalseValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); - mFalseValueRange[t].LimitMin(0); + mTrueValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); + mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); + mFalseValueRange[s1].LimitMin(0); } - } - else if (mInstructions[sz - 2]->mOperator == IA_CMPGEU) - { - if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) + break; + case IA_CMPGEU: + if (s0 < 0) { - int t = mInstructions[sz - 2]->mSrc[1].mTemp; -// if (mTrueValueRange[t].mMinState == IntegerValueRange::S_BOUND && mTrueValueRange[t].mMinValue >= 0) - { - mTrueValueRange[t].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst); - } - - mFalseValueRange[t].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1); - mFalseValueRange[t].LimitMin(0); + mTrueValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst); + mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1); + mFalseValueRange[s1].LimitMin(0); } + break; } } } } +void InterCodeBasicBlock::RestartLocalIntegerRangeSets(void) +{ + int i; + + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mEntryValueRange.Size(); i++) + { + 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; + } + + UpdateLocalIntegerRangeSets(); + + if (mTrueJump) mTrueJump->RestartLocalIntegerRangeSets(); + if (mFalseJump) mFalseJump->RestartLocalIntegerRangeSets(); + } +} + void InterCodeBasicBlock::BuildLocalIntegerRangeSets(int num) { int i; @@ -6127,6 +6272,9 @@ InterCodeBasicBlock* InterCodeBasicBlock::PropagateDominator(InterCodeProcedure* { mDominator = new InterCodeBasicBlock(); proc->Append(mDominator); + InterInstruction * jins = new InterInstruction(); + jins->mCode = IC_JUMP; + mDominator->Append(jins); mDominator->Close(this, nullptr); } } @@ -6425,7 +6573,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams) InterInstruction* ins = block->mInstructions[i]; if (ins->mInvariant && ins->mExpensive) { - mDominator->mInstructions.Push(ins); + mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins); } else { @@ -6583,7 +6731,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa InterInstruction* ins = mInstructions[i]; if (ins->mInvariant) { - mDominator->mInstructions.Push(ins); + mDominator->mInstructions.Insert(mDominator->mInstructions.Size() - 1, ins); } else { @@ -7733,12 +7881,25 @@ void InterCodeProcedure::Close(void) } while (mEntryBlock->BuildGlobalIntegerRangeSets()); DisassembleDebug("Estimated value range"); +#if 1 + ResetVisited(); + mEntryBlock->RestartLocalIntegerRangeSets(); + do { + DisassembleDebug("tr"); + + ResetVisited(); + } while (mEntryBlock->BuildGlobalIntegerRangeSets()); + + DisassembleDebug("Estimated value range 2"); +#endif ResetVisited(); mEntryBlock->SimplifyIntegerRangeRelops(); DisassembleDebug("Simplified range limited relational ops"); #endif + + #if 1 ResetVisited(); mEntryBlock->DropUnreachable(); @@ -7750,8 +7911,11 @@ void InterCodeProcedure::Close(void) BuildDataFlowSets(); TempForwarding(); RemoveUnusedInstructions(); - + DisassembleDebug("Removed unreachable branches"); + + BuildTraces(false); + #endif MapVariables(); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 920094a..ef55807 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -395,6 +395,7 @@ public: void SimpleLocalToTemp(int vindex, int temp); bool ConstantFolding(void); + bool ConstantFoldingRelationRange(void); void Disassemble(FILE* file); }; @@ -511,6 +512,7 @@ public: bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars); bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars); + void RestartLocalIntegerRangeSets(void); void BuildLocalIntegerRangeSets(int num); void UpdateLocalIntegerRangeSets(void); bool BuildGlobalIntegerRangeSets(void); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index f2f5557..167f6d9 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -73,7 +73,7 @@ int main(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.2.61"); + strcpy(strProductVersion, "1.2.62"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 4706fd7..dbd665f 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,61,0 - PRODUCTVERSION 1,2,61,0 + FILEVERSION 1,2,62,0 + PRODUCTVERSION 1,2,62,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.2.61.0" + VALUE "FileVersion", "1.2.62.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.2.61.0" + VALUE "ProductVersion", "1.2.62.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 4b7e41a..3b196a3 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -2987,15 +2987,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{FDB14C01-E512-47D7-AB10-6431DB1DC40B}" - "PackageCode" = "8:{8C16AAEE-9A02-4BA9-9DD9-BD5606D870F6}" + "ProductCode" = "8:{B0D25385-A6F7-4134-8C6B-8CEFA1F244B1}" + "PackageCode" = "8:{00172C8A-7F93-49AC-B3A4-A451DD1544E4}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.2.61" + "ProductVersion" = "8:1.2.62" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:"