diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 5d46492..9b8e8a5 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -579,14 +579,17 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio i++; if (i >= 64) i = 0xff; - - Expression* ex = new Expression(mLocation, EX_CONSTANT); - Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER); - dec->mBase = TheUnsignedCharTypeDeclaration; - dec->mInteger = i; - ex->mDecValue = dec; - ex->mDecType = dec->mBase; - return ex; + + if (i < 64 || (mLeft->mDecValue->mFlags & DTF_DEFINED)) + { + Expression* ex = new Expression(mLocation, EX_CONSTANT); + Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER); + dec->mBase = TheSignedIntTypeDeclaration; + dec->mInteger = i; + ex->mDecValue = dec; + ex->mDecType = dec->mBase; + return ex; + } } return this; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index c047cab..6da97bb 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -1584,6 +1584,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPEQ: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst == op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mIntConst == op2.mIntConst && op1.mLinkerObject == op2.mLinkerObject; else dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) == ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1591,6 +1593,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPNE: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst != op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory != op2.mMemory || op1.mVarIndex != op2.mVarIndex || op1.mIntConst != op2.mIntConst || op1.mLinkerObject != op2.mLinkerObject; else dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) != ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1598,6 +1602,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPGES: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst >= op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst >= op2.mIntConst; else dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) >= ToTypedSigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1605,6 +1611,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPGEU: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst >= op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst >= op2.mIntConst; else dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) >= ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1612,6 +1620,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPLES: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst <= op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst <= op2.mIntConst; else dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) <= ToTypedSigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1619,6 +1629,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPLEU: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst <= op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst <= op2.mIntConst; else dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) <= ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1626,6 +1638,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPGS: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst > op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst > op2.mIntConst; else dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) > ToTypedSigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1633,6 +1647,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPGU: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst > op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst > op2.mIntConst; else dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) > ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1640,6 +1656,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPLS: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst < op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst < op2.mIntConst; else dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) < ToTypedSigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1647,6 +1665,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, case IA_CMPLU: if (op1.mType == IT_FLOAT) dop.mIntConst = op1.mFloatConst < op2.mFloatConst ? 1 : 0; + else if (op1.mType == IT_POINTER) + dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst < op2.mIntConst; else dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) < ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0; dop.mType = IT_BOOL; @@ -1715,6 +1735,38 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1, else dop.mIntConst = -op1.mIntConst; break; + case IA_ABS: + dop.mType = op1.mType; + if (op1.mType == IT_FLOAT) + { + if (op1.mFloatConst < 0) + dop.mFloatConst = -op1.mFloatConst; + else + dop.mFloatConst = op1.mFloatConst; + } + else + { + if (op1.mIntConst < 0) + dop.mIntConst = -op1.mIntConst; + else + dop.mIntConst = op1.mIntConst; + } + break; + break; + case IA_FLOOR: + dop.mType = op1.mType; + if (op1.mType == IT_FLOAT) + dop.mFloatConst = floor(op1.mFloatConst); + else + dop.mIntConst = op1.mIntConst; + break; + case IA_CEIL: + dop.mType = op1.mType; + if (op1.mType == IT_FLOAT) + dop.mFloatConst = ceil(op1.mFloatConst); + else + dop.mIntConst = op1.mIntConst; + break; case IA_NOT: dop.mType = op1.mType; switch (op1.mType) @@ -7333,6 +7385,83 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray return changed; } +bool InterCodeBasicBlock::EarlyBranchElimination(const GrowingInstructionPtrArray& ctemps) +{ + bool changed = false; + + int i; + + if (!mVisited) + { + mVisited = true; + + GrowingInstructionPtrArray temps(ctemps); + if (mNumEntries > 1) + temps.Clear(); + + int sz = mInstructions.Size(); + for (i = 0; i < sz; i++) + { + InterInstruction* ins = mInstructions[i]; + if (ins->mDst.mTemp >= 0) + { + if (ins->mCode == IC_UNARY_OPERATOR && temps[ins->mSrc[0].mTemp]) + { + ins->mConst = OperandConstantFolding(ins->mOperator, temps[ins->mSrc[0].mTemp]->mConst, temps[ins->mSrc[0].mTemp]->mConst); + ins->mCode = IC_CONSTANT; + ins->mNumOperands = 0; + ins->mSrc[0].mTemp = -1; + } + else if (ins->mCode == IC_BINARY_OPERATOR && temps[ins->mSrc[0].mTemp] && temps[ins->mSrc[1].mTemp]) + { + ins->mConst = OperandConstantFolding(ins->mOperator, temps[ins->mSrc[1].mTemp]->mConst, temps[ins->mSrc[0].mTemp]->mConst); + ins->mCode = IC_CONSTANT; + ins->mNumOperands = 0; + ins->mSrc[0].mTemp = -1; + } + else if (ins->mCode == IC_RELATIONAL_OPERATOR && temps[ins->mSrc[0].mTemp] && temps[ins->mSrc[1].mTemp]) + { + ins->mConst = OperandConstantFolding(ins->mOperator, temps[ins->mSrc[1].mTemp]->mConst, temps[ins->mSrc[0].mTemp]->mConst); + ins->mCode = IC_CONSTANT; + ins->mNumOperands = 0; + ins->mSrc[0].mTemp = -1; + } + + if (ins->mCode == IC_CONSTANT) + temps[mInstructions[i]->mDst.mTemp] = ins; + else + temps[mInstructions[i]->mDst.mTemp] = nullptr; + } + } + + if (sz > 0 && mInstructions[sz - 1]->mCode == IC_BRANCH && temps[mInstructions[sz - 1]->mSrc[0].mTemp]) + { + InterInstruction* cins = temps[mInstructions[sz - 1]->mSrc[0].mTemp]; + + if (cins->mConst.mType == IT_BOOL) + { + mInstructions[sz - 1]->mCode = IC_JUMP; + if (cins->mConst.mIntConst) + mFalseJump->mNumEntries--; + else + { + mTrueJump->mNumEntries--; + mTrueJump = mFalseJump; + } + mFalseJump = nullptr; + changed = true; + } + } + + if (mTrueJump && mTrueJump->EarlyBranchElimination(temps)) + changed = true; + if (mFalseJump && mFalseJump->EarlyBranchElimination(temps)) + changed = true; + } + + return changed; +} + bool InterCodeBasicBlock::ForwardConstTemps(const GrowingInstructionPtrArray& ctemps) { bool changed = false; @@ -21674,6 +21803,15 @@ void InterCodeProcedure::RebuildIntegerRangeSet(void) DisassembleDebug("Estimated value range 2"); } +void InterCodeProcedure::EarlyBranchElimination(void) +{ + GrowingInstructionPtrArray ctemps(nullptr); + + ResetVisited(); + while (mEntryBlock->EarlyBranchElimination(ctemps)) + {} +} + void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact) { // Count number of entries @@ -22599,7 +22737,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "Test::move"); + CheckFunc = !strcmp(mIdent->mString, "main"); CheckCase = false; mEntryBlock = mBlocks[0]; @@ -22608,6 +22746,10 @@ void InterCodeProcedure::Close(void) BuildTraces(true); + EarlyBranchElimination(); + + DisassembleDebug("branch elimination"); + ResetVisited(); mLeafProcedure = mEntryBlock->IsLeafProcedure(); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index c88b4fe..9a0830a 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -444,6 +444,8 @@ public: bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps); bool ForwardConstTemps(const GrowingInstructionPtrArray& ctemps); + bool EarlyBranchElimination(const GrowingInstructionPtrArray& ctemps); + bool PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars, const NumberSet & aliasedLocals, const NumberSet & aliasedParams); void BuildLocalTempSets(int num); @@ -746,6 +748,7 @@ public: protected: void BuildLocalAliasTable(void); void BuildTraces(bool expand, bool dominators = true, bool compact = false); + void EarlyBranchElimination(void); void BuildDataFlowSets(void); void RenameTemporaries(void); void TempForwarding(bool reverse = false, bool checkloops = false); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 9beb982..070c121 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -3327,12 +3327,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mCode = IC_CONSTANT; ins->mNumOperands = 0; - ins->mConst.mType = IT_INT8; + ins->mConst.mType = IT_INT16; ins->mConst.mIntConst = i; - ins->mDst.mType = IT_INT8; + ins->mDst.mType = IT_INT16; ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); block->Append(ins); - return ExValue(TheUnsignedCharTypeDeclaration, ins->mDst.mTemp, vl.mReference - 1); + return ExValue(TheSignedIntTypeDeclaration, ins->mDst.mTemp, vl.mReference - 1); } } mErrors->Error(exp->mLocation, ERRR_CANNOT_FIND_BANK_OF_EXPRESSION, "Cannot find bank of expressiohn"); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 0ee63d1..3a737b1 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -8425,7 +8425,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs) } else if (nexp->mToken == TK_BANKOF) { - nexp->mDecType = TheUnsignedCharTypeDeclaration; + nexp->mDecType = TheSignedIntTypeDeclaration; } else if (nexp->mToken == TK_BINARY_AND) {