Fix loop wrap around aliasing
This commit is contained in:
parent
ff4a0802ea
commit
92b72b19ec
|
@ -259,6 +259,30 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
|
|||
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 changed = false;
|
||||
|
@ -282,6 +306,9 @@ bool GlobalOptimizer::Optimize(void)
|
|||
if (CheckConstReturns(func->mValue))
|
||||
changed = true;
|
||||
|
||||
if (ReplaceGlobalConst(func->mValue))
|
||||
changed = true;
|
||||
|
||||
if (func->mOptFlags & OPTF_MULTI_CALL)
|
||||
{
|
||||
Declaration* pdata = ftype->mParams;
|
||||
|
@ -434,7 +461,6 @@ void GlobalOptimizer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
|
|||
{
|
||||
if (adec->mBase->mFlags & DTF_GLOBAL)
|
||||
AnalyzeGlobalVariable(adec->mBase);
|
||||
else
|
||||
adec->mBase->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
|
||||
}
|
||||
else if (adec->mType == DT_LABEL)
|
||||
|
@ -445,7 +471,6 @@ void GlobalOptimizer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
|
|||
{
|
||||
if (adec->mFlags & DTF_GLOBAL)
|
||||
AnalyzeGlobalVariable(adec);
|
||||
else
|
||||
adec->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
|
||||
}
|
||||
else if (adec->mType == DT_ARGUMENT)
|
||||
|
@ -611,13 +636,11 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
|
||||
AnalyzeGlobalVariable(exp->mDecValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & ANAFL_RHS)
|
||||
exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
|
||||
if (flags & ANAFL_LHS)
|
||||
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
|
||||
}
|
||||
|
||||
if (exp->mDecValue->mType == DT_ARGUMENT)
|
||||
{
|
||||
exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD;
|
||||
|
|
|
@ -39,5 +39,6 @@ protected:
|
|||
bool ReplaceParamConst(Expression* exp, Declaration* param);
|
||||
void PropagateCommas(Expression*& exp);
|
||||
void PropagateParamCommas(Expression *& fexp, Expression*& exp);
|
||||
bool ReplaceGlobalConst(Expression* exp);
|
||||
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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
|
||||
{
|
||||
// Cannot swap branches
|
||||
|
@ -14556,6 +14605,8 @@ bool InterCodeBasicBlock::CollidingMem(InterCodeBasicBlock* block, InterInstruct
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool InterCodeBasicBlock::InvalidatedBy(const InterInstruction* ins, const InterInstruction* by) const
|
||||
{
|
||||
if (by->mDst.mTemp >= 0 && ins->ReferencesTemp(by->mDst.mTemp))
|
||||
|
@ -17815,7 +17866,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
|||
InterInstruction* sins = mInstructions[j];
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
@ -17845,7 +17896,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
|||
|
||||
// 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];
|
||||
if (ti->mCode == IC_LOAD && SameMem(ti->mSrc[0], ins->mSrc[0]))
|
||||
|
|
|
@ -556,14 +556,23 @@ public:
|
|||
bool IsTempModifiedOnPath(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(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 InterOperand& op, InterType type, const InterInstruction* ins) 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 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 CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const;
|
||||
|
|
Loading…
Reference in New Issue