Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: src/IceLoopAnalyzer.cpp

Issue 1318553003: Compute the loop nest depth of each CfgNode and weight Variables by it. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //===- subzero/src/IceLoopAnalyzer.cpp - Loop Analysis --------------------===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file implements the loop analysis on the CFG.
12 ///
13 //===----------------------------------------------------------------------===//
14 #include "IceLoopAnalyzer.h"
15
16 #include "IceCfg.h"
17 #include "IceCfgNode.h"
18
19 namespace Ice {
20
21 void LoopAnalyzer::LoopNode::reset() {
22 if (Deleted)
23 return;
24 Succ = BB->getOutEdges().begin();
25 Index = LowLink = UndefinedIndex;
26 OnStack = false;
27 }
28
29 NodeList::const_iterator LoopAnalyzer::LoopNode::successorsEnd() const {
30 return BB->getOutEdges().end();
31 }
32
33 void LoopAnalyzer::LoopNode::incrementLoopNestDepth() {
34 BB->incrementLoopNestDepth();
35 }
36
37 LoopAnalyzer::LoopAnalyzer(Cfg *Func) : Func(Func) {
38 const NodeList &Nodes = Func->getNodes();
39
40 // Allocate memory ahead of time. This is why a vector is used instead of a
41 // stack which doesn't support reserving (or bulk erasure used below).
42 AllNodes.reserve(Nodes.size());
43 WorkStack.reserve(Nodes.size());
44 LoopStack.reserve(Nodes.size());
45
46 // Create the LoopNodes from the function's CFG
47 for (CfgNode *Node : Nodes)
48 AllNodes.emplace_back(Node);
49 }
50
51 void LoopAnalyzer::computeLoopNestDepth() {
52 assert(AllNodes.size() == Func->getNodes().size());
53 assert(NextIndex == FirstDefinedIndex);
54 assert(NumDeletedNodes == 0);
55
56 while (NumDeletedNodes < AllNodes.size()) {
57 // Prepare to run Tarjan's
58 for (LoopNode &Node : AllNodes)
59 Node.reset();
60
61 assert(WorkStack.empty());
62 assert(LoopStack.empty());
63
64 for (LoopNode &Node : AllNodes) {
65 if (Node.isDeleted() || Node.isVisited())
66 continue;
67
68 WorkStack.push_back(&Node);
69
70 while (!WorkStack.empty()) {
71 LoopNode &WorkNode = *WorkStack.back();
72 if (LoopNode *Succ = processNode(WorkNode))
73 WorkStack.push_back(Succ);
74 else
75 WorkStack.pop_back();
76 }
77 }
78 }
79 }
80
81 LoopAnalyzer::LoopNode *
82 LoopAnalyzer::processNode(LoopAnalyzer::LoopNode &Node) {
83 if (!Node.isVisited()) {
84 Node.visit(NextIndex++);
85 LoopStack.push_back(&Node);
86 Node.setOnStack();
87 } else {
88 // Returning to a node after having recursed into Succ so continue
89 // iterating through successors after using the Succ.LowLink value that was
90 // computed in the recursion.
91 LoopNode &Succ = AllNodes[(*Node.currentSuccessor())->getIndex()];
92 Node.tryLink(Succ.getLowLink());
93 Node.nextSuccessor();
94 }
95
96 // Visit the successors and recurse into unvisited nodes. The recursion could
97 // cause the iteration to be suspended but it will resume as the stack is
98 // unwound.
99 auto SuccEnd = Node.successorsEnd();
100 for (; Node.currentSuccessor() != SuccEnd; Node.nextSuccessor()) {
101 LoopNode &Succ = AllNodes[(*Node.currentSuccessor())->getIndex()];
102
103 if (Succ.isDeleted())
104 continue;
105
106 if (!Succ.isVisited())
107 return &Succ;
108 else if (Succ.isOnStack())
109 Node.tryLink(Succ.getIndex());
110 }
111
112 if (Node.getLowLink() != Node.getIndex())
113 return nullptr;
114
115 // Single node means no loop in the CFG
116 if (LoopStack.back() == &Node) {
117 LoopStack.back()->setOnStack(false);
118 LoopStack.back()->setDeleted();
119 ++NumDeletedNodes;
120 LoopStack.pop_back();
121 return nullptr;
122 }
123
124 // Reaching here means a loop has been found! It consists of the nodes on
125 // the top of the stack, down until the current node being processed, Node,
126 // is found.
127 for (auto It = LoopStack.rbegin(); It != LoopStack.rend(); ++It) {
128 (*It)->setOnStack(false);
129 (*It)->incrementLoopNestDepth();
130 // Remove the loop from the stack and delete the head node
131 if (*It == &Node) {
132 (*It)->setDeleted();
133 ++NumDeletedNodes;
134 LoopStack.erase(It.base() - 1, LoopStack.end());
135 break;
136 }
137 }
138
139 return nullptr;
140 }
141
142 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698