Improve cross function memory aliasing analysis
This commit is contained in:
parent
34947da898
commit
d9f81ad653
|
@ -501,11 +501,33 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1,
|
||||||
if (op1.mRestricted)
|
if (op1.mRestricted)
|
||||||
return false;
|
return false;
|
||||||
else if (op2.mMemory == IM_GLOBAL)
|
else if (op2.mMemory == IM_GLOBAL)
|
||||||
return mProc->mModule->mGlobalVars[op2.mVarIndex]->mAliased;
|
{
|
||||||
|
if (op1.mMemoryBase == IM_GLOBAL)
|
||||||
|
return op1.mVarIndex == op2.mVarIndex && CollidingMemType(type1, type2);
|
||||||
|
else
|
||||||
|
return mProc->mModule->mGlobalVars[op2.mVarIndex]->mAliased;
|
||||||
|
}
|
||||||
else if (op2.mMemory == IM_FPARAM || op2.mMemory == IM_FFRAME)
|
else if (op2.mMemory == IM_FPARAM || op2.mMemory == IM_FFRAME)
|
||||||
return false;
|
return false;
|
||||||
else if (op2.mMemory == IM_LOCAL)
|
else if (op2.mMemory == IM_LOCAL)
|
||||||
return mProc->mLocalVars[op2.mVarIndex]->mAliased && CollidingMemType(type1, type2);
|
{
|
||||||
|
if (op1.mMemoryBase == IM_LOCAL)
|
||||||
|
return op1.mVarIndex == op2.mVarIndex && CollidingMemType(type1, type2);
|
||||||
|
else
|
||||||
|
return mProc->mLocalVars[op2.mVarIndex]->mAliased && CollidingMemType(type1, type2);
|
||||||
|
}
|
||||||
|
else if (op2.mMemory == IM_INDIRECT && (op1.mMemoryBase != IM_NONE && op2.mMemoryBase != IM_NONE && op1.mMemoryBase != IM_INDIRECT && op2.mMemoryBase != IM_INDIRECT))
|
||||||
|
{
|
||||||
|
if (op1.mMemoryBase == op2.mMemoryBase)
|
||||||
|
{
|
||||||
|
if (op1.mMemoryBase == IM_LOCAL || op1.mMemoryBase == IM_GLOBAL)
|
||||||
|
return op1.mVarIndex == op2.mVarIndex && CollidingMemType(type1, type2);
|
||||||
|
else
|
||||||
|
return CollidingMemType(type1, type2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return CollidingMemType(type1, type2);
|
return CollidingMemType(type1, type2);
|
||||||
}
|
}
|
||||||
|
@ -514,11 +536,21 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1,
|
||||||
if (op2.mRestricted)
|
if (op2.mRestricted)
|
||||||
return false;
|
return false;
|
||||||
else if (op1.mMemory == IM_GLOBAL)
|
else if (op1.mMemory == IM_GLOBAL)
|
||||||
return mProc->mModule->mGlobalVars[op1.mVarIndex]->mAliased;
|
{
|
||||||
|
if (op2.mMemoryBase == IM_GLOBAL)
|
||||||
|
return op1.mVarIndex == op2.mVarIndex;
|
||||||
|
else
|
||||||
|
return mProc->mModule->mGlobalVars[op1.mVarIndex]->mAliased;
|
||||||
|
}
|
||||||
else if (op1.mMemory == IM_FPARAM || op1.mMemory == IM_FFRAME)
|
else if (op1.mMemory == IM_FPARAM || op1.mMemory == IM_FFRAME)
|
||||||
return false;
|
return false;
|
||||||
else if (op1.mMemory == IM_LOCAL)
|
else if (op1.mMemory == IM_LOCAL)
|
||||||
return mProc->mLocalVars[op1.mVarIndex]->mAliased && CollidingMemType(type1, type2);
|
{
|
||||||
|
if (op1.mMemoryBase == IM_LOCAL)
|
||||||
|
return op1.mVarIndex == op2.mVarIndex;
|
||||||
|
else
|
||||||
|
return mProc->mLocalVars[op1.mVarIndex]->mAliased && CollidingMemType(type1, type2);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return CollidingMemType(type1, type2);
|
return CollidingMemType(type1, type2);
|
||||||
}
|
}
|
||||||
|
@ -3025,7 +3057,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
|
|
||||||
|
|
||||||
InterOperand::InterOperand(void)
|
InterOperand::InterOperand(void)
|
||||||
: mTemp(INVALID_TEMPORARY), mType(IT_NONE), mFinal(false), mIntConst(0), mFloatConst(0), mVarIndex(-1), mOperandSize(0), mLinkerObject(nullptr), mMemory(IM_NONE), mStride(1), mRestricted(0)
|
: mTemp(INVALID_TEMPORARY), mType(IT_NONE), mFinal(false), mIntConst(0), mFloatConst(0), mVarIndex(-1), mOperandSize(0), mLinkerObject(nullptr), mMemory(IM_NONE), mStride(1), mRestricted(0), mMemoryBase(IM_NONE)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool InterOperand::IsNotUByte(void) const
|
bool InterOperand::IsNotUByte(void) const
|
||||||
|
@ -3088,6 +3120,7 @@ void InterOperand::ForwardMem(const InterOperand& op)
|
||||||
mOperandSize = op.mOperandSize;
|
mOperandSize = op.mOperandSize;
|
||||||
mLinkerObject = op.mLinkerObject;
|
mLinkerObject = op.mLinkerObject;
|
||||||
mMemory = op.mMemory;
|
mMemory = op.mMemory;
|
||||||
|
mMemoryBase = op.mMemoryBase;
|
||||||
mTemp = op.mTemp;
|
mTemp = op.mTemp;
|
||||||
mType = op.mType;
|
mType = op.mType;
|
||||||
mRange = op.mRange;
|
mRange = op.mRange;
|
||||||
|
@ -4566,7 +4599,62 @@ void InterOperand::Disassemble(FILE* file, InterCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mRestricted)
|
if (mRestricted)
|
||||||
fprintf(file, "{%d}", mRestricted);
|
fprintf(file, "{R%d}", mRestricted);
|
||||||
|
else if (mMemory == IM_INDIRECT && mMemoryBase != IM_INDIRECT && mMemoryBase != IM_NONE)
|
||||||
|
{
|
||||||
|
const char* vname = "";
|
||||||
|
bool aliased = false;
|
||||||
|
|
||||||
|
if (mMemoryBase == IM_LOCAL)
|
||||||
|
{
|
||||||
|
if (!proc->mLocalVars[mVarIndex])
|
||||||
|
vname = "null";
|
||||||
|
else if (!proc->mLocalVars[mVarIndex]->mIdent)
|
||||||
|
{
|
||||||
|
vname = "";
|
||||||
|
aliased = proc->mLocalVars[mVarIndex]->mAliased;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vname = proc->mLocalVars[mVarIndex]->mIdent->mString;
|
||||||
|
aliased = proc->mLocalVars[mVarIndex]->mAliased;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mMemoryBase == IM_PROCEDURE)
|
||||||
|
{
|
||||||
|
if (proc->mModule->mProcedures[mVarIndex])
|
||||||
|
vname = proc->mModule->mProcedures[mVarIndex]->mIdent->mString;
|
||||||
|
else if (mLinkerObject && mLinkerObject->mIdent)
|
||||||
|
vname = mLinkerObject->mIdent->mString;
|
||||||
|
}
|
||||||
|
else if (mMemoryBase == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
if (mVarIndex < 0)
|
||||||
|
{
|
||||||
|
if (mLinkerObject && mLinkerObject->mIdent)
|
||||||
|
vname = mLinkerObject->mIdent->mString;
|
||||||
|
else
|
||||||
|
vname = "";
|
||||||
|
}
|
||||||
|
else if (!proc->mModule->mGlobalVars[mVarIndex])
|
||||||
|
vname = "null";
|
||||||
|
else if (!proc->mModule->mGlobalVars[mVarIndex]->mIdent)
|
||||||
|
{
|
||||||
|
vname = "";
|
||||||
|
aliased = proc->mModule->mGlobalVars[mVarIndex]->mAliased;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vname = proc->mModule->mGlobalVars[mVarIndex]->mIdent->mString;
|
||||||
|
aliased = proc->mModule->mGlobalVars[mVarIndex]->mAliased;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aliased)
|
||||||
|
fprintf(file, " {V(%d '%s' A)} ", mVarIndex, vname);
|
||||||
|
else
|
||||||
|
fprintf(file, " {V(%d '%s')} ", mVarIndex, vname);
|
||||||
|
}
|
||||||
|
|
||||||
if (mRange.mMinState >= IntegerValueRange::S_WEAK || mRange.mMaxState >= IntegerValueRange::S_WEAK)
|
if (mRange.mMinState >= IntegerValueRange::S_WEAK || mRange.mMaxState >= IntegerValueRange::S_WEAK)
|
||||||
{
|
{
|
||||||
|
@ -10927,7 +11015,16 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
||||||
InterOperand& op(lins->mSrc[k]);
|
InterOperand& op(lins->mSrc[k]);
|
||||||
|
|
||||||
if (op.mTemp >= 0)
|
if (op.mTemp >= 0)
|
||||||
flush = proc->mStoresIndirect;
|
{
|
||||||
|
if (op.mMemoryBase == IM_GLOBAL)
|
||||||
|
flush = proc->ModifiesGlobal(op.mVarIndex);
|
||||||
|
else if (op.mMemoryBase == IM_LOCAL && !mProc->mLocalVars[op.mVarIndex]->mAliased)
|
||||||
|
flush = false;
|
||||||
|
else if ((op.mMemoryBase == IM_PARAM || op.mMemoryBase == IM_FPARAM) && !mProc->mParamVars[op.mVarIndex]->mAliased)
|
||||||
|
flush = false;
|
||||||
|
else
|
||||||
|
flush = proc->mStoresIndirect;
|
||||||
|
}
|
||||||
else if (op.mMemory == IM_FFRAME || op.mMemory == IM_FRAME)
|
else if (op.mMemory == IM_FFRAME || op.mMemory == IM_FRAME)
|
||||||
flush = true;
|
flush = true;
|
||||||
else if (op.mMemory == IM_GLOBAL)
|
else if (op.mMemory == IM_GLOBAL)
|
||||||
|
@ -14327,21 +14424,45 @@ void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPt
|
||||||
for (int j = 0; j < ins->mNumOperands; j++)
|
for (int j = 0; j < ins->mNumOperands; j++)
|
||||||
{
|
{
|
||||||
if (ins->mSrc[j].mTemp > 0 && ltvalue[ins->mSrc[j].mTemp] && ins->mSrc[j].mType == IT_POINTER)
|
if (ins->mSrc[j].mTemp > 0 && ltvalue[ins->mSrc[j].mTemp] && ins->mSrc[j].mType == IT_POINTER)
|
||||||
|
{
|
||||||
ins->mSrc[j].mRestricted = ltvalue[ins->mSrc[j].mTemp]->mDst.mRestricted;
|
ins->mSrc[j].mRestricted = ltvalue[ins->mSrc[j].mTemp]->mDst.mRestricted;
|
||||||
|
ins->mSrc[j].mMemoryBase = ltvalue[ins->mSrc[j].mTemp]->mDst.mMemoryBase;
|
||||||
|
ins->mSrc[j].mVarIndex = ltvalue[ins->mSrc[j].mTemp]->mDst.mVarIndex;
|
||||||
|
ins->mSrc[j].mLinkerObject = ltvalue[ins->mSrc[j].mTemp]->mDst.mLinkerObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ins->mCode == IC_LEA)
|
||||||
|
{
|
||||||
|
ins->mDst.mRestricted = ins->mSrc[1].mRestricted;
|
||||||
|
if (ins->mSrc[1].mMemory != IM_INDIRECT)
|
||||||
|
ins->mSrc[1].mMemoryBase = ins->mSrc[1].mMemory;
|
||||||
|
ins->mDst.mMemoryBase = ins->mSrc[1].mMemoryBase;
|
||||||
|
ins->mDst.mVarIndex = ins->mSrc[1].mVarIndex;
|
||||||
|
ins->mDst.mLinkerObject = ins->mSrc[1].mLinkerObject;
|
||||||
|
}
|
||||||
|
else if (ins->mCode == IC_LOAD_TEMPORARY)
|
||||||
|
{
|
||||||
|
ins->mDst.mRestricted = ins->mSrc[0].mRestricted;
|
||||||
|
ins->mDst.mMemoryBase = ins->mSrc[0].mMemoryBase;
|
||||||
|
ins->mDst.mVarIndex = ins->mSrc[0].mVarIndex;
|
||||||
|
ins->mDst.mLinkerObject = ins->mSrc[0].mLinkerObject;
|
||||||
|
}
|
||||||
|
else if (ins->mCode == IC_CONSTANT)
|
||||||
|
{
|
||||||
|
ins->mDst.mRestricted = ins->mConst.mRestricted;
|
||||||
|
ins->mDst.mMemoryBase = ins->mConst.mMemory;
|
||||||
|
ins->mDst.mVarIndex = ins->mConst.mVarIndex;
|
||||||
|
ins->mDst.mLinkerObject = ins->mConst.mLinkerObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ins->mDst.mTemp >= 0)
|
if (ins->mDst.mTemp >= 0)
|
||||||
{
|
{
|
||||||
if (ins->mDst.mRestricted)
|
if (ins->mDst.mRestricted || ins->mDst.mMemoryBase != IM_NONE)
|
||||||
ltvalue[ins->mDst.mTemp] = ins;
|
ltvalue[ins->mDst.mTemp] = ins;
|
||||||
else
|
else
|
||||||
ltvalue[ins->mDst.mTemp] = nullptr;
|
ltvalue[ins->mDst.mTemp] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ins->mCode == IC_LEA)
|
|
||||||
ins->mDst.mRestricted = ins->mSrc[1].mRestricted;
|
|
||||||
else if (ins->mCode == IC_LOAD_TEMPORARY)
|
|
||||||
ins->mDst.mRestricted = ins->mSrc[0].mRestricted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17757,7 +17878,7 @@ void InterCodeBasicBlock::CollectGlobalReferences(NumberSet& referencedGlobals,
|
||||||
case IC_LOAD:
|
case IC_LOAD:
|
||||||
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[0].mVarIndex >= 0)
|
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[0].mVarIndex >= 0)
|
||||||
referencedGlobals += ins->mSrc[0].mVarIndex;
|
referencedGlobals += ins->mSrc[0].mVarIndex;
|
||||||
else if (ins->mSrc[0].mTemp >= 0)
|
else if (ins->mSrc[0].mTemp >= 0 && (ins->mSrc[0].mMemoryBase == IM_NONE || ins->mSrc[0].mMemoryBase == IM_INDIRECT))
|
||||||
loadsIndirect = true;
|
loadsIndirect = true;
|
||||||
break;
|
break;
|
||||||
case IC_STORE:
|
case IC_STORE:
|
||||||
|
@ -17766,21 +17887,21 @@ void InterCodeBasicBlock::CollectGlobalReferences(NumberSet& referencedGlobals,
|
||||||
referencedGlobals += ins->mSrc[1].mVarIndex;
|
referencedGlobals += ins->mSrc[1].mVarIndex;
|
||||||
modifiedGlobals += ins->mSrc[1].mVarIndex;
|
modifiedGlobals += ins->mSrc[1].mVarIndex;
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[1].mTemp >= 0)
|
else if (ins->mSrc[1].mTemp >= 0 && (ins->mSrc[1].mMemoryBase == IM_NONE || ins->mSrc[1].mMemoryBase == IM_INDIRECT))
|
||||||
storesIndirect = true;
|
storesIndirect = true;
|
||||||
break;
|
break;
|
||||||
case IC_COPY:
|
case IC_COPY:
|
||||||
case IC_STRCPY:
|
case IC_STRCPY:
|
||||||
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[0].mVarIndex >= 0)
|
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[0].mVarIndex >= 0)
|
||||||
referencedGlobals += ins->mSrc[0].mVarIndex;
|
referencedGlobals += ins->mSrc[0].mVarIndex;
|
||||||
else if (ins->mSrc[0].mTemp >= 0)
|
else if (ins->mSrc[0].mTemp >= 0 && (ins->mSrc[0].mMemoryBase == IM_NONE || ins->mSrc[0].mMemoryBase == IM_INDIRECT))
|
||||||
loadsIndirect = true;
|
loadsIndirect = true;
|
||||||
if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && ins->mSrc[1].mVarIndex >= 0)
|
if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && ins->mSrc[1].mVarIndex >= 0)
|
||||||
{
|
{
|
||||||
referencedGlobals += ins->mSrc[1].mVarIndex;
|
referencedGlobals += ins->mSrc[1].mVarIndex;
|
||||||
modifiedGlobals += ins->mSrc[1].mVarIndex;
|
modifiedGlobals += ins->mSrc[1].mVarIndex;
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[1].mTemp >= 0)
|
else if (ins->mSrc[1].mTemp >= 0 && (ins->mSrc[1].mMemoryBase == IM_NONE || ins->mSrc[1].mMemoryBase == IM_INDIRECT))
|
||||||
storesIndirect = true;
|
storesIndirect = true;
|
||||||
break;
|
break;
|
||||||
case IC_CALL:
|
case IC_CALL:
|
||||||
|
@ -19171,7 +19292,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "_menuShowSprites");
|
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||||
CheckCase = false;
|
CheckCase = false;
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
|
|
@ -270,7 +270,7 @@ public:
|
||||||
double mFloatConst;
|
double mFloatConst;
|
||||||
int mVarIndex, mOperandSize, mStride, mRestricted;
|
int mVarIndex, mOperandSize, mStride, mRestricted;
|
||||||
LinkerObject * mLinkerObject;
|
LinkerObject * mLinkerObject;
|
||||||
InterMemory mMemory;
|
InterMemory mMemory, mMemoryBase;
|
||||||
IntegerValueRange mRange;
|
IntegerValueRange mRange;
|
||||||
|
|
||||||
void Forward(const InterOperand& op);
|
void Forward(const InterOperand& op);
|
||||||
|
|
Loading…
Reference in New Issue