Optimize global variable alias analysis
This commit is contained in:
parent
214ebd93f2
commit
d3cba85efe
|
@ -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;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -192,6 +192,7 @@ public:
|
|||
|
||||
int mOffset;
|
||||
const char * mLine;
|
||||
bool mStartOfLine;
|
||||
|
||||
const Ident * mTokenIdent;
|
||||
char mTokenString[1024], mTokenChar;
|
||||
|
|
Loading…
Reference in New Issue