Shortcut jump cascades
This commit is contained in:
parent
00ded29b35
commit
6178bb1f9d
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue