Basic block struct copy propagation
This commit is contained in:
parent
a65c802485
commit
a4fa4cd482
|
@ -352,6 +352,135 @@ void ValueSet::FlushCallAliases(const GrowingInstructionPtrArray& tvalue, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool CollidingMem(const InterOperand& op1, const InterOperand& op2)
|
||||||
|
{
|
||||||
|
if (op1.mMemory != op2.mMemory)
|
||||||
|
return op1.mMemory == IM_INDIRECT || op2.mMemory == IM_INDIRECT;
|
||||||
|
|
||||||
|
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
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CollidingMem(const InterOperand& op, const InterInstruction* ins)
|
||||||
|
{
|
||||||
|
if (ins->mCode == IC_LOAD)
|
||||||
|
return CollidingMem(op, ins->mSrc[0]);
|
||||||
|
else if (ins->mCode == IC_STORE)
|
||||||
|
return CollidingMem(op, ins->mSrc[1]);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SameMem(const InterOperand& op1, const InterOperand& op2)
|
||||||
|
{
|
||||||
|
if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (op1.mMemory)
|
||||||
|
{
|
||||||
|
case IM_LOCAL:
|
||||||
|
case IM_FPARAM:
|
||||||
|
case IM_PARAM:
|
||||||
|
return op1.mVarIndex == op2.mVarIndex;
|
||||||
|
case IM_ABSOLUTE:
|
||||||
|
return true;
|
||||||
|
case IM_GLOBAL:
|
||||||
|
return op1.mLinkerObject == op2.mLinkerObject;
|
||||||
|
case IM_INDIRECT:
|
||||||
|
return op1.mTemp == op2.mTemp;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns true if op2 is part of op1
|
||||||
|
static bool SameMemSegment(const InterOperand& op1, const InterOperand& op2)
|
||||||
|
{
|
||||||
|
if (op1.mMemory != op2.mMemory || op1.mIntConst > op2.mIntConst || op1.mIntConst + op1.mOperandSize < op2.mIntConst + op2.mOperandSize)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (op1.mMemory)
|
||||||
|
{
|
||||||
|
case IM_LOCAL:
|
||||||
|
case IM_FPARAM:
|
||||||
|
case IM_PARAM:
|
||||||
|
return op1.mVarIndex == op2.mVarIndex;
|
||||||
|
case IM_ABSOLUTE:
|
||||||
|
return true;
|
||||||
|
case IM_GLOBAL:
|
||||||
|
return op1.mLinkerObject == op2.mLinkerObject;
|
||||||
|
case IM_INDIRECT:
|
||||||
|
return op1.mTemp == op2.mTemp;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SameMemAndSize(const InterOperand& op1, const InterOperand& op2)
|
||||||
|
{
|
||||||
|
if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst || op1.mOperandSize != op2.mOperandSize)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (op1.mMemory)
|
||||||
|
{
|
||||||
|
case IM_LOCAL:
|
||||||
|
case IM_FPARAM:
|
||||||
|
case IM_PARAM:
|
||||||
|
return op1.mVarIndex == op2.mVarIndex;
|
||||||
|
case IM_ABSOLUTE:
|
||||||
|
return true;
|
||||||
|
case IM_GLOBAL:
|
||||||
|
return op1.mLinkerObject == op2.mLinkerObject;
|
||||||
|
case IM_INDIRECT:
|
||||||
|
return op1.mTemp == op2.mTemp;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SameMem(const InterOperand& op, const InterInstruction* ins)
|
||||||
|
{
|
||||||
|
if (ins->mCode == IC_LOAD)
|
||||||
|
return SameMem(op, ins->mSrc[0]);
|
||||||
|
else if (ins->mCode == IC_STORE)
|
||||||
|
return SameMem(op, ins->mSrc[1]);
|
||||||
|
else
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int64 ConstantFolding(InterOperator oper, InterType type, int64 val1, int64 val2 = 0)
|
static int64 ConstantFolding(InterOperator oper, InterType type, int64 val1, int64 val2 = 0)
|
||||||
{
|
{
|
||||||
switch (oper)
|
switch (oper)
|
||||||
|
@ -4002,6 +4131,102 @@ void InterCodeBasicBlock::CollectConstTemps(GrowingInstructionPtrArray& ctemps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
GrowingInstructionPtrArray ltemps(nullptr);
|
||||||
|
|
||||||
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
|
{
|
||||||
|
InterInstruction* ins(mInstructions[i]);
|
||||||
|
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (ins->mDst.mTemp >= 0)
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
for (int k = 0; k < ltemps.Size(); k++)
|
||||||
|
{
|
||||||
|
if (ltemps[k]->mSrc[0].mTemp != ins->mDst.mTemp && ltemps[k]->mSrc[1].mTemp != ins->mDst.mTemp)
|
||||||
|
{
|
||||||
|
ltemps[j++] = ltemps[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ltemps.SetSize(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ins->mCode)
|
||||||
|
{
|
||||||
|
case IC_LOAD:
|
||||||
|
for (int k = 0; k < ltemps.Size(); k++)
|
||||||
|
{
|
||||||
|
if (SameMemSegment(ltemps[k]->mSrc[1], ins->mSrc[0]))
|
||||||
|
{
|
||||||
|
ins->mSrc[0].mMemory = ltemps[k]->mSrc[0].mMemory;
|
||||||
|
ins->mSrc[0].mTemp = ltemps[k]->mSrc[0].mTemp;
|
||||||
|
ins->mSrc[0].mVarIndex = ltemps[k]->mSrc[0].mVarIndex;
|
||||||
|
ins->mSrc[0].mIntConst += ltemps[k]->mSrc[0].mIntConst;
|
||||||
|
ins->mSrc[0].mLinkerObject = ltemps[k]->mSrc[0].mLinkerObject;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IC_STORE:
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
for(int k=0; k<ltemps.Size(); k++)
|
||||||
|
{
|
||||||
|
if (!CollidingMem(ltemps[k]->mSrc[0], ins->mSrc[1]) &&
|
||||||
|
!CollidingMem(ltemps[k]->mSrc[1], ins->mSrc[1]))
|
||||||
|
{
|
||||||
|
ltemps[j++] = ltemps[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ltemps.SetSize(j);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IC_COPY:
|
||||||
|
for (int k = 0; k < ltemps.Size(); k++)
|
||||||
|
{
|
||||||
|
if (SameMemAndSize(ltemps[k]->mSrc[1], ins->mSrc[0]))
|
||||||
|
{
|
||||||
|
ins->mSrc[0] = ltemps[k]->mSrc[0];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
for (int k = 0; k < ltemps.Size(); k++)
|
||||||
|
{
|
||||||
|
if (!CollidingMem(ltemps[k]->mSrc[0], ins->mSrc[1]) &&
|
||||||
|
!CollidingMem(ltemps[k]->mSrc[1], ins->mSrc[1]))
|
||||||
|
{
|
||||||
|
ltemps[j++] = ltemps[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ltemps.SetSize(j);
|
||||||
|
ltemps.Push(ins);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->PropagateVariableCopy(ltemps))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->PropagateVariableCopy(ltemps))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool InterCodeBasicBlock::PropagateConstTemps(const GrowingInstructionPtrArray& ctemps)
|
bool InterCodeBasicBlock::PropagateConstTemps(const GrowingInstructionPtrArray& ctemps)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -6051,89 +6276,6 @@ static int Find(GrowingIntArray& table, int i)
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CollidingMem(const InterOperand& op1, const InterOperand& op2)
|
|
||||||
{
|
|
||||||
if (op1.mMemory != op2.mMemory)
|
|
||||||
return op1.mMemory == IM_INDIRECT || op2.mMemory == IM_INDIRECT;
|
|
||||||
|
|
||||||
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
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CollidingMem(const InterOperand& op, const InterInstruction * ins)
|
|
||||||
{
|
|
||||||
if (ins->mCode == IC_LOAD)
|
|
||||||
return CollidingMem(op, ins->mSrc[0]);
|
|
||||||
else if (ins->mCode == IC_STORE)
|
|
||||||
return CollidingMem(op, ins->mSrc[1]);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool SameMem(const InterOperand& op1, const InterOperand& op2)
|
|
||||||
{
|
|
||||||
if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (op1.mMemory)
|
|
||||||
{
|
|
||||||
case IM_LOCAL:
|
|
||||||
case IM_FPARAM:
|
|
||||||
case IM_PARAM:
|
|
||||||
return op1.mVarIndex == op2.mVarIndex;
|
|
||||||
case IM_ABSOLUTE:
|
|
||||||
return true;
|
|
||||||
case IM_GLOBAL:
|
|
||||||
return op1.mLinkerObject == op2.mLinkerObject;
|
|
||||||
case IM_INDIRECT:
|
|
||||||
return op1.mTemp == op2.mTemp;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool SameMem(const InterOperand& op, const InterInstruction* ins)
|
|
||||||
{
|
|
||||||
if (ins->mCode == IC_LOAD)
|
|
||||||
return SameMem(op, ins->mSrc[0]);
|
|
||||||
else if (ins->mCode == IC_STORE)
|
|
||||||
return SameMem(op, ins->mSrc[1]);
|
|
||||||
else
|
|
||||||
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)
|
void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
|
@ -9062,6 +9204,69 @@ void InterCodeProcedure::RemoveUnusedInstructions(void)
|
||||||
} while (mEntryBlock->RemoveUnusedResultInstructions());
|
} while (mEntryBlock->RemoveUnusedResultInstructions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeProcedure::RemoveUnusedStoreInstructions(InterMemory paramMemory)
|
||||||
|
{
|
||||||
|
if (mLocalVars.Size() > 0 || mParamVars.Size() > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mLocalVars.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mLocalAliasedSet[i])
|
||||||
|
mLocalVars[i]->mAliased = true;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < mParamVars.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mParamAliasedSet[i])
|
||||||
|
mParamVars[i]->mAliased = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Now remove unused stores
|
||||||
|
//
|
||||||
|
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->BuildLocalVariableSets(mLocalVars, mParamVars, paramMemory);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->BuildGlobalProvidedVariableSet(mLocalVars, NumberSet(mLocalVars.Size()), mParamVars, NumberSet(mParamVars.Size()), paramMemory);
|
||||||
|
|
||||||
|
NumberSet totalRequired2(mLocalVars.Size());
|
||||||
|
NumberSet totalRequiredParams(mParamVars.Size());
|
||||||
|
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->BuildGlobalRequiredVariableSet(mLocalVars, totalRequired2, mParamVars, totalRequiredParams, paramMemory));
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->RemoveUnusedStoreInstructions(mLocalVars, mParamVars, paramMemory));
|
||||||
|
|
||||||
|
DisassembleDebug("removed unused local stores");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unused global stores
|
||||||
|
|
||||||
|
if (mModule->mGlobalVars.Size())
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->BuildStaticVariableSet(mModule->mGlobalVars);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->BuildGlobalProvidedStaticVariableSet(mModule->mGlobalVars, NumberSet(mModule->mGlobalVars.Size()));
|
||||||
|
|
||||||
|
NumberSet totalRequired2(mModule->mGlobalVars.Size());
|
||||||
|
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->BuildGlobalRequiredStaticVariableSet(mModule->mGlobalVars, totalRequired2));
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->RemoveUnusedStaticStoreInstructions(mModule->mGlobalVars));
|
||||||
|
|
||||||
|
DisassembleDebug("removed unused static stores");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::Close(void)
|
void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
int i, j, k, start;
|
int i, j, k, start;
|
||||||
|
@ -9210,67 +9415,7 @@ void InterCodeProcedure::Close(void)
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->CollectVariables(mModule->mGlobalVars, mLocalVars, mParamVars, paramMemory);
|
mEntryBlock->CollectVariables(mModule->mGlobalVars, mLocalVars, mParamVars, paramMemory);
|
||||||
|
|
||||||
|
RemoveUnusedStoreInstructions(paramMemory);
|
||||||
if (mLocalVars.Size() > 0 || mParamVars.Size() > 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < mLocalVars.Size(); i++)
|
|
||||||
{
|
|
||||||
if (mLocalAliasedSet[i])
|
|
||||||
mLocalVars[i]->mAliased = true;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < mParamVars.Size(); i++)
|
|
||||||
{
|
|
||||||
if (mParamAliasedSet[i])
|
|
||||||
mParamVars[i]->mAliased = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Now remove unused stores
|
|
||||||
//
|
|
||||||
|
|
||||||
do {
|
|
||||||
ResetVisited();
|
|
||||||
mEntryBlock->BuildLocalVariableSets(mLocalVars, mParamVars, paramMemory);
|
|
||||||
|
|
||||||
ResetVisited();
|
|
||||||
mEntryBlock->BuildGlobalProvidedVariableSet(mLocalVars, NumberSet(mLocalVars.Size()), mParamVars, NumberSet(mParamVars.Size()), paramMemory);
|
|
||||||
|
|
||||||
NumberSet totalRequired2(mLocalVars.Size());
|
|
||||||
NumberSet totalRequiredParams(mParamVars.Size());
|
|
||||||
|
|
||||||
do {
|
|
||||||
ResetVisited();
|
|
||||||
} while (mEntryBlock->BuildGlobalRequiredVariableSet(mLocalVars, totalRequired2, mParamVars, totalRequiredParams, paramMemory));
|
|
||||||
|
|
||||||
ResetVisited();
|
|
||||||
} while (mEntryBlock->RemoveUnusedStoreInstructions(mLocalVars, mParamVars, paramMemory));
|
|
||||||
|
|
||||||
DisassembleDebug("removed unused local stores");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove unused global stores
|
|
||||||
|
|
||||||
if (mModule->mGlobalVars.Size())
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
ResetVisited();
|
|
||||||
mEntryBlock->BuildStaticVariableSet(mModule->mGlobalVars);
|
|
||||||
|
|
||||||
ResetVisited();
|
|
||||||
mEntryBlock->BuildGlobalProvidedStaticVariableSet(mModule->mGlobalVars, NumberSet(mModule->mGlobalVars.Size()));
|
|
||||||
|
|
||||||
NumberSet totalRequired2(mModule->mGlobalVars.Size());
|
|
||||||
|
|
||||||
do {
|
|
||||||
ResetVisited();
|
|
||||||
} while (mEntryBlock->BuildGlobalRequiredStaticVariableSet(mModule->mGlobalVars, totalRequired2));
|
|
||||||
|
|
||||||
ResetVisited();
|
|
||||||
} while (mEntryBlock->RemoveUnusedStaticStoreInstructions(mModule->mGlobalVars));
|
|
||||||
|
|
||||||
DisassembleDebug("removed unused static stores");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (int j = 0; j < 2; j++)
|
for (int j = 0; j < 2; j++)
|
||||||
{
|
{
|
||||||
|
@ -9437,6 +9582,17 @@ void InterCodeProcedure::Close(void)
|
||||||
mEntryBlock->CompactInstructions();
|
mEntryBlock->CompactInstructions();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
GrowingInstructionPtrArray cipa(nullptr);
|
||||||
|
ResetVisited();
|
||||||
|
changed = mEntryBlock->PropagateVariableCopy(cipa);
|
||||||
|
|
||||||
|
RemoveUnusedStoreInstructions(paramMemory);
|
||||||
|
} while (changed);
|
||||||
|
|
||||||
|
DisassembleDebug("Copy forwarding");
|
||||||
|
|
||||||
|
|
||||||
GrowingInstructionPtrArray gipa(nullptr);
|
GrowingInstructionPtrArray gipa(nullptr);
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
|
|
|
@ -374,6 +374,8 @@ public:
|
||||||
void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
|
void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
|
||||||
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
|
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
|
||||||
|
|
||||||
|
bool PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps);
|
||||||
|
|
||||||
void BuildLocalTempSets(int num);
|
void BuildLocalTempSets(int num);
|
||||||
void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps);
|
void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps);
|
||||||
bool BuildGlobalRequiredTempSet(NumberSet& fromRequiredTemps);
|
bool BuildGlobalRequiredTempSet(NumberSet& fromRequiredTemps);
|
||||||
|
@ -525,6 +527,7 @@ protected:
|
||||||
bool PropagateNonLocalUsedTemps(void);
|
bool PropagateNonLocalUsedTemps(void);
|
||||||
void BuildLoopPrefix(void);
|
void BuildLoopPrefix(void);
|
||||||
void SingleAssignmentForwarding(void);
|
void SingleAssignmentForwarding(void);
|
||||||
|
void RemoveUnusedStoreInstructions(InterMemory paramMemory);
|
||||||
|
|
||||||
void MergeBasicBlocks(void);
|
void MergeBasicBlocks(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue