Expand global aliasing analysis
This commit is contained in:
parent
ae21bbac09
commit
0b1d42b7d5
|
@ -660,6 +660,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_ASSIGNMENT:
|
||||
ldec = Analyze(exp->mLeft, procDec, true);
|
||||
rdec = Analyze(exp->mRight, procDec, false);
|
||||
if (exp->mLeft->mType == EX_VARIABLE && exp->mRight->mType == EX_CALL && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
|
||||
exp->mLeft->mDecValue->mFlags |= DTF_VAR_ALIASING;
|
||||
RegisterProc(rdec);
|
||||
return ldec;
|
||||
|
||||
|
|
|
@ -3095,6 +3095,11 @@ void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable, Gro
|
|||
nparams = mSrc[1].mVarIndex + 1;
|
||||
}
|
||||
}
|
||||
else if (mSrc[1].mTemp >= 0)
|
||||
{
|
||||
localTable[mDst.mTemp] = localTable[mSrc[1].mTemp];
|
||||
paramTable[mDst.mTemp] = paramTable[mSrc[1].mTemp];
|
||||
}
|
||||
}
|
||||
else if (mCode == IC_LOAD_TEMPORARY)
|
||||
{
|
||||
|
@ -9918,6 +9923,39 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
else
|
||||
nins = ins;
|
||||
}
|
||||
else if (ins->mCode == IC_CALL_NATIVE && ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mLinkerObject && ins->mSrc[0].mLinkerObject->mProc && ins->mSrc[0].mLinkerObject->mProc->mGlobalsChecked)
|
||||
{
|
||||
InterCodeProcedure* proc = ins->mSrc[0].mLinkerObject->mProc;
|
||||
|
||||
int j = 0, k = 0;
|
||||
while (j < mLoadStoreInstructions.Size())
|
||||
{
|
||||
InterOperand* op = nullptr;
|
||||
|
||||
if (mLoadStoreInstructions[j]->mCode == IC_LOAD)
|
||||
op = mLoadStoreInstructions[j]->mSrc + 0;
|
||||
else if (mLoadStoreInstructions[j]->mCode == IC_STORE)
|
||||
op = mLoadStoreInstructions[j]->mSrc + 1;
|
||||
|
||||
bool flush = false;
|
||||
if (op)
|
||||
{
|
||||
if (op->mTemp >= 0)
|
||||
flush = proc->mStoresIndirect;
|
||||
else if (op->mMemory == IM_FFRAME || op->mMemory == IM_FRAME)
|
||||
flush = true;
|
||||
else if (op->mMemory == IM_GLOBAL)
|
||||
flush = proc->ModifiesGlobal(op->mVarIndex);
|
||||
else
|
||||
flush = true;
|
||||
}
|
||||
|
||||
if (!flush)
|
||||
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
|
||||
j++;
|
||||
}
|
||||
mLoadStoreInstructions.SetSize(k);
|
||||
}
|
||||
else if (HasSideEffect(ins->mCode))
|
||||
flushMem = true;
|
||||
|
||||
|
@ -11298,7 +11336,7 @@ void InterCodeBasicBlock::CollectStaticStack(LinkerObject* lobj, const GrowingVa
|
|||
|
||||
for (int i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
if (mInstructions[i]->mCode == IC_CALL || mInstructions[i]->mCode == IC_CALL_NATIVE)
|
||||
if ((mInstructions[i]->mCode == IC_CALL || mInstructions[i]->mCode == IC_CALL_NATIVE) && mInstructions[i]->mSrc[0].mLinkerObject->mStackSection)
|
||||
lobj->mStackSection->mSections.Push(mInstructions[i]->mSrc[0].mLinkerObject->mStackSection);
|
||||
|
||||
if (mInstructions[i]->mCode == IC_LOAD)
|
||||
|
@ -15350,6 +15388,74 @@ void InterCodeBasicBlock::CheckValueReturn(void)
|
|||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::CollectGlobalReferences(NumberSet& referencedGlobals, NumberSet& modifiedGlobals, bool& storesIndirect, bool& loadsIndirect, bool& globalsChecked)
|
||||
{
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
for (int i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
InterInstruction* ins = mInstructions[i];
|
||||
|
||||
switch (ins->mCode)
|
||||
{
|
||||
case IC_LOAD:
|
||||
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[0].mVarIndex >= 0)
|
||||
referencedGlobals += ins->mSrc[0].mVarIndex;
|
||||
else if (ins->mSrc[0].mTemp >= 0)
|
||||
loadsIndirect = true;
|
||||
break;
|
||||
case IC_STORE:
|
||||
if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && ins->mSrc[1].mVarIndex >= 0)
|
||||
{
|
||||
referencedGlobals += ins->mSrc[1].mVarIndex;
|
||||
modifiedGlobals += ins->mSrc[1].mVarIndex;
|
||||
}
|
||||
else if (ins->mSrc[1].mTemp >= 0)
|
||||
storesIndirect = true;
|
||||
break;
|
||||
case IC_COPY:
|
||||
case IC_STRCPY:
|
||||
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[0].mVarIndex >= 0)
|
||||
referencedGlobals += ins->mSrc[0].mVarIndex;
|
||||
else if (ins->mSrc[0].mTemp >= 0)
|
||||
loadsIndirect = true;
|
||||
if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && ins->mSrc[1].mVarIndex >= 0)
|
||||
{
|
||||
referencedGlobals += ins->mSrc[1].mVarIndex;
|
||||
modifiedGlobals += ins->mSrc[1].mVarIndex;
|
||||
}
|
||||
else if (ins->mSrc[1].mTemp >= 0)
|
||||
storesIndirect = true;
|
||||
break;
|
||||
case IC_CALL:
|
||||
case IC_CALL_NATIVE:
|
||||
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mLinkerObject && ins->mSrc[0].mLinkerObject->mProc)
|
||||
{
|
||||
InterCodeProcedure* proc = ins->mSrc[0].mLinkerObject->mProc;
|
||||
if (proc->mGlobalsChecked)
|
||||
{
|
||||
if (proc->mStoresIndirect)
|
||||
storesIndirect = true;
|
||||
if (proc->mLoadsIndirect)
|
||||
loadsIndirect = true;
|
||||
referencedGlobals |= proc->mReferencedGlobals;
|
||||
modifiedGlobals |= proc->mModifiedGlobals;
|
||||
}
|
||||
else
|
||||
globalsChecked = false;
|
||||
}
|
||||
else
|
||||
globalsChecked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump) mTrueJump->CollectGlobalReferences(referencedGlobals, modifiedGlobals, storesIndirect, loadsIndirect, globalsChecked);
|
||||
if (mFalseJump) mFalseJump->CollectGlobalReferences(referencedGlobals, modifiedGlobals, storesIndirect, loadsIndirect, globalsChecked);
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::WarnUsedUndefinedVariables(void)
|
||||
{
|
||||
|
@ -15707,7 +15813,7 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
|
|||
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), mDynamicStack(false),
|
||||
mSaveTempsLinkerObject(nullptr), mValueReturn(false), mFramePointer(false),
|
||||
mCheckUnreachable(true), mReturnType(IT_NONE), mCheapInline(false),
|
||||
mDeclaration(nullptr)
|
||||
mDeclaration(nullptr), mGlobalsChecked(false)
|
||||
{
|
||||
mID = mModule->mProcedures.Size();
|
||||
mModule->mProcedures.Push(this);
|
||||
|
@ -16551,7 +16657,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||
CheckFunc = !strcmp(mIdent->mString, "card_color");
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
||||
|
@ -17173,6 +17279,7 @@ void InterCodeProcedure::Close(void)
|
|||
|
||||
#if 1
|
||||
ResetVisited();
|
||||
|
||||
if (!mInterruptCalled && !mDynamicStack && mNativeProcedure && mEntryBlock->CheckStaticStack())
|
||||
{
|
||||
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
|
||||
|
@ -17379,6 +17486,18 @@ void InterCodeProcedure::Close(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (mTempSize <= BC_REG_TMP_SAVED - BC_REG_TMP && !(mLinkerObject->mFlags & LOBJF_STATIC_STACK) && mLeafProcedure)
|
||||
{
|
||||
bool hasLocals = false;
|
||||
|
||||
for (int i = 0; i < mLocalVars.Size(); i++)
|
||||
if (mLocalVars[i] && mLocalVars[i]->mUsed)
|
||||
hasLocals = true;
|
||||
|
||||
if (!hasLocals)
|
||||
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
|
||||
}
|
||||
|
||||
if (!mEntryBlock->mTrueJump)
|
||||
{
|
||||
int nconst = 0, nvariables = 0, nparams = 0, ncalls = 0, nret = 0, nother = 0, nops = 0;
|
||||
|
@ -17449,6 +17568,15 @@ void InterCodeProcedure::Close(void)
|
|||
if (nother == 0 && ncalls <= 1 && nret == 1 && nconst <= 1 + nparams && nops <= 1 + nparams)
|
||||
mCheapInline = true;
|
||||
}
|
||||
|
||||
mGlobalsChecked = true;
|
||||
mStoresIndirect = false;
|
||||
mLoadsIndirect = false;
|
||||
mReferencedGlobals.Reset(mModule->mGlobalVars.Size());
|
||||
mModifiedGlobals.Reset(mModule->mGlobalVars.Size());
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->CollectGlobalReferences(mReferencedGlobals, mModifiedGlobals, mStoresIndirect, mLoadsIndirect, mGlobalsChecked);
|
||||
}
|
||||
|
||||
void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc)
|
||||
|
@ -17778,6 +17906,36 @@ void InterCodeProcedure::MergeBasicBlocks(void)
|
|||
|
||||
}
|
||||
|
||||
bool InterCodeProcedure::ReferencesGlobal(int varindex)
|
||||
{
|
||||
if (mGlobalsChecked)
|
||||
{
|
||||
if (mModule->mGlobalVars[varindex]->mAliased)
|
||||
return mLoadsIndirect || mStoresIndirect;
|
||||
else if (varindex < mReferencedGlobals.Size())
|
||||
return mReferencedGlobals[varindex];
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InterCodeProcedure::ModifiesGlobal(int varindex)
|
||||
{
|
||||
if (mGlobalsChecked)
|
||||
{
|
||||
if (mModule->mGlobalVars[varindex]->mAliased)
|
||||
return mStoresIndirect;
|
||||
else if (varindex < mModifiedGlobals.Size())
|
||||
return mModifiedGlobals[varindex];
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void InterCodeProcedure::BuildLoopPrefix(void)
|
||||
{
|
||||
ResetVisited();
|
||||
|
|
|
@ -576,6 +576,8 @@ public:
|
|||
void WarnUsedUndefinedVariables(void);
|
||||
void CheckValueReturn(void);
|
||||
|
||||
void CollectGlobalReferences(NumberSet& referencedGlobals, NumberSet& modifiedGlobals, bool & storesIndirect, bool & loadsIndirect, bool & globalsChecked);
|
||||
|
||||
};
|
||||
|
||||
class InterCodeProcedure
|
||||
|
@ -614,6 +616,9 @@ public:
|
|||
InterType mReturnType;
|
||||
uint64 mCompilerOptions;
|
||||
|
||||
bool mLoadsIndirect, mStoresIndirect, mGlobalsChecked;
|
||||
NumberSet mReferencedGlobals, mModifiedGlobals;
|
||||
|
||||
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);
|
||||
~InterCodeProcedure(void);
|
||||
|
||||
|
@ -631,6 +636,9 @@ public:
|
|||
|
||||
void MapCallerSavedTemps(void);
|
||||
|
||||
bool ReferencesGlobal(int varindex);
|
||||
bool ModifiesGlobal(int varindex);
|
||||
|
||||
void MapVariables(void);
|
||||
void ReduceTemporaries(void);
|
||||
void Disassemble(FILE* file);
|
||||
|
|
|
@ -43,12 +43,14 @@ void LinkerObject::AddReference(const LinkerReference& ref)
|
|||
mReferences.Push(nref);
|
||||
}
|
||||
|
||||
LinkerReference* LinkerObject::FindReference(int offset)
|
||||
LinkerReference* LinkerObject::FindReference(int64 offset)
|
||||
{
|
||||
for (int i = 0; i < mReferences.Size(); i++)
|
||||
{
|
||||
if (mReferences[i]->mOffset == offset)
|
||||
return mReferences[i];
|
||||
else if ((mReferences[i]->mFlags & LREF_LOWBYTE) && (mReferences[i]->mFlags & LREF_HIGHBYTE) && mReferences[i]->mOffset + 1 == offset)
|
||||
return mReferences[i];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -202,7 +202,7 @@ public:
|
|||
|
||||
GrowingArray<LinkerReference*> mReferences;
|
||||
|
||||
LinkerReference* FindReference(int offset);
|
||||
LinkerReference* FindReference(int64 offset);
|
||||
|
||||
void AddReference(const LinkerReference& ref);
|
||||
|
||||
|
|
|
@ -7132,6 +7132,29 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
|
|||
}
|
||||
|
||||
if (size <= msize)
|
||||
{
|
||||
LinkerObject* slo = ins->mSrc[0].mLinkerObject;
|
||||
if (slo && (slo->mFlags & LOBJF_CONST))
|
||||
{
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
int64 si = ins->mSrc[0].mIntConst + offset + i * sstride;
|
||||
|
||||
LinkerReference* lr = slo->FindReference(si);
|
||||
if (lr)
|
||||
{
|
||||
if ((lr->mFlags & LREF_LOWBYTE) && lr->mOffset == si)
|
||||
block->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, lr->mRefOffset, lr->mRefObject, NCIF_LOWER));
|
||||
else
|
||||
block->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, lr->mRefOffset, lr->mRefObject, NCIF_UPPER));
|
||||
}
|
||||
else
|
||||
block->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, slo->mData[si]));
|
||||
block->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + offset + i * dstride, ins->mSrc[1].mLinkerObject, flags));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
|
@ -7139,6 +7162,7 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
|
|||
block->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + offset + i * dstride, ins->mSrc[1].mLinkerObject, flags));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
|
||||
|
@ -7156,6 +7180,40 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
|
|||
|
||||
return block;
|
||||
}
|
||||
else if ((ins->mSrc[0].mMemory == IM_GLOBAL || ins->mSrc[0].mMemory == IM_ABSOLUTE) && (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME))
|
||||
{
|
||||
LinkerObject* slo = ins->mSrc[0].mLinkerObject;
|
||||
if (slo && (slo->mFlags & LOBJF_CONST))
|
||||
{
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
int64 si = ins->mSrc[0].mIntConst + i * sstride;
|
||||
|
||||
LinkerReference* lr = slo->FindReference(si);
|
||||
if (lr)
|
||||
{
|
||||
if ((lr->mFlags & LREF_LOWBYTE) && lr->mOffset == si)
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, lr->mRefOffset, lr->mRefObject, NCIF_LOWER));
|
||||
else
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, lr->mRefOffset, lr->mRefObject, NCIF_UPPER));
|
||||
}
|
||||
else
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, slo->mData[si]));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst + i * dstride));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + i * sstride, ins->mSrc[0].mLinkerObject, flags));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst + i * dstride));
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue