diff --git a/include/opp/vector.h b/include/opp/vector.h index 417e122..d28d51e 100644 --- a/include/opp/vector.h +++ b/include/opp/vector.h @@ -164,6 +164,11 @@ public: void insert(int at, const T & t); void erase(int at, int n = 1); + + template + void emplace_back(const P&... p); +protected: + T * add_back(void); }; @@ -224,19 +229,30 @@ void vector::shrink_to_fit(void) } template -void vector::push_back(const T & t) +T * vector::add_back(void) { if (_size == _capacity) reserve(_size + 1 + (_size >> 1)); - new (_data + _size++)T(t); + return _data + _size++; +} + +template +void vector::push_back(const T & t) +{ + new (add_back())T(t); } template void vector::push_back(T && t) { - if (_size == _capacity) - reserve(_size + 1 + (_size >> 1)); - new (_data + _size++)T(t); + new (add_back())T(t); +} + +template +template +void vector::emplace_back(const P&... p) +{ + new (add_back())T(p...); } template diff --git a/oscar64/Constexpr.cpp b/oscar64/Constexpr.cpp index 1a5b83d..3d36080 100644 --- a/oscar64/Constexpr.cpp +++ b/oscar64/Constexpr.cpp @@ -885,7 +885,11 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons if (dec) pos = dec->mVarIndex; - mParams[pos] = caller->REval(pex->mLeft); + if (dec) + mParams[pos] = caller->EvalCoerce(pex->mLeft, caller->Eval(pex->mLeft), dec->mBase); + else + mParams[pos] = caller->REval(pex->mLeft); + pos += dec->mSize; pex = pex->mRight; if (dec) @@ -895,7 +899,10 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons { if (dec) pos = dec->mVarIndex; - mParams[pos] = caller->REval(pex); + if (dec) + mParams[pos] = caller->EvalCoerce(pex, caller->Eval(pex), dec->mBase); + else + mParams[pos] = caller->REval(pex); } if (exp->mLeft->mDecValue->mFlags & DTF_INTRINSIC) @@ -976,14 +983,25 @@ ConstexprInterpreter::Value ConstexprInterpreter::Eval(Expression* exp) return Value(exp); case EX_VARIABLE: if (exp->mDecValue->mType == DT_ARGUMENT) - return Value(&mParams[exp->mDecValue->mVarIndex]); + { + if (mParams[exp->mDecValue->mVarIndex].mBaseValue) + return mParams[exp->mDecValue->mVarIndex]; + else + return Value(&mParams[exp->mDecValue->mVarIndex]); + } else if (exp->mDecValue->mType == DT_VARIABLE) { if (!(exp->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL))) { if (!mLocals[exp->mDecValue->mVarIndex].mDataSize) + { mLocals[exp->mDecValue->mVarIndex] = Value(exp->mDecValue->mLocation, exp->mDecValue->mBase); - return Value(&mLocals[exp->mDecValue->mVarIndex]); + return Value(&mLocals[exp->mDecValue->mVarIndex]); + } + else if (mLocals[exp->mDecValue->mVarIndex].mBaseValue) + return mLocals[exp->mDecValue->mVarIndex]; + else + return Value(&mLocals[exp->mDecValue->mVarIndex]); } } break; diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 8622ac8..bef5f0d 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -1240,7 +1240,11 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec) Declaration* tpdec = ex->mDecType; if (tpdec->IsReference()) tpdec = tpdec->mBase; - tpdec = tpdec->Clone(); + + if (tpdec->mType == DT_TYPE_ARRAY) + tpdec = tpdec->mBase->BuildPointer(tpdec->mLocation); + else + tpdec = tpdec->Clone(); if (ptail) ptail->mNext = tpdec; @@ -1338,6 +1342,8 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec) { if (tdec->IsSame(fdec)) return true; + else if (fdec->IsReference()) + return ResolveTemplate(fdec->mBase, tdec); else if (tdec->mType == DT_TYPE_FUNCTION) { if (fdec->mType == DT_TYPE_FUNCTION) @@ -1369,17 +1375,11 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec) } else if (tdec->mType == DT_TYPE_REFERENCE) { - if (fdec->mType == DT_TYPE_REFERENCE) - return ResolveTemplate(fdec->mBase, tdec->mBase); - else - return ResolveTemplate(fdec, tdec->mBase); + return ResolveTemplate(fdec, tdec->mBase); } else if (tdec->mType == DT_TYPE_RVALUEREF) { - if (fdec->mType == DT_TYPE_RVALUEREF) - return ResolveTemplate(fdec->mBase, tdec->mBase); - else - return ResolveTemplate(fdec, tdec->mBase); + return ResolveTemplate(fdec, tdec->mBase); } else if (tdec->mType == DT_TYPE_POINTER) { @@ -1390,6 +1390,9 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec) } else if (tdec->mType == DT_TYPE_TEMPLATE) { + if (fdec->mType == DT_TYPE_ARRAY) + fdec = fdec->mBase->BuildPointer(fdec->mLocation); + Declaration* pdec; if (tdec->mBase) { @@ -1871,6 +1874,11 @@ bool Declaration::IsSameParams(const Declaration* dec) const if (ld->mValue != rd->mValue) return false; } + else if (ld->mType == DT_PACK_TEMPLATE && rd->mType == DT_PACK_TEMPLATE) + { + if (!ld->mBase->IsSameParams(rd->mBase)) + return false; + } else if (!ld->mBase || !rd->mBase) return false; else if (!ld->mBase->IsSame(rd->mBase)) @@ -1881,6 +1889,19 @@ bool Declaration::IsSameParams(const Declaration* dec) const return !ld && !rd; } + else if (mType == DT_PACK_TYPE && dec->mType == DT_PACK_TYPE) + { + Declaration* ld = mBase, * rd = dec->mBase; + while (ld && rd) + { + if (!ld->IsSame(rd)) + return false; + ld = ld->mNext; + rd = rd->mNext; + } + + return !ld && !rd; + } else return false; } @@ -1989,6 +2010,13 @@ bool Declaration::IsTemplateSame(const Declaration* dec, const Declaration * tde return true; dflags |= dec->mFlags; } + else if (dec->mType == DT_PACK_TEMPLATE) + { + dec = tdec->mScope->Lookup(dec->mIdent); + if (!dec) + return true; + dflags |= dec->mFlags; + } if (this == dec) return true; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index bfcd4a7..9c008a9 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -692,7 +692,19 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons ins0->mCode == IC_PUSH_FRAME || ins0->mCode == IC_POP_FRAME || ins0->mCode == IC_MALLOC || ins0->mCode == IC_FREE) return false; - if (ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) + if (ins0->mCode == IC_LOAD) + { + if (ins0->mSrc[0].mTemp >= 0) + return false; + if (ins0->mSrc[0].mMemory == IM_PARAM || ins0->mSrc[0].mMemory == IM_FPARAM) + { + if (mProc->mParamAliasedSet[ins0->mSrc[0].mVarIndex]) + return false; + } + else + return false; + } + else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) return false; } if (ins0->mCode == IC_CALL || ins0->mCode == IC_CALL_NATIVE || ins0->mCode == IC_ASSEMBLER) @@ -13675,6 +13687,31 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa InterCodeBasicBlock* tailBlock = this == mTrueJump ? mFalseJump : mTrueJump; assert(tailBlock->mNumEntries == 1); + // remove counting loop without body + if (mInstructions.Size() == 3) + { + InterInstruction* ains = mInstructions[0]; + InterInstruction* cins = mInstructions[1]; + InterInstruction* bins = mInstructions[2]; + + if (ains->mCode == IC_BINARY_OPERATOR && cins->mCode == IC_RELATIONAL_OPERATOR && bins->mCode == IC_BRANCH) + { + if (ains->mSrc[1].mTemp == ains->mDst.mTemp && ains->mSrc[0].mTemp < 0 && + cins->mSrc[1].mTemp == ains->mDst.mTemp && ains->mSrc[0].mTemp < 0 && + bins->mSrc[0].mTemp == cins->mDst.mTemp && bins->mSrc[0].mFinal) + { + if (ains->mOperator == IA_ADD && ains->mSrc[0].mIntConst == 1 && + cins->mOperator == IA_CMPLU && mTrueJump == this && !tailBlock->mEntryRequiredTemps[ains->mDst.mTemp]) + { + cins->mCode = IC_CONSTANT; + cins->mConst.mType = IT_BOOL; + cins->mConst.mIntConst = 0; + cins->mNumOperands = 0; + } + } + } + } + if (!hasCall) { // Check forwarding globals @@ -17142,7 +17179,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "main"); + CheckFunc = !strcmp(mIdent->mString, "bv"); mEntryBlock = mBlocks[0]; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 4593fa3..d34f7c3 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -4997,7 +4997,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod { InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE, dec->mAlignment)); -#if 1 +#if 0 if (proc->mIdent && !strcmp(proc->mIdent->mString, "main")) exp->Dump(0); #endif diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 5089016..9fabfb9 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1201,9 +1201,15 @@ Declaration * Parser::ParseFunctionDeclaration(Declaration* bdec) adec->mParams = apdec; if (adec->mBase->IsReference()) - apdec->mBase = atdec->BuildReference(adec->mLocation); + { + if (adec->mBase->mBase->mFlags & DTF_CONST) + apdec->mBase = atdec->ToConstType()->BuildReference(adec->mLocation); + else + apdec->mBase = atdec->BuildReference(adec->mLocation); + } else apdec->mBase = atdec; + atdec = atdec->mNext; apdec->mFlags = DTF_DEFINED; apdec->mVarIndex = vi; @@ -3616,7 +3622,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex } else if (mScanner->mToken == TK_CONSTEXPR) { - storageFlags |= DTF_CONSTEXPR; + storageFlags |= DTF_CONSTEXPR | DTF_REQUEST_INLINE; mScanner->NextToken(); } else if (mScanner->mToken == TK_EXTERN) @@ -7920,8 +7926,10 @@ Expression* Parser::ParseStatement(void) switch (mScanner->mToken) { case TK_IF: + { mScanner->NextToken(); - exp = new Expression(mScanner->mLocation, EX_IF); + bool constExp = ConsumeTokenIf(TK_CONSTEXPR); + exp = new Expression(mScanner->mLocation, EX_IF); exp->mLeft = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration); exp->mRight = new Expression(mScanner->mLocation, EX_ELSE); exp->mRight->mLeft = ParseStatement(); @@ -7932,7 +7940,23 @@ Expression* Parser::ParseStatement(void) } else exp->mRight->mRight = nullptr; - break; + + if (constExp) + { + Expression * cexp = exp->mLeft->ConstantFold(mErrors, mDataSection); + if (cexp->mType == EX_CONSTANT && cexp->mDecValue->mType == DT_CONST_INTEGER) + { + if (cexp->mDecValue->mInteger) + exp = exp->mRight->mLeft; + else if (exp->mRight->mRight) + exp = exp->mRight->mRight; + else + exp = new Expression(mScanner->mLocation, EX_VOID); + } + else + mErrors->Error(exp->mLocation, EERR_INVALID_CONSTEXPR, "Condition is not constant"); + } + } break; case TK_WHILE: { mScanner->NextToken();