Add early dead code elimination to speed up template compilation
This commit is contained in:
parent
62ab925e01
commit
6af50f5eae
|
@ -580,13 +580,16 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
if (i >= 64)
|
||||
i = 0xff;
|
||||
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
|
||||
dec->mBase = TheUnsignedCharTypeDeclaration;
|
||||
dec->mInteger = i;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
if (i < 64 || (mLeft->mDecValue->mFlags & DTF_DEFINED))
|
||||
{
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
|
||||
dec->mBase = TheSignedIntTypeDeclaration;
|
||||
dec->mInteger = i;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
|
@ -1584,6 +1584,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPEQ:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst == op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mIntConst == op2.mIntConst && op1.mLinkerObject == op2.mLinkerObject;
|
||||
else
|
||||
dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) == ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1591,6 +1593,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPNE:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst != op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory != op2.mMemory || op1.mVarIndex != op2.mVarIndex || op1.mIntConst != op2.mIntConst || op1.mLinkerObject != op2.mLinkerObject;
|
||||
else
|
||||
dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) != ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1598,6 +1602,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPGES:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst >= op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst >= op2.mIntConst;
|
||||
else
|
||||
dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) >= ToTypedSigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1605,6 +1611,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPGEU:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst >= op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst >= op2.mIntConst;
|
||||
else
|
||||
dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) >= ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1612,6 +1620,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPLES:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst <= op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst <= op2.mIntConst;
|
||||
else
|
||||
dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) <= ToTypedSigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1619,6 +1629,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPLEU:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst <= op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst <= op2.mIntConst;
|
||||
else
|
||||
dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) <= ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1626,6 +1638,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPGS:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst > op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst > op2.mIntConst;
|
||||
else
|
||||
dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) > ToTypedSigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1633,6 +1647,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPGU:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst > op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst > op2.mIntConst;
|
||||
else
|
||||
dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) > ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1640,6 +1656,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPLS:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst < op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst < op2.mIntConst;
|
||||
else
|
||||
dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) < ToTypedSigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1647,6 +1665,8 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
case IA_CMPLU:
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mIntConst = op1.mFloatConst < op2.mFloatConst ? 1 : 0;
|
||||
else if (op1.mType == IT_POINTER)
|
||||
dop.mIntConst = op1.mMemory == op2.mMemory && op1.mVarIndex == op2.mVarIndex && op1.mLinkerObject == op2.mLinkerObject && op1.mIntConst < op2.mIntConst;
|
||||
else
|
||||
dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) < ToTypedUnsigned(op2.mIntConst, op2.mType) ? 1 : 0;
|
||||
dop.mType = IT_BOOL;
|
||||
|
@ -1715,6 +1735,38 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
else
|
||||
dop.mIntConst = -op1.mIntConst;
|
||||
break;
|
||||
case IA_ABS:
|
||||
dop.mType = op1.mType;
|
||||
if (op1.mType == IT_FLOAT)
|
||||
{
|
||||
if (op1.mFloatConst < 0)
|
||||
dop.mFloatConst = -op1.mFloatConst;
|
||||
else
|
||||
dop.mFloatConst = op1.mFloatConst;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (op1.mIntConst < 0)
|
||||
dop.mIntConst = -op1.mIntConst;
|
||||
else
|
||||
dop.mIntConst = op1.mIntConst;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case IA_FLOOR:
|
||||
dop.mType = op1.mType;
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mFloatConst = floor(op1.mFloatConst);
|
||||
else
|
||||
dop.mIntConst = op1.mIntConst;
|
||||
break;
|
||||
case IA_CEIL:
|
||||
dop.mType = op1.mType;
|
||||
if (op1.mType == IT_FLOAT)
|
||||
dop.mFloatConst = ceil(op1.mFloatConst);
|
||||
else
|
||||
dop.mIntConst = op1.mIntConst;
|
||||
break;
|
||||
case IA_NOT:
|
||||
dop.mType = op1.mType;
|
||||
switch (op1.mType)
|
||||
|
@ -7333,6 +7385,83 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray
|
|||
return changed;
|
||||
}
|
||||
|
||||
bool InterCodeBasicBlock::EarlyBranchElimination(const GrowingInstructionPtrArray& ctemps)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
int i;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
GrowingInstructionPtrArray temps(ctemps);
|
||||
if (mNumEntries > 1)
|
||||
temps.Clear();
|
||||
|
||||
int sz = mInstructions.Size();
|
||||
for (i = 0; i < sz; i++)
|
||||
{
|
||||
InterInstruction* ins = mInstructions[i];
|
||||
if (ins->mDst.mTemp >= 0)
|
||||
{
|
||||
if (ins->mCode == IC_UNARY_OPERATOR && temps[ins->mSrc[0].mTemp])
|
||||
{
|
||||
ins->mConst = OperandConstantFolding(ins->mOperator, temps[ins->mSrc[0].mTemp]->mConst, temps[ins->mSrc[0].mTemp]->mConst);
|
||||
ins->mCode = IC_CONSTANT;
|
||||
ins->mNumOperands = 0;
|
||||
ins->mSrc[0].mTemp = -1;
|
||||
}
|
||||
else if (ins->mCode == IC_BINARY_OPERATOR && temps[ins->mSrc[0].mTemp] && temps[ins->mSrc[1].mTemp])
|
||||
{
|
||||
ins->mConst = OperandConstantFolding(ins->mOperator, temps[ins->mSrc[1].mTemp]->mConst, temps[ins->mSrc[0].mTemp]->mConst);
|
||||
ins->mCode = IC_CONSTANT;
|
||||
ins->mNumOperands = 0;
|
||||
ins->mSrc[0].mTemp = -1;
|
||||
}
|
||||
else if (ins->mCode == IC_RELATIONAL_OPERATOR && temps[ins->mSrc[0].mTemp] && temps[ins->mSrc[1].mTemp])
|
||||
{
|
||||
ins->mConst = OperandConstantFolding(ins->mOperator, temps[ins->mSrc[1].mTemp]->mConst, temps[ins->mSrc[0].mTemp]->mConst);
|
||||
ins->mCode = IC_CONSTANT;
|
||||
ins->mNumOperands = 0;
|
||||
ins->mSrc[0].mTemp = -1;
|
||||
}
|
||||
|
||||
if (ins->mCode == IC_CONSTANT)
|
||||
temps[mInstructions[i]->mDst.mTemp] = ins;
|
||||
else
|
||||
temps[mInstructions[i]->mDst.mTemp] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (sz > 0 && mInstructions[sz - 1]->mCode == IC_BRANCH && temps[mInstructions[sz - 1]->mSrc[0].mTemp])
|
||||
{
|
||||
InterInstruction* cins = temps[mInstructions[sz - 1]->mSrc[0].mTemp];
|
||||
|
||||
if (cins->mConst.mType == IT_BOOL)
|
||||
{
|
||||
mInstructions[sz - 1]->mCode = IC_JUMP;
|
||||
if (cins->mConst.mIntConst)
|
||||
mFalseJump->mNumEntries--;
|
||||
else
|
||||
{
|
||||
mTrueJump->mNumEntries--;
|
||||
mTrueJump = mFalseJump;
|
||||
}
|
||||
mFalseJump = nullptr;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->EarlyBranchElimination(temps))
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->EarlyBranchElimination(temps))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool InterCodeBasicBlock::ForwardConstTemps(const GrowingInstructionPtrArray& ctemps)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -21674,6 +21803,15 @@ void InterCodeProcedure::RebuildIntegerRangeSet(void)
|
|||
DisassembleDebug("Estimated value range 2");
|
||||
}
|
||||
|
||||
void InterCodeProcedure::EarlyBranchElimination(void)
|
||||
{
|
||||
GrowingInstructionPtrArray ctemps(nullptr);
|
||||
|
||||
ResetVisited();
|
||||
while (mEntryBlock->EarlyBranchElimination(ctemps))
|
||||
{}
|
||||
}
|
||||
|
||||
void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact)
|
||||
{
|
||||
// Count number of entries
|
||||
|
@ -22599,7 +22737,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "Test::move");
|
||||
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||
CheckCase = false;
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
@ -22608,6 +22746,10 @@ void InterCodeProcedure::Close(void)
|
|||
|
||||
BuildTraces(true);
|
||||
|
||||
EarlyBranchElimination();
|
||||
|
||||
DisassembleDebug("branch elimination");
|
||||
|
||||
ResetVisited();
|
||||
mLeafProcedure = mEntryBlock->IsLeafProcedure();
|
||||
|
||||
|
|
|
@ -444,6 +444,8 @@ public:
|
|||
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
|
||||
bool ForwardConstTemps(const GrowingInstructionPtrArray& ctemps);
|
||||
|
||||
bool EarlyBranchElimination(const GrowingInstructionPtrArray& ctemps);
|
||||
|
||||
bool PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars, const NumberSet & aliasedLocals, const NumberSet & aliasedParams);
|
||||
|
||||
void BuildLocalTempSets(int num);
|
||||
|
@ -746,6 +748,7 @@ public:
|
|||
protected:
|
||||
void BuildLocalAliasTable(void);
|
||||
void BuildTraces(bool expand, bool dominators = true, bool compact = false);
|
||||
void EarlyBranchElimination(void);
|
||||
void BuildDataFlowSets(void);
|
||||
void RenameTemporaries(void);
|
||||
void TempForwarding(bool reverse = false, bool checkloops = false);
|
||||
|
|
|
@ -3327,12 +3327,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
ins->mCode = IC_CONSTANT;
|
||||
ins->mNumOperands = 0;
|
||||
ins->mConst.mType = IT_INT8;
|
||||
ins->mConst.mType = IT_INT16;
|
||||
ins->mConst.mIntConst = i;
|
||||
ins->mDst.mType = IT_INT8;
|
||||
ins->mDst.mType = IT_INT16;
|
||||
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||
block->Append(ins);
|
||||
return ExValue(TheUnsignedCharTypeDeclaration, ins->mDst.mTemp, vl.mReference - 1);
|
||||
return ExValue(TheSignedIntTypeDeclaration, ins->mDst.mTemp, vl.mReference - 1);
|
||||
}
|
||||
}
|
||||
mErrors->Error(exp->mLocation, ERRR_CANNOT_FIND_BANK_OF_EXPRESSION, "Cannot find bank of expressiohn");
|
||||
|
|
|
@ -8425,7 +8425,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
|
|||
}
|
||||
else if (nexp->mToken == TK_BANKOF)
|
||||
{
|
||||
nexp->mDecType = TheUnsignedCharTypeDeclaration;
|
||||
nexp->mDecType = TheSignedIntTypeDeclaration;
|
||||
}
|
||||
else if (nexp->mToken == TK_BINARY_AND)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue