Optimize switch case tree
This commit is contained in:
parent
6cb15fd7d9
commit
6e4bf52781
|
@ -1051,40 +1051,53 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
|
||||||
assert(offset == osize);
|
assert(offset == osize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, ExValue v, const SwitchNodeArray& nodes, int left, int right, InterCodeBasicBlock* dblock)
|
void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, ExValue v, const SwitchNodeArray& nodes, int left, int right, int vleft, int vright, InterCodeBasicBlock* dblock)
|
||||||
{
|
{
|
||||||
if (right - left < 5)
|
if (right - left < 3)
|
||||||
{
|
{
|
||||||
for (int i = left; i < right; i++)
|
for (int i = left; i < right; i++)
|
||||||
{
|
{
|
||||||
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
|
if (vleft == vright)
|
||||||
|
{
|
||||||
|
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
||||||
|
block->Append(jins);
|
||||||
|
block->Close(nodes[i].mBlock, nullptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
|
||||||
|
|
||||||
InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
vins->mConst.mType = IT_INT16;
|
vins->mConst.mType = IT_INT16;
|
||||||
vins->mConst.mIntConst = nodes[i].mValue;
|
vins->mConst.mIntConst = nodes[i].mValue;
|
||||||
vins->mDst.mType = IT_INT16;
|
vins->mDst.mType = IT_INT16;
|
||||||
vins->mDst.mTemp = proc->AddTemporary(vins->mDst.mType);
|
vins->mDst.mTemp = proc->AddTemporary(vins->mDst.mType);
|
||||||
block->Append(vins);
|
block->Append(vins);
|
||||||
|
|
||||||
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_RELATIONAL_OPERATOR);
|
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_RELATIONAL_OPERATOR);
|
||||||
cins->mOperator = IA_CMPEQ;
|
cins->mOperator = IA_CMPEQ;
|
||||||
cins->mSrc[0].mType = vins->mDst.mType;
|
cins->mSrc[0].mType = vins->mDst.mType;
|
||||||
cins->mSrc[0].mTemp = vins->mDst.mTemp;
|
cins->mSrc[0].mTemp = vins->mDst.mTemp;
|
||||||
cins->mSrc[1].mType = vins->mDst.mType;
|
cins->mSrc[1].mType = vins->mDst.mType;
|
||||||
cins->mSrc[1].mTemp = v.mTemp;
|
cins->mSrc[1].mTemp = v.mTemp;
|
||||||
cins->mDst.mType = IT_BOOL;
|
cins->mDst.mType = IT_BOOL;
|
||||||
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
|
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
|
||||||
|
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
|
||||||
InterInstruction* bins = new InterInstruction(exp->mLocation, IC_BRANCH);
|
InterInstruction* bins = new InterInstruction(exp->mLocation, IC_BRANCH);
|
||||||
bins->mSrc[0].mType = IT_BOOL;
|
bins->mSrc[0].mType = IT_BOOL;
|
||||||
bins->mSrc[0].mTemp = cins->mDst.mTemp;
|
bins->mSrc[0].mTemp = cins->mDst.mTemp;
|
||||||
block->Append(bins);
|
block->Append(bins);
|
||||||
|
|
||||||
block->Close(nodes[i].mBlock, cblock);
|
block->Close(nodes[i].mBlock, cblock);
|
||||||
|
|
||||||
block = cblock;
|
block = cblock;
|
||||||
|
|
||||||
|
if (vleft == nodes[i].mValue)
|
||||||
|
vleft = nodes[i].mValue + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
||||||
|
@ -1094,7 +1107,8 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int center = (left + right + 1) >> 1;
|
int center = (left + right) >> 1;
|
||||||
|
int vcenter = nodes[center].mValue;
|
||||||
|
|
||||||
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
|
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
|
||||||
InterCodeBasicBlock* rblock = new InterCodeBasicBlock(proc);
|
InterCodeBasicBlock* rblock = new InterCodeBasicBlock(proc);
|
||||||
|
@ -1102,7 +1116,7 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e
|
||||||
|
|
||||||
InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
vins->mConst.mType = IT_INT16;
|
vins->mConst.mType = IT_INT16;
|
||||||
vins->mConst.mIntConst = nodes[center].mValue;
|
vins->mConst.mIntConst = vcenter;
|
||||||
vins->mDst.mType = IT_INT16;
|
vins->mDst.mType = IT_INT16;
|
||||||
vins->mDst.mTemp = proc->AddTemporary(vins->mDst.mType);
|
vins->mDst.mTemp = proc->AddTemporary(vins->mDst.mType);
|
||||||
block->Append(vins);
|
block->Append(vins);
|
||||||
|
@ -1143,8 +1157,8 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e
|
||||||
|
|
||||||
cblock->Close(lblock, rblock);
|
cblock->Close(lblock, rblock);
|
||||||
|
|
||||||
BuildSwitchTree(proc, exp, lblock, v, nodes, left, center, dblock);
|
BuildSwitchTree(proc, exp, lblock, v, nodes, left, center, vleft, vcenter -1, dblock);
|
||||||
BuildSwitchTree(proc, exp, rblock, v, nodes, center + 1, right, dblock);
|
BuildSwitchTree(proc, exp, rblock, v, nodes, center + 1, right, vcenter + 1, vright, dblock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1434,6 +1448,7 @@ void InterCodeGenerator::CopyStructSimple(InterCodeProcedure* proc, Expression *
|
||||||
cins->mSrc[1].mType = IT_POINTER;
|
cins->mSrc[1].mType = IT_POINTER;
|
||||||
cins->mSrc[1].mTemp = vl.mTemp;
|
cins->mSrc[1].mTemp = vl.mTemp;
|
||||||
cins->mSrc[1].mMemory = IM_INDIRECT;
|
cins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
cins->mSrc[1].mStride = vl.mType->mStripe;
|
||||||
|
|
||||||
cins->mConst.mOperandSize = vl.mType->mSize;
|
cins->mConst.mOperandSize = vl.mType->mSize;
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
@ -4752,6 +4767,25 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
vl = Dereference(proc, exp, block, vl);
|
vl = Dereference(proc, exp, block, vl);
|
||||||
|
|
||||||
|
int vleft = 0, vright = 65535;
|
||||||
|
|
||||||
|
if (vl.mType->mSize == 1)
|
||||||
|
{
|
||||||
|
if (vl.mType->mFlags & DTF_SIGNED)
|
||||||
|
{
|
||||||
|
vleft = -128;
|
||||||
|
vright = 127;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vright = 255;
|
||||||
|
}
|
||||||
|
else if (vl.mType->mFlags & DTF_SIGNED)
|
||||||
|
{
|
||||||
|
vleft = -32768;
|
||||||
|
vright = 32767;
|
||||||
|
}
|
||||||
|
|
||||||
vl = CoerceType(proc, exp, block, vl, TheSignedIntTypeDeclaration);
|
vl = CoerceType(proc, exp, block, vl, TheSignedIntTypeDeclaration);
|
||||||
|
|
||||||
InterCodeBasicBlock * dblock = nullptr;
|
InterCodeBasicBlock * dblock = nullptr;
|
||||||
|
@ -4824,7 +4858,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
sexp = sexp->mRight;
|
sexp = sexp->mRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildSwitchTree(proc, exp, sblock, vl, switchNodes, 0, switchNodes.Size(), dblock ? dblock : eblock);
|
|
||||||
|
BuildSwitchTree(proc, exp, sblock, vl, switchNodes, 0, switchNodes.Size(), vleft, vright, dblock ? dblock : eblock);
|
||||||
|
|
||||||
if (block)
|
if (block)
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,7 +78,7 @@ protected:
|
||||||
InterCodeProcedure* mMainInitProc;
|
InterCodeProcedure* mMainInitProc;
|
||||||
InterCodeBasicBlock* mMainInitBlock;
|
InterCodeBasicBlock* mMainInitBlock;
|
||||||
|
|
||||||
void BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, ExValue v, const SwitchNodeArray& nodes, int left, int right, InterCodeBasicBlock* dblock);
|
void BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, ExValue v, const SwitchNodeArray& nodes, int left, int right, int vleft, int vright, InterCodeBasicBlock* dblock);
|
||||||
|
|
||||||
ExValue ToValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v);
|
ExValue ToValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v);
|
||||||
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, int level = 0);
|
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, int level = 0);
|
||||||
|
|
Loading…
Reference in New Issue