Optimize value forwarding and memory alias check

This commit is contained in:
drmortalwombat 2022-01-31 13:33:39 +01:00
parent 94efcaeca6
commit e1f605b28c
3 changed files with 119 additions and 83 deletions

View File

@ -395,6 +395,7 @@ Declaration* Declaration::ToConstType(void)
ndec->mFlags = mFlags | DTF_CONST;
ndec->mScope = mScope;
ndec->mParams = mParams;
ndec->mIdent = mIdent;
return ndec;
}
@ -425,8 +426,8 @@ bool Declaration::IsSubType(const Declaration* dec) const
return true;
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
return true;
else if (mType == DT_TYPE_STRUCT && dec->mType == DT_TYPE_STRUCT)
return mScope == dec->mScope;
else if (mType == DT_TYPE_STRUCT)
return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize);
else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM || mType == DT_TYPE_UNION)
return false;
else if (mType == DT_TYPE_ARRAY)
@ -472,17 +473,12 @@ bool Declaration::IsSame(const Declaration* dec) const
return true;
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
return true;
else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM)
{
if (mIdent == dec->mIdent)
return true;
else
return false;
}
else if (mType == DT_TYPE_ENUM)
return mIdent == dec->mIdent;
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
return mBase->IsSame(dec->mBase);
else if (mType == DT_TYPE_STRUCT && dec->mType == DT_TYPE_STRUCT)
return mScope == dec->mScope;
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))
@ -518,7 +514,7 @@ bool Declaration::CanAssign(const Declaration* fromType) const
return true;
}
else if (mType == DT_TYPE_STRUCT && fromType->mType == DT_TYPE_STRUCT)
return mScope == fromType->mScope;
return mScope == fromType->mScope || (mIdent == fromType->mIdent && mSize == fromType->mSize);
else if (mType == DT_TYPE_POINTER)
{
if (fromType->mType == DT_TYPE_POINTER || fromType->mType == DT_TYPE_ARRAY)

View File

@ -5708,10 +5708,10 @@ static int Find(GrowingIntArray& table, int i)
return j;
}
static bool MatchingMem(const InterOperand& op1, const InterOperand& op2)
static bool CollidingMem(const InterOperand& op1, const InterOperand& op2)
{
if (op1.mMemory != op2.mMemory)
return false;
return op1.mMemory == IM_INDIRECT || op2.mMemory == IM_INDIRECT;
switch (op1.mMemory)
{
@ -5727,18 +5727,21 @@ static bool MatchingMem(const InterOperand& op1, const InterOperand& op2)
else
return false;
case IM_INDIRECT:
if (op1.mTemp == op2.mTemp)
return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize;
else
return true;
default:
return false;
}
}
static bool MatchingMem(const InterOperand& op, const InterInstruction * ins)
static bool CollidingMem(const InterOperand& op, const InterInstruction * ins)
{
if (ins->mCode == IC_LOAD)
return MatchingMem(op, ins->mSrc[0]);
return CollidingMem(op, ins->mSrc[0]);
else if (ins->mCode == IC_STORE)
return MatchingMem(op, ins->mSrc[1]);
return CollidingMem(op, ins->mSrc[1]);
else
return false;
}
@ -5759,7 +5762,7 @@ static bool SameMem(const InterOperand& op1, const InterOperand& op2)
case IM_GLOBAL:
return op1.mLinkerObject == op2.mLinkerObject;
case IM_INDIRECT:
return op1.mTemp == op2.mTemp;
default:
return false;
}
@ -5775,6 +5778,19 @@ static bool SameMem(const InterOperand& op, const InterInstruction* ins)
return false;
}
static bool SameInstruction(const InterInstruction* ins1, const InterInstruction* ins2)
{
if (ins1->mCode == ins2->mCode && ins1->mNumOperands == ins2->mNumOperands && ins1->mOperator == ins2->mOperator)
{
for(int i=0; i<ins1->mNumOperands; i++)
if (!ins1->mSrc[i].IsEqual(ins2->mSrc[i]))
return false;
return true;
}
return false;
}
void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue)
{
if (!mVisited)
@ -5812,22 +5828,10 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
{
InterInstruction* ins(mInstructions[i]);
if (ins->mDst.mTemp >= 0)
{
int j = 0, k = 0, t = ins->mDst.mTemp;
while (j < mLoadStoreInstructions.Size())
{
if (t != mLoadStoreInstructions[j]->mDst.mTemp && t != mLoadStoreInstructions[j]->mSrc[0].mTemp)
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++;
}
mLoadStoreInstructions.SetSize(k);
}
InterInstruction * nins = nullptr;
bool flushMem = false;
if (ins->mCode == IC_LOAD)
{
if (ins->mSrc[0].mTemp < 0)
{
if (!ins->mVolatile)
{
@ -5859,33 +5863,68 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
}
}
else
mLoadStoreInstructions.Push(ins);
}
nins = ins;
}
}
else if (ins->mCode == IC_STORE)
{
if (ins->mSrc[1].mTemp < 0)
int j = 0, k = 0;
while (j < mLoadStoreInstructions.Size())
{
if (!CollidingMem(ins->mSrc[1], mLoadStoreInstructions[j]))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++;
}
mLoadStoreInstructions.SetSize(k);
if (!ins->mVolatile)
nins = ins;
}
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
flushMem = true;
else if (ins->mCode == IC_LEA || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR)
{
int j = 0;
while (j < mLoadStoreInstructions.Size() && !MatchingMem(ins->mSrc[1], mLoadStoreInstructions[j]))
while (j < mLoadStoreInstructions.Size() && !SameInstruction(ins, mLoadStoreInstructions[j]))
j++;
if (j < mLoadStoreInstructions.Size())
mLoadStoreInstructions[j] = ins;
else
mLoadStoreInstructions.Push(ins);
}
{
InterInstruction* lins = mLoadStoreInstructions[j];
ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mDst;
ins->mNumOperands = 1;
}
else
mLoadStoreInstructions.SetSize(0);
nins = ins;
}
else if (ins->mCode == IC_COPY)
mLoadStoreInstructions.SetSize(0);
else if (HasSideEffect(ins->mCode))
mLoadStoreInstructions.SetSize(0);
flushMem = true;
{
int j = 0, k = 0, t = ins->mDst.mTemp;
while (j < mLoadStoreInstructions.Size())
{
if (flushMem && (mLoadStoreInstructions[j]->mCode == IC_LOAD || mLoadStoreInstructions[j]->mCode == IC_STORE))
;
else if (t < 0)
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
else if (t != mLoadStoreInstructions[j]->mDst.mTemp)
{
int l = 0;
while (l < mLoadStoreInstructions[j]->mNumOperands && t != mLoadStoreInstructions[j]->mSrc[l].mTemp)
l++;
if (l == mLoadStoreInstructions[j]->mNumOperands)
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
}
j++;
}
mLoadStoreInstructions.SetSize(k);
}
if (nins)
mLoadStoreInstructions.Push(nins);
}
if (mTrueJump) mTrueJump->LoadStoreForwarding(mLoadStoreInstructions);
@ -9164,7 +9203,7 @@ void InterCodeProcedure::Disassemble(FILE* file)
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
{
#if 1
#if 0
#ifdef _WIN32
FILE* file;
static bool initial = true;

View File

@ -243,6 +243,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
ndec->mBase = dec->mBase;
ndec->mScope = dec->mScope;
ndec->mParams = dec->mParams;
ndec->mIdent = dec->mIdent;
dec = ndec;
}
mScanner->NextToken();