Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use jump table for some switch statements #12978

Draft
wants to merge 33 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2ed2128
Add jump table to enum-like switch statements
jaa2 Apr 30, 2022
e790925
Fix formatting
jaa2 Apr 30, 2022
46ac486
Add relative jump table option
jaa2 May 4, 2022
e9299e0
Accept switch statements with any range <= 16 values
jaa2 May 5, 2022
e7caf2d
Expect at least one case tag in JumpTablePushTag
jaa2 May 20, 2022
9fffdf7
Ensure bitshift uses correct type
jaa2 May 20, 2022
6cd9212
Remove trailing whitespace
jaa2 May 21, 2022
920bb00
Remove TODO question
jaa2 May 21, 2022
7008ecf
Fix coding style errors
jaa2 May 21, 2022
ecbad03
Add JumpTablePushTag to nameAndData
jaa2 May 22, 2022
39888eb
Ensure pre-Constantinople compatibility
jaa2 May 23, 2022
5aa126d
Add Switch struct to BasicBlock
jaa2 Jun 14, 2022
ad44db5
Only use target when there is no default case
jaa2 Jun 16, 2022
fe1601d
Add switch instructions and case blocks to assembly output
jaa2 Jun 16, 2022
e22d46e
Restore stitchConditionalJumps entry
jaa2 Jun 16, 2022
cfce083
Order switch expression before switch block
jaa2 Jun 16, 2022
09824db
Fix stack layout in case blocks
jaa2 Jun 16, 2022
8185892
Add createStackLayout to top of switch assembly output
jaa2 Jun 17, 2022
04005eb
Remove some commented code
jaa2 Jun 17, 2022
c7accf8
Add Switch block type to CFG and StackLayoutGenerator tests
jaa2 Jun 17, 2022
1bcde18
Consolidate and switch members
jaa2 Jun 17, 2022
2a98f6a
Remove some print statements
jaa2 Jun 17, 2022
30170aa
Assign next block to defaultCase when necessary
jaa2 Jun 17, 2022
ca65870
Consolidate defaultCase and target in tests
jaa2 Jun 17, 2022
f980088
Give all cases entries from the switch block
jaa2 Jun 17, 2022
3fc7882
Remove redundant addChild calls
jaa2 Jun 17, 2022
f5b4381
Remove redundant createStackLayout in default case
jaa2 Jun 17, 2022
ae72fbf
Remove more debug print statements
jaa2 Jun 17, 2022
54fd5de
Consume switch expression in last case comparison
jaa2 Jul 3, 2022
c0b8be1
Use ghost variable switch generation for most switches
jaa2 Jul 6, 2022
4f8e757
Move switch utility functions to yul::Utilities
jaa2 Jul 20, 2022
e68bac5
Implement jump table in optimizer as switch CFG type
jaa2 Jul 20, 2022
c6dabfe
Update semantics tests with jump table
jaa2 Jul 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add Switch block type to CFG and StackLayoutGenerator tests
  • Loading branch information
jaa2 committed Aug 7, 2022
commit c7accf8c2724296119e4a0b76ee8299123c86e2c
41 changes: 40 additions & 1 deletion test/libyul/ControlFlowGraphTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ class ControlFlowGraphPrinter
"Invalid control flow graph."
);
},
[&](CFG::BasicBlock::Switch const& _switch)
{
bool found = false;
if (_switch.defaultCase != nullptr)
found |= (_switch.defaultCase == &_block);
for (auto const& [caseValue, caseBlock]: _switch.cases)
found |= (caseBlock == &_block);
found |= (_switch.target == &_block);
soltestAssert(found, "Switch: Invalid control flow graph.");
},
[&](auto const&)
{
soltestAssert(false, "Invalid control flow graph.");
Expand Down Expand Up @@ -178,7 +188,36 @@ class ControlFlowGraphPrinter
{
m_stream << "Block" << getBlockId(_block) << "Exit [label=\"Terminated\"];\n";
m_stream << "Block" << getBlockId(_block) << " -> Block" << getBlockId(_block) << "Exit;\n";
}
},
[&](CFG::BasicBlock::Switch const& _switch)
{
m_stream << "Block" << getBlockId(_block) << " -> Block" << getBlockId(_block) << "Exit;\n";
m_stream << "Block" << getBlockId(_block) << "Exit [label=\"{ ";
m_stream << stackSlotToString(_switch.switchExpr);
m_stream << "| { ";
std::string exitList = "";
if (_switch.defaultCase != nullptr)
exitList = "<Default> Default ";
for (auto const& [caseValue, caseBlock]: _switch.cases)
{
if (exitList.length() > 0)
exitList += "| ";
exitList += "<" + caseValue.str() + "> " + caseValue.str() + " ";
}
m_stream << exitList;
m_stream << "}}\" shape=Mrecord];\n";

if (_switch.defaultCase != nullptr)
{
m_stream << "Block" << getBlockId(_block);
m_stream << "Exit:Default -> Block" << getBlockId(*_switch.defaultCase) << ";\n";
}
for (auto const& [caseValue, caseBlock]: _switch.cases)
{
m_stream << "Block" << getBlockId(_block);
m_stream << "Exit:" << caseValue << " -> Block" << getBlockId(*caseBlock) << ";\n";
}
},
}, _block.exit);
m_stream << "\n";
}
Expand Down
41 changes: 40 additions & 1 deletion test/libyul/StackLayoutGeneratorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ class StackLayoutPrinter
"Invalid control flow graph."
);
},
[&](CFG::BasicBlock::Switch const& _switch)
{
bool found = false;
if (_switch.defaultCase != nullptr)
found |= (_switch.defaultCase == &_block);
for (auto const& [caseValue, caseBlock]: _switch.cases)
found |= (caseBlock == &_block);
found |= (_switch.target == &_block);
soltestAssert(found, "Switch: Invalid control flow graph.");
},
[&](auto const&)
{
soltestAssert(false, "Invalid control flow graph.");
Expand Down Expand Up @@ -194,7 +204,36 @@ class StackLayoutPrinter
{
m_stream << "Block" << getBlockId(_block) << "Exit [label=\"Terminated\"];\n";
m_stream << "Block" << getBlockId(_block) << " -> Block" << getBlockId(_block) << "Exit;\n";
}
},
[&](CFG::BasicBlock::Switch const& _switch)
{
m_stream << "Block" << getBlockId(_block) << " -> Block" << getBlockId(_block) << "Exit;\n";
m_stream << "Block" << getBlockId(_block) << "Exit [label=\"{ ";
m_stream << stackSlotToString(_switch.switchExpr);
m_stream << "| { ";
std::string exitList = "";
if (_switch.defaultCase != nullptr)
exitList = "<Default> Default ";
for (auto const& [caseValue, caseBlock]: _switch.cases)
{
if (exitList.length() > 0)
exitList += "| ";
exitList += "<" + caseValue.str() + "> " + caseValue.str() + " ";
}
m_stream << exitList;
m_stream << "}}\" shape=Mrecord];\n";

if (_switch.defaultCase != nullptr)
{
m_stream << "Block" << getBlockId(_block);
m_stream << "Exit:Default -> Block" << getBlockId(*_switch.defaultCase) << ";\n";
}
for (auto const& [caseValue, caseBlock]: _switch.cases)
{
m_stream << "Block" << getBlockId(_block);
m_stream << "Exit:" << caseValue << " -> Block" << getBlockId(*caseBlock) << ";\n";
}
},
}, _block.exit);
m_stream << "\n";
}
Expand Down