Fix loop wrap around aliasing

This commit is contained in:
drmortalwombat 2024-09-19 21:01:24 +02:00
parent ff4a0802ea
commit 92b72b19ec
4 changed files with 294 additions and 210 deletions

View File

@ -259,6 +259,30 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
return changed; return changed;
} }
bool GlobalOptimizer::ReplaceGlobalConst(Expression* exp)
{
bool changed = false;
if (exp)
{
if (exp->mType == EX_VARIABLE && (exp->mDecValue->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(exp->mDecValue->mOptFlags & (OPTF_VAR_MODIFIED | OPTF_VAR_ADDRESS)) && exp->mDecValue->mValue)
{
Expression* cexp = exp->mDecValue->mValue;
if (cexp->mType == EX_CONSTANT)
{
exp->mType = EX_CONSTANT;
exp->mDecValue = cexp->mDecValue;
}
changed = true;
}
if (ReplaceGlobalConst(exp->mLeft))
changed = true;
if (ReplaceGlobalConst(exp->mRight))
changed = true;
}
return changed;
}
bool GlobalOptimizer::Optimize(void) bool GlobalOptimizer::Optimize(void)
{ {
bool changed = false; bool changed = false;
@ -282,6 +306,9 @@ bool GlobalOptimizer::Optimize(void)
if (CheckConstReturns(func->mValue)) if (CheckConstReturns(func->mValue))
changed = true; changed = true;
if (ReplaceGlobalConst(func->mValue))
changed = true;
if (func->mOptFlags & OPTF_MULTI_CALL) if (func->mOptFlags & OPTF_MULTI_CALL)
{ {
Declaration* pdata = ftype->mParams; Declaration* pdata = ftype->mParams;
@ -434,7 +461,6 @@ void GlobalOptimizer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
{ {
if (adec->mBase->mFlags & DTF_GLOBAL) if (adec->mBase->mFlags & DTF_GLOBAL)
AnalyzeGlobalVariable(adec->mBase); AnalyzeGlobalVariable(adec->mBase);
else
adec->mBase->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS; adec->mBase->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
} }
else if (adec->mType == DT_LABEL) else if (adec->mType == DT_LABEL)
@ -445,7 +471,6 @@ void GlobalOptimizer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
{ {
if (adec->mFlags & DTF_GLOBAL) if (adec->mFlags & DTF_GLOBAL)
AnalyzeGlobalVariable(adec); AnalyzeGlobalVariable(adec);
else
adec->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS; adec->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
} }
else if (adec->mType == DT_ARGUMENT) else if (adec->mType == DT_ARGUMENT)
@ -611,13 +636,11 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
AnalyzeGlobalVariable(exp->mDecValue); AnalyzeGlobalVariable(exp->mDecValue);
} }
else
{
if (flags & ANAFL_RHS) if (flags & ANAFL_RHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_USED; exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
if (flags & ANAFL_LHS) if (flags & ANAFL_LHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS; exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
}
if (exp->mDecValue->mType == DT_ARGUMENT) if (exp->mDecValue->mType == DT_ARGUMENT)
{ {
exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD; exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD;

View File

@ -39,5 +39,6 @@ protected:
bool ReplaceParamConst(Expression* exp, Declaration* param); bool ReplaceParamConst(Expression* exp, Declaration* param);
void PropagateCommas(Expression*& exp); void PropagateCommas(Expression*& exp);
void PropagateParamCommas(Expression *& fexp, Expression*& exp); void PropagateParamCommas(Expression *& fexp, Expression*& exp);
bool ReplaceGlobalConst(Expression* exp);
}; };

View File

@ -544,203 +544,6 @@ static bool CollidingMemType(InterType type1, InterType type2)
} }
bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const
{
if (op1.mMemory != op2.mMemory)
{
if (op1.mMemory == IM_INDIRECT)
{
if (op1.mRestricted)
return false;
else if (op2.mMemory == IM_GLOBAL)
{
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)
return false;
else if (op2.mMemory == IM_LOCAL)
{
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
return CollidingMemType(type1, type2);
}
else if (op2.mMemory == IM_INDIRECT)
{
if (op2.mRestricted)
return false;
else if (op1.mMemory == IM_GLOBAL)
{
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)
return false;
else if (op1.mMemory == IM_LOCAL)
{
if (op1.mMemoryBase == IM_LOCAL)
return op1.mVarIndex == op2.mVarIndex;
else
return mProc->mLocalVars[op1.mVarIndex]->mAliased && CollidingMemType(type1, type2);
}
else
return CollidingMemType(type1, type2);
}
else
return false;
}
switch (op1.mMemory)
{
case IM_LOCAL:
case IM_FPARAM:
case IM_PARAM:
return op1.mVarIndex == op2.mVarIndex && op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize;
case IM_ABSOLUTE:
return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize;
case IM_GLOBAL:
if (op1.mLinkerObject == op2.mLinkerObject)
return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize;
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 if (op1.mLinkerObject && op2.mLinkerObject && op1.mLinkerObject != op2.mLinkerObject)
return false;
else if (op1.mRestricted && op2.mRestricted && op1.mRestricted != op2.mRestricted)
return false;
else
return CollidingMemType(type1, type2);
default:
return false;
}
}
bool InterCodeBasicBlock::CollidingMem(const InterOperand& op, InterType type, const InterInstruction* ins) const
{
if (ins->mCode == IC_LOAD)
return CollidingMem(op, type, ins->mSrc[0], ins->mDst.mType);
else if (ins->mCode == IC_STORE)
return CollidingMem(op, type, ins->mSrc[1], ins->mSrc[0].mType);
else if (ins->mCode == IC_FILL)
return CollidingMem(op, type, ins->mSrc[1], IT_NONE);
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
return CollidingMem(op, type, ins->mSrc[0], IT_NONE) || CollidingMem(op, type, ins->mSrc[1], IT_NONE);
else
return false;
}
bool InterCodeBasicBlock::CollidingMem(const InterInstruction* ins1, const InterInstruction* ins2) const
{
if (ins1->mCode == IC_LOAD)
return CollidingMem(ins1->mSrc[0], ins1->mDst.mType, ins2);
else if (ins1->mCode == IC_STORE)
return CollidingMem(ins1->mSrc[1], ins1->mSrc[0].mType, ins2);
else if (ins1->mCode == IC_FILL)
return CollidingMem(ins1->mSrc[1], IT_NONE, ins2);
else if (ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)
return CollidingMem(ins1->mSrc[0], IT_NONE, ins2) || CollidingMem(ins1->mSrc[1], IT_NONE, ins2);
else
return false;
}
bool InterCodeBasicBlock::DestroyingMem(const InterInstruction* lins, const InterInstruction* sins) const
{
if (sins->mCode == IC_LOAD)
return false;
else if (sins->mCode == IC_STORE)
return CollidingMem(sins->mSrc[1], sins->mSrc[0].mType, lins);
else if (sins->mCode == IC_FILL)
return CollidingMem(sins->mSrc[1], IT_NONE, lins);
else if (sins->mCode == IC_COPY || sins->mCode == IC_STRCPY)
return CollidingMem(sins->mSrc[1], IT_NONE, lins);
else if (sins->mCode == IC_CALL || sins->mCode == IC_CALL_NATIVE)
{
if (sins->mSrc[0].mTemp < 0 && sins->mSrc[0].mLinkerObject)
{
InterCodeProcedure* proc = sins->mSrc[0].mLinkerObject->mProc;
if (proc)
{
int opmask = 0;
if (lins->mCode == IC_LOAD)
opmask = 1;
else if (lins->mCode == IC_STORE)
opmask = 2;
else if (lins->mCode == IC_FILL)
opmask = 2;
else if (lins->mCode == IC_COPY)
opmask = 3;
for (int k = 0; k < lins->mNumOperands; k++)
{
if ((1 << k) & opmask)
{
const InterOperand& op(lins->mSrc[k]);
if (op.mTemp >= 0)
{
if (proc->mStoresIndirect)
return true;
}
else if (op.mMemory == IM_FFRAME || op.mMemory == IM_FRAME)
return true;
else if (op.mMemory == IM_GLOBAL)
{
if (proc->ModifiesGlobal(op.mVarIndex))
return true;
}
else if (op.mMemory == IM_LOCAL && !mProc->mLocalVars[op.mVarIndex]->mAliased)
;
else if ((op.mMemory == IM_PARAM || op.mMemory == IM_FPARAM) && !mProc->mParamVars[op.mVarIndex]->mAliased)
;
else
return true;
}
}
return false;
}
}
return true;
}
else
return false;
}
bool InterCodeBasicBlock::DestroyingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const
{
for (int i = from; i < to; i++)
{
InterInstruction* ins = block->mInstructions[i];
if (DestroyingMem(lins, ins))
return true;
}
return false;
}
static bool SameMem(const InterOperand& op1, const InterOperand& op2) static bool SameMem(const InterOperand& op1, const InterOperand& op2)
{ {
if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst) if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst)
@ -908,6 +711,252 @@ static void SwapInstructions(InterInstruction* it, InterInstruction* ib)
} }
} }
bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const
{
if (op1.mMemory != op2.mMemory)
{
if (op1.mMemory == IM_INDIRECT)
{
if (op1.mRestricted)
return false;
else if (op2.mMemory == IM_GLOBAL)
{
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)
return false;
else if (op2.mMemory == IM_LOCAL)
{
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
return CollidingMemType(type1, type2);
}
else if (op2.mMemory == IM_INDIRECT)
{
if (op2.mRestricted)
return false;
else if (op1.mMemory == IM_GLOBAL)
{
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)
return false;
else if (op1.mMemory == IM_LOCAL)
{
if (op1.mMemoryBase == IM_LOCAL)
return op1.mVarIndex == op2.mVarIndex;
else
return mProc->mLocalVars[op1.mVarIndex]->mAliased && CollidingMemType(type1, type2);
}
else
return CollidingMemType(type1, type2);
}
else
return false;
}
switch (op1.mMemory)
{
case IM_LOCAL:
case IM_FPARAM:
case IM_PARAM:
return op1.mVarIndex == op2.mVarIndex && op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize;
case IM_ABSOLUTE:
return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize;
case IM_GLOBAL:
if (op1.mLinkerObject == op2.mLinkerObject)
return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize;
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 if (op1.mLinkerObject && op2.mLinkerObject && op1.mLinkerObject != op2.mLinkerObject)
return false;
else if (op1.mRestricted && op2.mRestricted && op1.mRestricted != op2.mRestricted)
return false;
else
return CollidingMemType(type1, type2);
default:
return false;
}
}
bool InterCodeBasicBlock::CollidingMem(const InterOperand& op, InterType type, const InterInstruction* ins) const
{
if (ins->mCode == IC_LOAD)
return CollidingMem(op, type, ins->mSrc[0], ins->mDst.mType);
else if (ins->mCode == IC_STORE)
return CollidingMem(op, type, ins->mSrc[1], ins->mSrc[0].mType);
else if (ins->mCode == IC_FILL)
return CollidingMem(op, type, ins->mSrc[1], IT_NONE);
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
return CollidingMem(op, type, ins->mSrc[0], IT_NONE) || CollidingMem(op, type, ins->mSrc[1], IT_NONE);
else
return false;
}
bool InterCodeBasicBlock::CollidingMem(const InterInstruction* ins1, const InterInstruction* ins2) const
{
if (ins1->mCode == IC_LOAD)
return CollidingMem(ins1->mSrc[0], ins1->mDst.mType, ins2);
else if (ins1->mCode == IC_STORE)
return CollidingMem(ins1->mSrc[1], ins1->mSrc[0].mType, ins2);
else if (ins1->mCode == IC_FILL)
return CollidingMem(ins1->mSrc[1], IT_NONE, ins2);
else if (ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)
return CollidingMem(ins1->mSrc[0], IT_NONE, ins2) || CollidingMem(ins1->mSrc[1], IT_NONE, ins2);
else
return false;
}
bool InterCodeBasicBlock::AliasingMem(const InterInstruction* ins1, const InterInstruction* ins2) const
{
if (ins1->mCode == IC_LOAD)
return AliasingMem(ins1->mSrc[0], ins1->mDst.mType, ins2);
else if (ins1->mCode == IC_STORE)
return AliasingMem(ins1->mSrc[1], ins1->mSrc[0].mType, ins2);
else if (ins1->mCode == IC_FILL)
return AliasingMem(ins1->mSrc[1], IT_NONE, ins2);
else if (ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)
return AliasingMem(ins1->mSrc[0], IT_NONE, ins2) || AliasingMem(ins1->mSrc[1], IT_NONE, ins2);
else
return false;
}
bool InterCodeBasicBlock::AliasingMem(const InterOperand& op, InterType type, const InterInstruction* ins) const
{
if (ins->mCode == IC_LOAD)
return AliasingMem(op, type, ins->mSrc[0], ins->mDst.mType);
else if (ins->mCode == IC_STORE)
return AliasingMem(op, type, ins->mSrc[1], ins->mSrc[0].mType);
else if (ins->mCode == IC_FILL)
return AliasingMem(op, type, ins->mSrc[1], IT_NONE);
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
return AliasingMem(op, type, ins->mSrc[0], IT_NONE) || AliasingMem(op, type, ins->mSrc[1], IT_NONE);
else
return false;
}
bool InterCodeBasicBlock::AliasingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const
{
if (type1 != IT_NONE && type1 == type2 && SameMem(op1, op2))
return false;
else
return CollidingMem(op1, type1, op2, type2);
}
bool InterCodeBasicBlock::AliasingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const
{
if (to > block->mInstructions.Size())
to = block->mInstructions.Size();
for (int i = from; i < to; i++)
if (AliasingMem(block->mInstructions[i], lins))
return true;
return false;
}
bool InterCodeBasicBlock::DestroyingMem(const InterInstruction* lins, const InterInstruction* sins) const
{
if (sins->mCode == IC_LOAD)
return false;
else if (sins->mCode == IC_STORE)
return CollidingMem(sins->mSrc[1], sins->mSrc[0].mType, lins);
else if (sins->mCode == IC_FILL)
return CollidingMem(sins->mSrc[1], IT_NONE, lins);
else if (sins->mCode == IC_COPY || sins->mCode == IC_STRCPY)
return CollidingMem(sins->mSrc[1], IT_NONE, lins);
else if (sins->mCode == IC_CALL || sins->mCode == IC_CALL_NATIVE)
{
if (sins->mSrc[0].mTemp < 0 && sins->mSrc[0].mLinkerObject)
{
InterCodeProcedure* proc = sins->mSrc[0].mLinkerObject->mProc;
if (proc)
{
int opmask = 0;
if (lins->mCode == IC_LOAD)
opmask = 1;
else if (lins->mCode == IC_STORE)
opmask = 2;
else if (lins->mCode == IC_FILL)
opmask = 2;
else if (lins->mCode == IC_COPY)
opmask = 3;
for (int k = 0; k < lins->mNumOperands; k++)
{
if ((1 << k) & opmask)
{
const InterOperand& op(lins->mSrc[k]);
if (op.mTemp >= 0)
{
if (proc->mStoresIndirect)
return true;
}
else if (op.mMemory == IM_FFRAME || op.mMemory == IM_FRAME)
return true;
else if (op.mMemory == IM_GLOBAL)
{
if (proc->ModifiesGlobal(op.mVarIndex))
return true;
}
else if (op.mMemory == IM_LOCAL && !mProc->mLocalVars[op.mVarIndex]->mAliased)
;
else if ((op.mMemory == IM_PARAM || op.mMemory == IM_FPARAM) && !mProc->mParamVars[op.mVarIndex]->mAliased)
;
else
return true;
}
}
return false;
}
}
return true;
}
else
return false;
}
bool InterCodeBasicBlock::DestroyingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const
{
for (int i = from; i < to; i++)
{
InterInstruction* ins = block->mInstructions[i];
if (DestroyingMem(lins, ins))
return true;
}
return false;
}
bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const
{ {
// Cannot swap branches // Cannot swap branches
@ -14556,6 +14605,8 @@ bool InterCodeBasicBlock::CollidingMem(InterCodeBasicBlock* block, InterInstruct
return false; return false;
} }
bool InterCodeBasicBlock::InvalidatedBy(const InterInstruction* ins, const InterInstruction* by) const bool InterCodeBasicBlock::InvalidatedBy(const InterInstruction* ins, const InterInstruction* by) const
{ {
if (by->mDst.mTemp >= 0 && ins->ReferencesTemp(by->mDst.mTemp)) if (by->mDst.mTemp >= 0 && ins->ReferencesTemp(by->mDst.mTemp))
@ -17815,7 +17866,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
InterInstruction* sins = mInstructions[j]; InterInstruction* sins = mInstructions[j];
// Does a full store // Does a full store
if (SameMem(ins->mSrc[0], sins->mSrc[1])) if (SameMem(ins->mSrc[0], sins->mSrc[1]) && !AliasingMem(this, ins, 0, mInstructions.Size()))
{ {
if (sins->mSrc[0].mTemp >= 0) if (sins->mSrc[0].mTemp >= 0)
{ {
@ -17845,7 +17896,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
// Propagate all loads to move temps // Propagate all loads to move temps
for (int t = j + 1; t < mInstructions.Size(); t++) for (int t = i + 1; t < mInstructions.Size(); t++)
{ {
InterInstruction* ti = mInstructions[t]; InterInstruction* ti = mInstructions[t];
if (ti->mCode == IC_LOAD && SameMem(ti->mSrc[0], ins->mSrc[0])) if (ti->mCode == IC_LOAD && SameMem(ti->mSrc[0], ins->mSrc[0]))

View File

@ -556,14 +556,23 @@ public:
bool IsTempModifiedOnPath(int temp, int at) const; bool IsTempModifiedOnPath(int temp, int at) const;
bool IsTempReferencedOnPath(int temp, int at) const; bool IsTempReferencedOnPath(int temp, int at) const;
// The memory referenced by lins may be writtne by sind
bool DestroyingMem(const InterInstruction* lins, const InterInstruction* sins) const; bool DestroyingMem(const InterInstruction* lins, const InterInstruction* sins) const;
bool DestroyingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const; bool DestroyingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const;
// The two memory operations may have overlapping reads/writs and writes
bool CollidingMem(const InterInstruction* ins1, const InterInstruction* ins2) const; bool CollidingMem(const InterInstruction* ins1, const InterInstruction* ins2) const;
bool CollidingMem(const InterOperand& op, InterType type, const InterInstruction* ins) const; bool CollidingMem(const InterOperand& op, InterType type, const InterInstruction* ins) const;
bool CollidingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const; bool CollidingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const;
bool CollidingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const; bool CollidingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const;
bool InvalidatedBy(const InterInstruction* ins, const InterInstruction* by) const; bool InvalidatedBy(const InterInstruction* ins, const InterInstruction* by) const;
// The two memory regions may be aliased but not just the same
bool AliasingMem(const InterInstruction* ins1, const InterInstruction* ins2) const;
bool AliasingMem(const InterOperand& op, InterType type, const InterInstruction* ins) const;
bool AliasingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const;
bool AliasingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const;
bool PushSinglePathResultInstructions(void); bool PushSinglePathResultInstructions(void);
bool CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const; bool CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const;