Add early dead code elimination to speed up template compilation

This commit is contained in:
drmortalwombat 2024-10-01 18:30:07 +02:00
parent 62ab925e01
commit 6af50f5eae
5 changed files with 161 additions and 13 deletions

View File

@ -579,14 +579,17 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
i++;
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;

View File

@ -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();

View File

@ -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);

View File

@ -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");

View File

@ -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)
{