Shortcut jump cascades

This commit is contained in:
drmortalwombat 2023-07-10 22:12:41 +02:00
parent 00ded29b35
commit 6178bb1f9d
7 changed files with 146 additions and 34 deletions

View File

@ -8,6 +8,14 @@ static inline void smemcpy(char * dp, const char * sp, char s)
dp[i] = sp[i];
}
static inline char sstrlen(const char * sp)
{
char n = 0;
while (sp[n])
n++;
return n;
}
string::string(void) : cstr(nullptr)
{}
@ -16,7 +24,7 @@ string::string(const string & s)
if (s.cstr)
{
char l = s.cstr[0];
cstr = malloc(l + 2);
cstr = malloc(char(l + 2));
smemcpy(cstr, s.cstr, l + 2);
}
else
@ -25,10 +33,10 @@ string::string(const string & s)
string::string(const char * s)
{
char l = strlen(s);
char l = sstrlen(s);
if (l)
{
cstr = malloc(l + 2);
cstr = malloc(char(l + 2));
cstr[0] = l;
smemcpy(cstr + 1, s, l + 1);
}
@ -64,7 +72,7 @@ string & string::operator=(const string & s)
if (s.cstr)
{
char l = s.cstr[0];
cstr = malloc(l + 2);
cstr = malloc(char(l + 2));
smemcpy(cstr, s.cstr, l + 2);
}
else
@ -77,10 +85,10 @@ string & string::operator=(const string & s)
string & string::operator=(const char * s)
{
free(cstr);
char l = strlen(s);
char l = sstrlen(s);
if (l)
{
cstr = malloc(l + 2);
cstr = malloc(char(l + 2));
cstr[0] = l;
smemcpy(cstr + 1, s, l + 1);
}
@ -97,7 +105,7 @@ string & string::operator+=(const string & s)
if (cstr)
{
char l = cstr[0] + s.cstr[0];
char * c = malloc(l + 2);
char * c = malloc(char(l + 2));
c[0] = l;
smemcpy(c + 1, cstr + 1, cstr[0]);
smemcpy(c + 1 + cstr[0], s.cstr + 1, s.cstr[0] + 1);
@ -107,7 +115,7 @@ string & string::operator+=(const string & s)
else
{
char l = s.cstr[0];
cstr = malloc(l + 2);
cstr = malloc(char(l + 2));
smemcpy(cstr, s.cstr, l + 2);
}
}
@ -116,13 +124,13 @@ string & string::operator+=(const string & s)
string & string::operator+=(const char * s)
{
char sl = strlen(s);
char sl = sstrlen(s);
if (sl)
{
if (cstr)
{
char l = sl + cstr[0];
char * c = malloc(l + 2);
char * c = malloc(char(l + 2));
c[0] = l;
smemcpy(c + 1, cstr + 1, cstr[0]);
smemcpy(c + 1 + cstr[0], s, sl + 1);
@ -131,7 +139,7 @@ string & string::operator+=(const char * s)
}
else
{
cstr = malloc(sl + 2);
cstr = malloc(char(sl + 2));
cstr[0] = sl;
smemcpy(cstr + 1, s, sl + 1);
}
@ -144,7 +152,7 @@ string & string::operator+=(char c)
if (cstr)
{
char l = cstr[0] + 1;
char * p = malloc(l + 2);
char * p = malloc(char(l + 2));
p[0] = l;
smemcpy(p + 1, cstr + 1, cstr[0]);
p[l] = c;
@ -185,7 +193,7 @@ string string::operator+(const string & s) const
if (s.cstr)
{
char l = cstr[0] + s.cstr[0];
char * p = malloc(l + 2);
char * p = malloc(char(l + 2));
smemcpy(p + 1, cstr + 1, cstr[0]);
smemcpy(p + 1 + cstr[0], s.cstr + 1, s.cstr[0]);
return string(l, p);
@ -201,11 +209,11 @@ string string::operator+(const char * s) const
{
if (cstr)
{
char sl = strlen(s);
char sl = sstrlen(s);
if (sl)
{
char l = cstr[0] + sl;
char * p = malloc(l + 2);
char * p = malloc(char(l + 2));
smemcpy(p + 1, cstr + 1, cstr[0]);
smemcpy(p + 1 + cstr[0], s, sl);
return string(l, p);
@ -222,7 +230,7 @@ string string::operator+(char c) const
if (cstr)
{
char l = cstr[0] + 1;
char * p = malloc(l + 2);
char * p = malloc(char(l + 2));
smemcpy(p + 1, cstr + 1, cstr[0]);
p[l] = c;
return string(l, p);
@ -472,7 +480,7 @@ int string::find(const char * s, char pos) const
if (cstr)
{
char l = cstr[0];
char sl = strlen(s);
char sl = sstrlen(s);
if (sl <= l)
{
l -= sl;

View File

@ -11863,7 +11863,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
for (int i = 0; i < path.Size(); i++)
printf("path %d\n", path[i]->mIndex);
#endif
bool hasCall = false, hasFrame = false;
bool hasCall = false, hasFrame = false, hasStore = false;
for (int bi = 0; bi < body.Size(); bi++)
{
InterCodeBasicBlock* block = body[bi];
@ -11877,6 +11877,17 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
hasCall = true;
else if (ins->mCode == IC_PUSH_FRAME)
hasFrame = true;
else if (ins->mCode == IC_STORE)
{
if (ins->mSrc[1].mTemp >= 0)
hasStore = true;
else if ((ins->mSrc[1].mMemory == IM_PARAM || ins->mSrc[1].mMemory == IM_FPARAM) && !aliasedParams[ins->mSrc[1].mVarIndex])
;
else
hasStore = true;
}
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
hasStore = true;
}
}
@ -11897,7 +11908,11 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
ins->mInvariant = false;
else if (ins->mCode == IC_LOAD)
{
if (ins->mSrc[0].mTemp >= 0 || ins->mVolatile)
if (ins->mVolatile)
{
ins->mInvariant = false;
}
else if (ins->mSrc[0].mTemp >= 0 && (hasStore || hasCall))
{
ins->mInvariant = false;
}
@ -16129,7 +16144,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "test_find");
CheckFunc = !strcmp(mIdent->mString, "string::find");
mEntryBlock = mBlocks[0];

View File

@ -969,6 +969,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
if (vp.mTemp != vr.mTemp)
{
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY);
cins->mNumOperands = 2;
cins->mSrc[0].mType = IT_POINTER;
cins->mSrc[0].mTemp = vr.mTemp;
@ -1276,6 +1277,8 @@ void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, I
else
{
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY);
cins->mNumOperands = 2;
cins->mSrc[0].mType = IT_POINTER;
cins->mSrc[0].mTemp = vr.mTemp;
cins->mSrc[0].mMemory = IM_INDIRECT;
@ -1753,6 +1756,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (vr.mTemp != vl.mTemp)
{
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_COPY);
ins->mNumOperands = 2;
ins->mSrc[0].mType = IT_POINTER;
ins->mSrc[0].mTemp = vr.mTemp;
ins->mSrc[0].mMemory = IM_INDIRECT;
@ -2118,8 +2123,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
crins->mDst.mTemp = proc->AddTemporary(crins->mDst.mType);
block->Append(crins);
int s = vl.mType->Stride();
bool binary = !(s & (s - 1));
if (binary)
{
int n = 0;
while (s > 1)
{
s >>= 1;
n++;
}
s = n;
}
InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CONSTANT);
cins->mConst.mIntConst = vl.mType->Stride();
cins->mConst.mIntConst = s;
cins->mDst.mType = IT_INT16;
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
block->Append(cins);
@ -2134,7 +2152,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
sins->mDst.mTemp = proc->AddTemporary(sins->mDst.mType);
block->Append(sins);
dins->mOperator = IA_DIVS;
dins->mOperator = binary ? IA_SAR : IA_DIVS;
dins->mSrc[0].mType = IT_INT16;
dins->mSrc[0].mTemp = cins->mDst.mTemp;
dins->mSrc[1].mType = IT_INT16;
@ -2834,6 +2852,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
mErrors->Error(sex->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_COPY);
ins->mNumOperands = 2;
ins->mSrc[0].mType = IT_POINTER;
ins->mSrc[0].mMemory = IM_INDIRECT;
ins->mSrc[0].mTemp = vr.mTemp;
@ -2931,6 +2951,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else
{
fins = new InterInstruction(exp->mLocation, IC_PUSH_FRAME);
fins->mNumOperands = 0;
fins->mConst.mIntConst = atotal;
block->Append(fins);
}
@ -3228,6 +3249,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
fins->mConst.mIntConst = atotal;
InterInstruction* xins = new InterInstruction(exp->mLocation, IC_POP_FRAME);
xins->mNumOperands = 0;
xins->mConst.mIntConst = atotal;
block->Append(xins);
}
@ -3690,6 +3712,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, destack, inlineMapper);
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_UNREACHABLE);
ins->mNumOperands = 0;
fblock->Append(ins);
fblock->Close(nullptr, nullptr);

View File

@ -34974,7 +34974,31 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
#endif
else if (
mIns[i + 0].mType == ASMIT_INC && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && !(mIns[i + 1].mLive & LIVE_MEM))
{
if (!(mIns[i + 0].mLive & LIVE_CPU_REG_X))
{
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns.Insert(i + 1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_INX));
mIns[i + 2].mType = ASMIT_TXA; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (!(mIns[i + 0].mLive & LIVE_CPU_REG_Y))
{
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns.Insert(i + 1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_INY));
mIns[i + 2].mType = ASMIT_TYA; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (!(mIns[i + 0].mLive & LIVE_CPU_REG_C))
{
mIns.Insert(i + 1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_CLC));
mIns[i + 2].mType = ASMIT_ADC; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 1;
progress = true;
}
}
#if 0
else if (
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
@ -39859,6 +39883,45 @@ bool NativeCodeBasicBlock::CalculateOffset(int& total)
return changed;
}
void NativeCodeBasicBlock::ShortcutJump(int offset)
{
if (mCode[offset] == 0x4c)
{
int i = 0;
while (i < mRelocations.Size() && mRelocations[i].mOffset != offset + 1)
i++;
if (i < mRelocations.Size())
{
LinkerReference& ref(mRelocations[i]);
if (ref.mRefObject && ref.mRefObject->mData)
{
LinkerObject* lo = ref.mRefObject;
if (lo->mData[ref.mRefOffset] == 0x4c || lo->mData[ref.mRefOffset] == 0x6c)
{
int j = 0;
while (j < lo->mReferences.Size() && lo->mReferences[j]->mOffset != ref.mRefOffset + 1)
j++;
if (j < lo->mReferences.Size())
{
mCode[offset] = lo->mData[ref.mRefOffset];
ref.mRefObject = lo->mReferences[j]->mRefObject;
ref.mRefOffset = lo->mReferences[j]->mRefOffset;
ref.mFlags = lo->mReferences[j]->mFlags;
}
else
{
mCode[offset] = lo->mData[ref.mRefOffset];
mCode[offset + 1] = lo->mData[ref.mRefOffset + 1];
mCode[offset + 2] = lo->mData[ref.mRefOffset + 2];
mRelocations.Remove(i);
}
}
}
}
}
}
void NativeCodeBasicBlock::ShortcutTailRecursion()
{
if (!mVisited)
@ -39869,6 +39932,7 @@ void NativeCodeBasicBlock::ShortcutTailRecursion()
this->mCode[this->mCode.Size() - 3] = 0x4c;
mTrueJump->mNumEntries--;
mTrueJump = nullptr;
ShortcutJump(this->mCode.Size() - 3);
}
else if (!mFalseJump && !mTrueJump)
{
@ -39877,6 +39941,7 @@ void NativeCodeBasicBlock::ShortcutTailRecursion()
{
this->mCode.Remove(this->mCode.Size() - 1);
this->mCode[this->mCode.Size() - 3] = 0x4c;
ShortcutJump(this->mCode.Size() - 3);
}
}

View File

@ -269,6 +269,7 @@ public:
void PrependInstruction(const NativeCodeInstruction& ins);
void ShortcutTailRecursion();
void ShortcutJump(int offset);
bool ReferencesAccu(int from = 0, int to = 65536) const;
bool ReferencesYReg(int from = 0, int to = 65536) const;

View File

@ -1337,7 +1337,7 @@ Expression* Parser::BuildMemberInitializer(Expression* vexp)
mScanner->NextToken();
if (mScanner->mToken != TK_CLOSE_PARENTHESIS)
{
fexp->mRight = ParseListExpression();
fexp->mRight = ParseListExpression(false);
ConsumeToken(TK_CLOSE_PARENTHESIS);
}
else
@ -2887,7 +2887,7 @@ void Parser::ParseVariableInit(Declaration* ndec)
mScanner->NextToken();
if (mScanner->mToken != TK_CLOSE_PARENTHESIS)
{
pexp = ParseListExpression();
pexp = ParseListExpression(false);
ConsumeToken(TK_CLOSE_PARENTHESIS);
}
else
@ -4332,7 +4332,7 @@ Expression* Parser::ParseQualify(Expression* exp)
nexp->mRight = nullptr;
else
{
nexp->mRight = ParseListExpression();
nexp->mRight = ParseListExpression(false);
ConsumeToken(TK_CLOSE_PARENTHESIS);
}
@ -4530,7 +4530,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
mScanner->NextToken();
if (mScanner->mToken != TK_CLOSE_PARENTHESIS)
{
pexp = ParseListExpression();
pexp = ParseListExpression(false);
ConsumeToken(TK_CLOSE_PARENTHESIS);
}
else
@ -4641,7 +4641,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
nexp->mLeft = exp;
if (mScanner->mToken != TK_CLOSE_PARENTHESIS)
{
nexp->mRight = ParseListExpression();
nexp->mRight = ParseListExpression(false);
ConsumeToken(TK_CLOSE_PARENTHESIS);
}
else
@ -4876,7 +4876,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
{
if (!ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
{
pexp = ParseListExpression();
pexp = ParseListExpression(false);
mdec = dec->mScope->Lookup(dec->mIdent);
@ -5717,16 +5717,16 @@ Expression* Parser::ParseExpression(bool lhs)
return ParseAssignmentExpression(lhs);
}
Expression* Parser::ParseListExpression(void)
Expression* Parser::ParseListExpression(bool lhs)
{
Expression* exp = ParseExpression(true);
Expression* exp = ParseExpression(lhs);
if (mScanner->mToken == TK_COMMA)
{
Expression* nexp = new Expression(mScanner->mLocation, EX_LIST);
nexp->mToken = mScanner->mToken;
nexp->mLeft = exp;
mScanner->NextToken();
nexp->mRight = ParseListExpression();
nexp->mRight = ParseListExpression(false);
exp = nexp;
}
return exp;
@ -6183,7 +6183,7 @@ Expression* Parser::ParseStatement(void)
break;
default:
exp = CleanupExpression(ParseListExpression());
exp = CleanupExpression(ParseListExpression(true));
ConsumeToken(TK_SEMICOLON);
}
}

View File

@ -105,7 +105,7 @@ protected:
Expression* ParseAssignmentExpression(bool lhs);
Expression* ParseExpression(bool lhs);
Expression* ParseRExpression(void);
Expression* ParseListExpression(void);
Expression* ParseListExpression(bool lhs);
Expression* ParseParenthesisExpression(void);