MLIR: lib/Conversion/PDLToPDLInterp/RootOrdering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

15

16 #include "llvm/ADT/DenseMap.h"

17 #include "llvm/ADT/DenseSet.h"

18 #include "llvm/ADT/SmallVector.h"

19 #include

20 #include

21

22 using namespace mlir;

24

25

26

31 do {

32 cycle.push_back(node);

33 node = parents.lookup(node);

34 assert(node && "got an empty value in the cycle");

35 } while (node != rep);

36 return cycle;

37 }

38

39

40

41

42

43

44

45

46

47

52 Value rep = cycle.front();

54

55

57 for (auto outer = graph.begin(), e = graph.end(); outer != e; ++outer) {

58 Value target = outer->first;

59 if (cycleSet.contains(target)) {

60

61 unsigned parentDepth = parentDepths.lookup(target);

62 for (const auto &inner : outer->second) {

63 Value source = inner.first;

64

65 if (cycleSet.contains(source))

66 continue;

67

68

69 std::pair<unsigned, unsigned> cost = inner.second.cost;

70 assert(parentDepth <= cost.first && "invalid parent depth");

71

72

73

74

75

76

77 cost.first -= parentDepth;

78 auto it = repEntries.find(source);

79 if (it == repEntries.end() || it->second.cost > cost) {

80 actualTarget[source] = target;

81

82

83 repEntries[source].cost = cost;

84 }

85 }

86

87 graph.erase(outer);

88 } else {

89

92 std::pair<unsigned, unsigned> bestCost;

93 auto inner = entries.begin(), innerE = entries.end();

94 while (inner != innerE) {

95 Value source = inner->first;

96 if (cycleSet.contains(source)) {

97

98 if (!bestSource || bestCost > inner->second.cost) {

99 bestSource = source;

100 bestCost = inner->second.cost;

101 }

102 entries.erase(inner++);

103 } else {

104 ++inner;

105 }

106 }

107

108

109 if (bestSource) {

110 entries[rep].cost = bestCost;

111 actualSource[target] = bestSource;

112 }

113 }

114 }

115

116

117 graph[rep] = std::move(repEntries);

118 }

119

121 : graph(std::move(graph)), root(root) {}

122

124

125 parents.clear();

126 parents[root] = Value();

127 unsigned totalCost = 0;

128

129

130

132 parentDepths.reserve(graph.size());

133

134

135

136

137 for (const auto &outer : graph) {

138 Value node = outer.first;

139 if (parents.count(node))

140 continue;

141

142

143

144

145 parentDepths.clear();

146 do {

147 auto it = graph.find(node);

148 assert(it != graph.end() && "the graph is not strongly connected");

149

150

151

152 Value &bestSource = parents[node];

153 std::pair<unsigned, unsigned> bestCost;

154 for (const auto &inner : it->second) {

156 if (!bestSource || bestCost > entry.cost) {

157 bestSource = inner.first;

158 bestCost = entry.cost;

159 }

160 }

161 assert(bestSource && "the graph is not strongly connected");

162 parentDepths[node] = bestCost.first;

163 node = bestSource;

164 totalCost += bestCost.first;

165 } while (!parents.count(node));

166

167

168 if (parentDepths.count(node)) {

169

171

172

173

175

176

177 contract(graph, cycle, parentDepths, actualSource, actualTarget);

178 totalCost = solve();

179

180

181 for (auto &p : parents)

182 if (p.second == node)

183

184

185 p.second = actualSource.lookup(p.first);

186

187

188 Value parent = parents.lookup(node);

189 Value entry = actualTarget.lookup(parent);

190 cycle.push_back(node);

191 for (size_t i = 0, e = cycle.size() - 1; i < e; ++i) {

192 totalCost += parentDepths.lookup(cycle[i]);

193 if (cycle[i] == entry)

194 parents[cycle[i]] = parent;

195 else

196 parents[cycle[i]] = cycle[i + 1];

197 }

198

199

200 break;

201 }

202 }

203

204 return totalCost;

205 }

206

209

211 for (Value node : nodes) {

212 if (node != root) {

213 Value parent = parents.lookup(node);

214 assert(parent && "invalid parent");

215 children[parent].push_back(node);

216 }

217 }

218

219

221 result.reserve(nodes.size());

222 result.emplace_back(root, Value());

223

224

225 for (size_t i = 0; i < result.size(); ++i) {

226 Value node = result[i].first;

227 for (Value child : children[node])

228 result.emplace_back(child, node);

229 }

230

231 return result;

232 }

static void contract(RootOrderingGraph &graph, ArrayRef< Value > cycle, const DenseMap< Value, unsigned > &parentDepths, DenseMap< Value, Value > &actualSource, DenseMap< Value, Value > &actualTarget)

Contracts the specified cycle in the given graph in-place.

static SmallVector< Value > getCycle(const DenseMap< Value, Value > &parents, Value rep)

Returns the cycle implied by the specified parent relation, starting at the given node.

This class represents an instance of an SSA value in the MLIR system, representing a computable value...

unsigned solve()

Runs the Edmonds' algorithm for the current graph, returning the total cost of the minimum-weight spa...

std::vector< std::pair< Value, Value > > EdgeList

A list of edges (child, parent).

OptimalBranching(RootOrderingGraph graph, Value root)

Constructs the solver for the given graph and root value.

EdgeList preOrderTraversal(ArrayRef< Value > nodes) const

Returns the computed edges as visited in the preorder traversal.

Include the generated interface declarations.

The information associated with an edge in the cost graph.

std::pair< unsigned, unsigned > cost

The depth of the connector Value w.r.t.