P4C
The P4 Compiler
Loading...
Searching...
No Matches
removeReturns.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef FRONTENDS_P4_REMOVERETURNS_H_
9#define FRONTENDS_P4_REMOVERETURNS_H_
10
11#include "frontends/common/resolveReferences/resolveReferences.h"
12#include "frontends/p4/ternaryBool.h"
13#include "frontends/p4/typeChecking/typeChecker.h"
14#include "ir/ir.h"
15
16namespace P4 {
17using namespace literals;
18
24class HasExits : public Inspector {
25 public:
26 bool hasExits;
27 bool hasReturns;
28 HasExits() : hasExits(false), hasReturns(false) { setName("HasExits"); }
29
30 void postorder(const IR::ExitStatement *) override { hasExits = true; }
31 void postorder(const IR::ReturnStatement *) override { hasReturns = true; }
32};
33
59class MoveToElseAfterBranch : public Modifier {
60 /* This pass does not use (inherit from) ControlFlowVisitor, even though it is doing
61 * control flow analysis, as it turns out to be more efficient to do it directly here
62 * by overloading the branching constructs (if/switch/loops) and not cloning the visitor,
63 * because we *only* care about statements (not expressions) locally in a block (and
64 * not across calls), and we only have one bit of data (hasJumped flag). */
65
68 bool hasJumped = false;
69
72 bool movedToIfBranch = false;
73
74 bool preorder(IR::BlockStatement *) override;
75 bool moveFromParentTo(const IR::Statement *&child);
76 bool preorder(IR::IfStatement *) override;
77 bool preorder(IR::SwitchStatement *) override;
78 void postorder(IR::LoopStatement *) override;
79 bool branch() {
80 hasJumped = true;
81 // no need to visit children
82 return false;
83 }
84 bool preorder(IR::BreakStatement *) override { return branch(); }
85 bool preorder(IR::ContinueStatement *) override { return branch(); }
86 bool preorder(IR::ExitStatement *) override { return branch(); }
87 bool preorder(IR::ReturnStatement *) override { return branch(); }
88 // Only visit statements, skip all expressions
89 bool preorder(IR::Expression *) override { return false; }
90
91 public:
92 MoveToElseAfterBranch() {}
93};
94
112class DoRemoveReturns : public Transform {
113 protected:
114 MinimalNameGenerator nameGen;
115 IR::ID returnVar; // one for each context
116 IR::ID returnedValue; // only for functions that return expressions
117 cstring variableName;
118 cstring retValName;
119
120 std::vector<TernaryBool> stack;
121 void push() { stack.push_back(TernaryBool::No); }
122 void pop() { stack.pop_back(); }
123 void set(TernaryBool r) {
124 BUG_CHECK(!stack.empty(), "Empty stack");
125 stack.back() = r;
126 }
127 TernaryBool hasReturned() {
128 BUG_CHECK(!stack.empty(), "Empty stack");
129 return stack.back();
130 }
131
132 public:
133 explicit DoRemoveReturns(cstring varName = "hasReturned"_cs, cstring retValName = "retval"_cs)
134 : variableName(varName), retValName(retValName) {
135 visitDagOnce = false;
136 setName("DoRemoveReturns");
137 }
138
139 const IR::Node *preorder(IR::Function *function) override;
140 const IR::Node *preorder(IR::BlockStatement *statement) override;
141 const IR::Node *preorder(IR::ReturnStatement *statement) override;
142 const IR::Node *preorder(IR::ExitStatement *statement) override;
143 const IR::Node *preorder(IR::IfStatement *statement) override;
144 const IR::Node *preorder(IR::SwitchStatement *statement) override;
145
146 const IR::Node *preorder(IR::P4Action *action) override;
147 const IR::Node *preorder(IR::P4Control *control) override;
148 const IR::Node *preorder(IR::P4Parser *parser) override {
149 prune();
150 return parser;
151 }
152
153 const IR::Node *postorder(IR::LoopStatement *loop) override;
154 profile_t init_apply(const IR::Node *node) override;
155};
156
157class RemoveReturns : public PassManager {
158 public:
159 RemoveReturns() : PassManager({new MoveToElseAfterBranch(), new DoRemoveReturns()}) {}
160};
161
162} // namespace P4
163
164#endif /* FRONTENDS_P4_REMOVERETURNS_H_ */
Definition removeReturns.h:112
Definition node.h:53
Definition visitor.h:418
Definition referenceMap.h:36
Definition visitor.h:385
Definition removeReturns.h:59
Definition visitor.h:442
Definition visitor.h:78
Definition cstring.h:85
Definition cstring.h:80
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
Definition id.h:28