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

Doxygen-style comments for ParserCallGraph and SimplifyParsers. #571

Merged
merged 1 commit into from
May 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions frontends/p4/parserCallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ namespace P4 {

typedef CallGraph<const IR::ParserState*> ParserCallGraph;

/** @brief Builds a CallGraph of ParserState nodes.
*/
class ComputeParserCG : public Inspector {
const ReferenceMap* refMap;
ParserCallGraph* transitions;
Expand Down
28 changes: 24 additions & 4 deletions frontends/p4/simplifyParsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ namespace {
// All the classes in this namespace are invoked on each parser
// independently.

/** @brief Removes unreachable ParserState nodes.
*
* If the "accept" state is unreachable, a compiler warning is emitted but the
* state is not removed.
*
* Must be invoked on each parser independently.
*/
class RemoveUnreachableStates : public Transform {
ParserCallGraph* transitions;
std::set<const IR::ParserState*> reachable;
Expand Down Expand Up @@ -62,7 +69,16 @@ class RemoveUnreachableStates : public Transform {
}
};

// This is only invoked on parsers
/** @brief Collapses chains in the parse graph into a single node.
*
* Finds chains of parser states, eg. ```s -> s1 -> s2``` such that these are
* all the transitions between these states, and collapses them into a single
* state. The "accept", "reject", and "start" states are not considered.
*
* Each new node has the same name as the head node of the chain it collapses.
*
* Must only be invoked on parsers.
*/
class CollapseChains : public Transform {
ParserCallGraph* transitions;
std::map<const IR::ParserState*, const IR::ParserState*> chain;
Expand All @@ -73,11 +89,12 @@ class CollapseChains : public Transform {
{ CHECK_NULL(transitions); setName("CollapseChains"); }

const IR::Node* preorder(IR::P4Parser* parser) override {
// pred[s2] = s1 if there is exactly one outgoing edge from s1, it goes
// to s2, and s2 has no other incoming edges.
std::map<const IR::ParserState*, const IR::ParserState*> pred;

// Find chains s -> s1 -> s2
// such that these are all the transitions between these states.
// Collapse these into a single state.
// Find edges s1 -> s2 such that s1 has no other outgoing edges and s2
// has no other incoming edges.
for (auto oe : *transitions) {
auto node = oe.first;
auto outedges = oe.second;
Expand All @@ -100,6 +117,7 @@ class CollapseChains : public Transform {
if (chain.empty())
return parser;

// Find the head of each chain.
for (auto e : pred) {
auto crt = e.first;
while (pred.find(crt) != pred.end()) {
Expand All @@ -111,6 +129,8 @@ class CollapseChains : public Transform {
chainStart.emplace(crt);
}

// Collapse the states in each chain into a new state with the name and
// annotations of the chain's head state.
auto states = new IR::IndexedVector<IR::ParserState>();
for (auto s : parser->states) {
if (pred.find(s) != pred.end())
Expand Down
11 changes: 9 additions & 2 deletions frontends/p4/simplifyParsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@ limitations under the License.

namespace P4 {

// - remove unreachable parser states
// - collapse simple chains of states
/** @brief Remove unreachable parser states, and collapse simple chains of
* states.
*
* Does not remove the "accept" state, even if it is not reachable. A
* transition between states ```s1``` and ```s2``` is part of a "simple" chain if:
* - there are no other outgoing edges from ```s1```,
* - there are no other incoming edges to ```s2```,
* - and ```s2``` does not have annotations.
*/
class DoSimplifyParsers : public Transform {
ReferenceMap *refMap;
public:
Expand Down