5 #include "src/compiler/control-equivalence.h" 6 #include "src/compiler/node-properties.h" 10 if (FLAG_trace_turbo_ceq) PrintF(__VA_ARGS__); \ 17 void ControlEquivalence::Run(Node* exit) {
18 if (!Participates(exit) || GetClass(exit) == kInvalidClass) {
19 DetermineParticipation(exit);
20 RunUndirectedDFS(exit);
26 STATIC_CONST_MEMBER_DEFINITION
const size_t ControlEquivalence::kInvalidClass;
29 void ControlEquivalence::VisitPre(Node* node) {
30 TRACE(
"CEQ: Pre-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
34 void ControlEquivalence::VisitMid(Node* node, DFSDirection direction) {
35 TRACE(
"CEQ: Mid-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
36 BracketList& blist = GetBracketList(node);
39 BracketListDelete(blist, node, direction);
43 DCHECK_EQ(kInputDirection, direction);
44 VisitBackedge(node, graph_->end(), kInputDirection);
48 BracketListTRACE(blist);
49 Bracket* recent = &blist.back();
50 if (recent->recent_size != blist.size()) {
51 recent->recent_size = blist.size();
52 recent->recent_class = NewClassNumber();
56 SetClass(node, recent->recent_class);
57 TRACE(
" Assigned class number is %zu\n", GetClass(node));
61 void ControlEquivalence::VisitPost(Node* node, Node* parent_node,
62 DFSDirection direction) {
63 TRACE(
"CEQ: Post-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
64 BracketList& blist = GetBracketList(node);
67 BracketListDelete(blist, node, direction);
70 if (parent_node !=
nullptr) {
71 BracketList& parent_blist = GetBracketList(parent_node);
72 parent_blist.splice(parent_blist.end(), blist);
77 void ControlEquivalence::VisitBackedge(Node* from, Node* to,
78 DFSDirection direction) {
79 TRACE(
"CEQ: Backedge from #%d:%s to #%d:%s\n", from->id(),
80 from->op()->mnemonic(), to->id(), to->op()->mnemonic());
83 Bracket bracket = {direction, kInvalidClass, 0, from, to};
84 GetBracketList(from).push_back(bracket);
88 void ControlEquivalence::RunUndirectedDFS(Node* exit) {
89 ZoneStack<DFSStackEntry> stack(zone_);
90 DFSPush(stack, exit,
nullptr, kInputDirection);
93 while (!stack.empty()) {
94 DFSStackEntry& entry = stack.top();
95 Node* node = entry.node;
97 if (entry.direction == kInputDirection) {
98 if (entry.input != node->input_edges().end()) {
99 Edge edge = *entry.input;
100 Node* input = edge.to();
102 if (NodeProperties::IsControlEdge(edge)) {
104 if (!Participates(input))
continue;
105 if (GetData(input)->visited)
continue;
106 if (GetData(input)->on_stack) {
108 if (input != entry.parent_node) {
109 VisitBackedge(node, input, kInputDirection);
113 DFSPush(stack, input, node, kInputDirection);
119 if (entry.use != node->use_edges().end()) {
121 entry.direction = kUseDirection;
122 VisitMid(node, kInputDirection);
127 if (entry.direction == kUseDirection) {
128 if (entry.use != node->use_edges().end()) {
129 Edge edge = *entry.use;
130 Node* use = edge.from();
132 if (NodeProperties::IsControlEdge(edge)) {
134 if (!Participates(use))
continue;
135 if (GetData(use)->visited)
continue;
136 if (GetData(use)->on_stack) {
138 if (use != entry.parent_node) {
139 VisitBackedge(node, use, kUseDirection);
143 DFSPush(stack, use, node, kUseDirection);
149 if (entry.input != node->input_edges().end()) {
151 entry.direction = kInputDirection;
152 VisitMid(node, kUseDirection);
158 DCHECK(entry.input == node->input_edges().end());
159 DCHECK(entry.use == node->use_edges().end());
161 VisitPost(node, entry.parent_node, entry.direction);
165 void ControlEquivalence::DetermineParticipationEnqueue(ZoneQueue<Node*>& queue,
167 if (!Participates(node)) {
174 void ControlEquivalence::DetermineParticipation(Node* exit) {
175 ZoneQueue<Node*> queue(zone_);
176 DetermineParticipationEnqueue(queue, exit);
177 while (!queue.empty()) {
178 Node* node = queue.front();
180 int max = NodeProperties::PastControlIndex(node);
181 for (
int i = NodeProperties::FirstControlIndex(node);
i < max;
i++) {
182 DetermineParticipationEnqueue(queue, node->InputAt(
i));
188 void ControlEquivalence::DFSPush(DFSStack& stack, Node* node, Node* from,
190 DCHECK(Participates(node));
191 DCHECK(!GetData(node)->visited);
192 GetData(node)->on_stack =
true;
193 Node::InputEdges::iterator input = node->input_edges().begin();
194 Node::UseEdges::iterator use = node->use_edges().begin();
195 stack.push({dir, input, use, from, node});
199 void ControlEquivalence::DFSPop(DFSStack& stack, Node* node) {
200 DCHECK_EQ(stack.top().node, node);
201 GetData(node)->on_stack =
false;
202 GetData(node)->visited =
true;
207 void ControlEquivalence::BracketListDelete(BracketList& blist, Node* to,
208 DFSDirection direction) {
210 for (BracketList::iterator
i = blist.begin();
i != blist.end(); ) {
211 if (
i->to == to &&
i->direction != direction) {
212 TRACE(
" BList erased: {%d->%d}\n",
i->from->id(),
i->to->id());
221 void ControlEquivalence::BracketListTRACE(BracketList& blist) {
222 if (FLAG_trace_turbo_ceq) {
224 for (Bracket bracket : blist) {
225 TRACE(
"{%d->%d} ", bracket.from->id(), bracket.to->id());