Skip to content

Commit

Permalink
Copy elision on return statements
Browse files Browse the repository at this point in the history
  • Loading branch information
drmortalwombat committed Jul 5, 2023
1 parent 0b79d44 commit 0b6a9c3
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 16 deletions.
63 changes: 63 additions & 0 deletions oscar64/Declaration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ void Expression::Dump(int ident) const
case EX_CLEANUP:
printf("CLEANUP");
break;
case EX_RESULT:
printf("RESULT");
break;
}
printf("\n");

Expand Down Expand Up @@ -810,6 +813,15 @@ Declaration* Declaration::BuildPointer(const Location& loc)
return pdec;
}

Declaration* Declaration::BuildReference(const Location& loc)
{
Declaration* pdec = new Declaration(loc, DT_TYPE_REFERENCE);
pdec->mBase = this;
pdec->mFlags = DTF_DEFINED;
pdec->mSize = 2;
return pdec;
}

Declaration* Declaration::Last(void)
{
mPrev = nullptr;
Expand Down Expand Up @@ -1069,6 +1081,57 @@ bool Declaration::IsSubType(const Declaration* dec) const
return false;
}

bool Declaration::IsSameMutable(const Declaration* dec) const
{
if (this == dec)
return true;
if (mType != dec->mType)
return false;
if (mSize != dec->mSize)
return false;
if (mStripe != dec->mStripe)
return false;

if ((mFlags & DTF_SIGNED) != (dec->mFlags & DTF_SIGNED))
return false;
if ((dec->mFlags & DTF_CONST) && !(mFlags & DTF_CONST))
return false;

if (mType == DT_TYPE_INTEGER)
return true;
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
return true;
else if (mType == DT_TYPE_ENUM)
return mIdent == dec->mIdent;
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
return this->Stride() == dec->Stride() && mBase->IsSame(dec->mBase);
else if (mType == DT_TYPE_STRUCT)
return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize);
else if (mType == DT_TYPE_FUNCTION)
{
if (!mBase->IsSame(dec->mBase))
return false;
Declaration* dl = mParams, * dr = dec->mParams;
while (dl && dr)
{
if (!dl->mBase->IsSame(dr->mBase))
return false;
dl = dl->mNext;
dr = dr->mNext;
}

if (dl || dr)
return false;

if ((mFlags & DTF_VARIADIC) != (dec->mFlags & DTF_VARIADIC))
return false;

return true;
}

return false;
}

bool Declaration::IsConstSame(const Declaration* dec) const
{
if (this == dec)
Expand Down
5 changes: 4 additions & 1 deletion oscar64/Declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ enum ExpressionType
EX_ASSUME,
EX_BANKOF,
EX_CONSTRUCT,
EX_CLEANUP
EX_CLEANUP,
EX_RESULT
};

class Expression
Expand Down Expand Up @@ -247,6 +248,7 @@ class Declaration
bool IsConstSame(const Declaration* dec) const;
bool IsSameValue(const Declaration* dec) const;
bool IsSameParams(const Declaration* dec) const;
bool IsSameMutable(const Declaration* dec) const;

bool IsIntegerType(void) const;
bool IsNumericType(void) const;
Expand All @@ -263,6 +265,7 @@ class Declaration
Declaration* Last(void);

Declaration* BuildPointer(const Location& loc);
Declaration* BuildReference(const Location& loc);

int Stride(void) const;
};
Expand Down
2 changes: 1 addition & 1 deletion oscar64/GlobalAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo

if (pdec && !(ldec->mBase->mFlags & DTF_VARIADIC) && !(ldec->mFlags & (DTF_INTRINSIC | DTF_FUNC_ASSEMBLER)))
{
#if 0
#if 1
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
{
if (!(pdec->mFlags & DTF_FPARAM_NOCONST))
Expand Down
10 changes: 9 additions & 1 deletion oscar64/InterCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6879,6 +6879,10 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
vr.LimitMax(ins->mSrc[0].mIntConst - 1);
else if (ins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND)
vr.LimitMax(ins->mSrc[0].mRange.mMaxValue - 1);
else if (ins->mSrc[1].mRange.mMaxState == IntegerValueRange::S_BOUND)
vr.LimitMax(ins->mSrc[1].mRange.mMaxValue);
else
vr.mMaxState = IntegerValueRange::S_UNBOUND;
break;
#endif
default:
Expand Down Expand Up @@ -11883,6 +11887,10 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
{
ins->mInvariant = false;
}
else if (ins->mSrc[0].mMemory == IM_PARAM && hasCall && aliasedParams[ins->mSrc[0].mVarIndex])
{
ins->mInvariant = false;
}
else
{
for (int bj = 0; bj < body.Size(); bj++)
Expand Down Expand Up @@ -16098,7 +16106,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);

CheckFunc = !strcmp(mIdent->mString, "main");
CheckFunc = !strcmp(mIdent->mString, "print");

mEntryBlock = mBlocks[0];

Expand Down
58 changes: 56 additions & 2 deletions oscar64/InterCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1313,7 +1313,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_CONSTRUCT:
{
if (exp->mLeft->mLeft)
TranslateExpression(procType, proc, block, exp->mLeft->mLeft, destack, breakBlock, continueBlock, inlineMapper);
TranslateExpression(procType, proc, block, exp->mLeft->mLeft, destack, breakBlock, continueBlock, inlineMapper, lrexp);

if (exp->mLeft->mRight)
{
Expand All @@ -1327,6 +1327,60 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
}
break;

case EX_RESULT:
{
if (lrexp)
return *lrexp;

InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);

if (inlineMapper)
{
if (inlineMapper->mResultExp)
{
ains->mDst.mTemp = inlineMapper->mResultExp->mTemp;
}
else
{
ains->mCode = IC_CONSTANT;
ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
ains->mConst.mOperandSize = procType->mBase->mSize;
ains->mConst.mIntConst = 0;
ains->mConst.mVarIndex = inlineMapper->mResult;
ains->mConst.mMemory = IM_LOCAL;
block->Append(ains);
}
}
else
{
InterInstruction* pins = new InterInstruction(exp->mLocation, IC_CONSTANT);
pins->mDst.mType = IT_POINTER;
pins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
pins->mConst.mVarIndex = 0;
pins->mConst.mIntConst = 0;
pins->mConst.mOperandSize = 2;
if (procType->mFlags & DTF_FASTCALL)
{
pins->mConst.mMemory = IM_FPARAM;
pins->mConst.mVarIndex += procType->mFastCallBase;
}
else
pins->mConst.mMemory = IM_PARAM;
block->Append(pins);

ains->mCode = IC_LOAD;
ains->mSrc[0].mMemory = IM_INDIRECT;
ains->mSrc[0].mType = IT_POINTER;
ains->mSrc[0].mTemp = pins->mDst.mTemp;
ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
ains->mNumOperands = 1;
block->Append(ains);
}

return ExValue(exp->mDecType, ains->mDst.mTemp, 1);
}
case EX_CLEANUP:
{
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
Expand Down Expand Up @@ -4453,7 +4507,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));

#if 0
if (proc->mIdent && !strcmp(proc->mIdent->mString, "main"))
if (proc->mIdent && !strcmp(proc->mIdent->mString, "A::func"))
exp->Dump(0);
#endif
#if 0
Expand Down
18 changes: 13 additions & 5 deletions oscar64/NativeCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18971,6 +18971,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
i++;
if (i == mEntryBlocks.Size())
{
mEntryRequiredRegs += CPU_REG_A;

mIns.Insert(0, eb->mIns[index]);
mIns[0].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_Y;
for (int i = 0; i < mEntryBlocks.Size(); i++)
Expand All @@ -18992,6 +18994,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
i++;
if (i == mEntryBlocks.Size())
{
mEntryRequiredRegs += CPU_REG_X;

mIns.Insert(0, eb->mIns[index]);
mIns[0].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_Y;
for (int i = 0; i < mEntryBlocks.Size(); i++)
Expand All @@ -19013,6 +19017,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
i++;
if (i == mEntryBlocks.Size())
{
mEntryRequiredRegs += CPU_REG_Y;

mIns.Insert(0, eb->mIns[index]);
mIns[0].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_Y;
for (int i = 0; i < mEntryBlocks.Size(); i++)
Expand Down Expand Up @@ -24803,6 +24809,8 @@ bool NativeCodeBasicBlock::MoveAbsoluteLoadStoreUp(int at)
return false;
if (mIns[at + 1].mMode == ASMIM_ABSOLUTE_Y && mIns[j].ChangesYReg())
return false;
if (mIns[at + 1].mMode == ASMIM_INDIRECT_Y && (mIns[j].ChangesYReg() || mIns[j].ChangesZeroPage(mIns[at + 1].mAddress) || mIns[j].ChangesZeroPage(mIns[at + 1].mAddress + 1)))
return false;

if (mIns[j].mType == ASMIT_JSR)
return false;
Expand Down Expand Up @@ -33307,7 +33315,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
for (int i = 2; i + 1 < mIns.Size(); i++)
{
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA &&
(mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ABSOLUTE_X || mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y))
(mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ABSOLUTE_X || mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y || mIns[i + 1].mMode == ASMIM_INDIRECT_Y))
{
if (MoveAbsoluteLoadStoreUp(i))
changed = true;
Expand Down Expand Up @@ -36469,7 +36477,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
else if (
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
mIns[i + 1].mType == ASMIT_ROL && mIns[i + 1].mMode == ASMIM_IMPLIED &&
mIns[i + 2].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_CLC &&
mIns[i + 3].mType == ASMIT_ADC)
{
mIns[i + 1].mType = ASMIT_NOP;
Expand Down Expand Up @@ -36536,7 +36544,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDA &&
mIns[i + 0].mType == ASMIT_LDA &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !mIns[i + 0].MayBeChangedOnAddress(mIns[i + 1]) &&
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 3].mType == ASMIT_ORA && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && mIns[i + 3].mMode != ASMIM_IMMEDIATE)
Expand All @@ -36548,9 +36556,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDA &&
mIns[i + 0].mType == ASMIT_LDA &&
mIns[i + 1].mType == ASMIT_EOR && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0xff &&
mIns[i + 2].mType == ASMIT_SEC &&
(mIns[i + 2].mType == ASMIT_SEC || mIns[i + 2].mType == ASMIT_CLC) &&
mIns[i + 3].mType == ASMIT_ADC)
{
mIns.Insert(i + 4, mIns[i + 0]);
Expand Down
26 changes: 21 additions & 5 deletions oscar64/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3172,9 +3172,12 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
{
pdec = mCompilationUnits->mScope->Insert(ndec->mQualIdent, ndec);

Declaration * ldec = mScope->Insert(ndec->mIdent, pdec ? pdec : ndec);
if (ldec && ldec != pdec)
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate definition");
if (ndec->mIdent == ndec->mQualIdent)
{
Declaration* ldec = mScope->Insert(ndec->mIdent, pdec ? pdec : ndec);
if (ldec && ldec != pdec)
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate definition");
}
}
else
pdec = mScope->Insert(ndec->mIdent, ndec);
Expand Down Expand Up @@ -4184,7 +4187,7 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
else
return NOOVERLOAD;
}
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_ARRAY && ptype->mBase->IsSame(etype->mBase))
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_ARRAY && ptype->mBase->IsSameMutable(etype->mBase))
dist += 1;
else if (ptype->IsSubType(etype))
dist += 256;
Expand Down Expand Up @@ -4819,7 +4822,9 @@ Expression* Parser::ParseMulExpression(bool lhs)
else
nexp->mDecType = exp->mDecType;

exp = nexp->ConstantFold(mErrors);
exp = CheckOperatorOverload(nexp);

exp = exp->ConstantFold(mErrors);
}

return exp;
Expand Down Expand Up @@ -5322,6 +5327,7 @@ Expression* Parser::ParseFunction(Declaration * dec)
if (dec->mFlags & DTF_FUNC_THIS)
mThisPointer = dec->mParams;

mReturnType = dec->mBase;

DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_FUNCTION);
mScope = scope;
Expand Down Expand Up @@ -5713,7 +5719,17 @@ Expression* Parser::ParseStatement(void)
mScanner->NextToken();
exp = new Expression(mScanner->mLocation, EX_RETURN);
if (mScanner->mToken != TK_SEMICOLON)
{
exp->mLeft = CleanupExpression(ParseRExpression());
if (exp->mLeft->mType == EX_CONSTRUCT && mReturnType && mReturnType->mType == DT_TYPE_STRUCT)
{
Expression* cexp = exp->mLeft->mLeft->mLeft;

exp->mLeft->mLeft->mRight = nullptr;

exp->mLeft->mRight->mType = EX_RESULT;
}
}
ConsumeToken(TK_SEMICOLON);
break;
case TK_BREAK:
Expand Down
2 changes: 1 addition & 1 deletion oscar64/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Parser
DeclarationScope * mGlobals, * mScope;
int mLocalIndex;
CompilationUnits * mCompilationUnits;
Declaration * mThisPointer;
Declaration * mThisPointer, * mReturnType;

LinkerSection * mCodeSection, * mDataSection, * mBSSection;

Expand Down

0 comments on commit 0b6a9c3

Please sign in to comment.