Optimize global variable alias analysis

This commit is contained in:
drmortalwombat 2021-11-01 12:42:03 +01:00
parent 214ebd93f2
commit d3cba85efe
8 changed files with 215 additions and 132 deletions

View File

@ -72,6 +72,8 @@ static const uint32 DTF_FUNC_ASSEMBLER = 0x00080000;
static const uint32 DTF_FUNC_RECURSIVE = 0x00100000;
static const uint32 DTF_FUNC_ANALYZING = 0x00200000;
static const uint32 DTF_VAR_ALIASING = 0x00400000;
class Declaration;

View File

@ -535,6 +535,13 @@ int Emulator::Emulate(int startIP)
mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1;
mRegS += 2;
}
else if (mIP == 0xffcf)
{
int ch = getchar();
mRegA = ch;
mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1;
mRegS += 2;
}
uint8 opcode = mMemory[mIP];
AsmInsData d = DecInsData[opcode];

View File

@ -280,6 +280,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
case EX_PREINCDEC:
return Analyze(exp->mLeft, procDec);
case EX_PREFIX:
ldec = Analyze(exp->mLeft, procDec);
if (exp->mToken == TK_BINARY_AND)
{
if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING;
}
break;
case EX_POSTFIX:
break;

View File

@ -433,7 +433,7 @@ static bool MemRange(const InterInstruction * ins, const GrowingInstructionPtrAr
return false;
}
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
{
InterMemory lmem, smem;
int lvindex, svindex;
@ -457,6 +457,8 @@ static bool StoreAliasing(const InterInstruction * lins, const InterInstruction*
return aliasedLocals[lvindex];
else if (lmem == IM_PARAM || lmem == IM_FPARAM)
return aliasedParams[lvindex];
else if (lmem == IM_GLOBAL)
return staticVars[lvindex]->mAliased;
}
return true;
@ -514,7 +516,7 @@ bool InterInstruction::IsEqual(const InterInstruction* ins) const
}
void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
{
int i, value, temp;
@ -609,7 +611,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
i = 0;
while (i < mNum)
{
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams))
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams, staticVars))
{
mNum--;
if (mNum > 0)
@ -627,7 +629,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
i = 0;
while (i < mNum)
{
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams))
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams, staticVars))
{
mNum--;
if (mNum > 0)
@ -787,7 +789,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
return;
}
@ -806,7 +808,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[1].mTemp = -1;
assert(ins->mSrc[0].mTemp >= 0);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
return;
}
@ -817,7 +819,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
return;
}
@ -832,7 +834,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[1].mTemp = -1;
assert(ins->mSrc[0].mTemp >= 0);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
return;
}
@ -844,7 +846,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
return;
}
@ -854,7 +856,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mOperator = IA_NEG;
ins->mSrc[1].mTemp = -1;
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
return;
}
@ -868,7 +870,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
return;
}
@ -878,7 +880,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[1].mTemp = -1;
assert(ins->mSrc[0].mTemp >= 0);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
return;
}
@ -1093,7 +1095,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
}
break;
case IT_POINTER:
@ -1107,7 +1109,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
}
else if (ins->mSrc[1].mTemp == ins->mSrc[0].mTemp)
{
@ -1133,7 +1135,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
}
break;
}
@ -1298,7 +1300,11 @@ void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticV
{
if (mSrc[0].mMemory == IM_INDIRECT)
{
requiredVars.OrNot(providedVars);
for (int i = 0; i < staticVars.Size(); i++)
{
if (staticVars[i]->mAliased && !providedVars[i])
requiredVars += i;
}
}
else if (mSrc[0].mMemory == IM_GLOBAL)
{
@ -1310,7 +1316,11 @@ void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticV
{
if (mSrc[1].mMemory == IM_INDIRECT)
{
requiredVars.OrNot(providedVars);
for (int i = 0; i < staticVars.Size(); i++)
{
if (staticVars[i]->mAliased && !providedVars[i])
requiredVars += i;
}
}
else if (mSrc[1].mMemory == IM_GLOBAL)
{
@ -1565,7 +1575,11 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable
{
if (mSrc[0].mMemory == IM_INDIRECT)
{
requiredVars.Fill();
for (int i = 0; i < staticVars.Size(); i++)
{
if (staticVars[i]->mAliased)
requiredVars += i;
}
}
else if (mSrc[0].mMemory == IM_GLOBAL)
{
@ -3185,7 +3199,7 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr
}
void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int& spareTemps)
void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int& spareTemps, const GrowingVariableArray& staticVars)
{
int i;
@ -3441,12 +3455,12 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra
}
#endif
lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams);
lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams, staticVars);
mInstructions[i]->PerformValueForwarding(ltvalue, tvalid);
}
if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps);
if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps);
if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps, staticVars);
if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps, staticVars);
}
}
@ -4885,7 +4899,7 @@ void InterCodeProcedure::Close(void)
tvalidSet.Reset(numTemps + 32);
ResetVisited();
mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet, numTemps);
mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet, numTemps, mModule->mGlobalVars);
ResetVisited();
eliminated = mEntryBlock->EliminateDeadBranches();

View File

@ -148,7 +148,7 @@ public:
void RemoveValue(int index);
void InsertValue(InterInstruction * ins);
void UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams);
void UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
void Intersect(ValueSet& set);
};
@ -475,7 +475,7 @@ public:
void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue);
void PerformTempForwarding(TempForwardingTable& forwardingTable);
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps);
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps, const GrowingVariableArray& staticVars);
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
bool EliminateDeadBranches(void);

View File

@ -837,6 +837,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
var->mIdent = dec->mIdent;
var->mOffset = 0;
var->mSize = dec->mSize;
if ((dec->mFlags & DTF_VAR_ALIASING) || dec->mBase->mType == DT_TYPE_ARRAY)
var->mAliased = true;
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
dec->mLinkerObject = var->mLinkerObject;
var->mLinkerObject->AddData(dec->mData, dec->mSize);

View File

@ -6,7 +6,8 @@
#include "MachineTypes.h"
const char* TokenNames[] = {
const char* TokenNames[] =
{
"tk_none",
"tk_eof",
"tk_error",
@ -138,7 +139,7 @@ const char* TokenNames[] = {
Macro::Macro(const Ident* ident)
: mIdent(ident), mString(nullptr), mNumArguments(0)
: mIdent(ident), mString(nullptr), mNumArguments(-1)
{
}
@ -471,6 +472,8 @@ void Scanner::NextToken(void)
if (mTokenChar == '(')
{
macro->mNumArguments = 0;
NextRawToken();
if (mTokenChar == ')')
@ -635,7 +638,21 @@ void Scanner::NextToken(void)
{
MacroExpansion* ex = new MacroExpansion();
ex->mDefinedArguments = mDefineArguments;
if (def->mNumArguments)
if (def->mNumArguments == 0)
{
NextRawToken();
if (mToken != TK_OPEN_PARENTHESIS)
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Missing '(' for macro expansion");
else
NextRawToken();
if (mToken != TK_CLOSE_PARENTHESIS)
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Missing ')' for macro expansion");
else
NextRawToken();
}
else if (def->mNumArguments > 0)
{
mDefineArguments = new MacroDict();
NextRawToken();
@ -712,9 +729,8 @@ void Scanner::NextRawToken(void)
{
if (mToken != TK_EOF)
{
Token pt = mToken;
mToken = TK_ERROR;
mStartOfLine = false;
while (IsWhitespace(mTokenChar))
{
@ -1011,7 +1027,7 @@ void Scanner::NextRawToken(void)
case '#':
{
if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1)
if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1 || mStartOfLine)
{
int n = 0;
char tkprep[128];
@ -1375,6 +1391,7 @@ bool Scanner::NextChar(void)
else if (mPreprocessor->NextLine())
{
mOffset = 0;
mStartOfLine = true;
}
else
{
@ -1603,6 +1620,40 @@ int64 Scanner::PrepParseSimple(void)
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
break;
case TK_IDENT:
if (strcmp(mTokenIdent->mString, "defined") == 0)
{
NextToken();
if (mToken == TK_OPEN_PARENTHESIS)
{
NextRawToken();
if (mToken == TK_IDENT)
{
Macro* def = nullptr;
if (mDefineArguments)
def = mDefineArguments->Lookup(mTokenIdent);
if (!def)
def = mDefines->Lookup(mTokenIdent);
if (def)
v = 1;
else
v = 0;
NextToken();
}
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected");
if (mToken == TK_CLOSE_PARENTHESIS)
NextToken();
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
}
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "'(' expected");
}
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor symbol", mTokenIdent->mString);
break;
default:
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor token", TokenName(mToken));
if (mToken != TK_EOL)

View File

@ -192,6 +192,7 @@ public:
int mOffset;
const char * mLine;
bool mStartOfLine;
const Ident * mTokenIdent;
char mTokenString[1024], mTokenChar;