[loco] Support traversal to Graph from Node (#5910)
author박종현/On-Device Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Sun, 28 Jul 2019 23:37:41 +0000 (08:37 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Sun, 28 Jul 2019 23:37:41 +0000 (08:37 +0900)
This commit extends Node class to provide "graph" method which returns
a pointer to associated Graph object.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
compiler/loco/include/loco/IR/Graph.forward.h [new file with mode: 0644]
compiler/loco/include/loco/IR/Graph.h
compiler/loco/include/loco/IR/Node.h
compiler/loco/include/loco/IR/NodePool.forward.h [new file with mode: 0644]
compiler/loco/include/loco/IR/NodePool.h [new file with mode: 0644]
compiler/loco/src/IR/Graph.cpp
compiler/loco/src/IR/Graph.test.cpp
compiler/loco/src/IR/Node.test.cpp
compiler/loco/src/IR/NodePool.cpp [new file with mode: 0644]

diff --git a/compiler/loco/include/loco/IR/Graph.forward.h b/compiler/loco/include/loco/IR/Graph.forward.h
new file mode 100644 (file)
index 0000000..2a43be9
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LOCO_IR_GRAPH_FORWARD_H__
+#define __LOCO_IR_GRAPH_FORWARD_H__
+
+namespace loco
+{
+
+// This forward declaration SHOULD BE aligned with the actual declaration in "Graph.h".
+class Graph;
+
+} // namespace loco
+
+#endif // __LOCO_IR_GRAPH_FORWARD_H__
index 4163f47..9b98c0d 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "loco/IR/DataType.h"
 #include "loco/IR/Nodes.h"
+#include "loco/IR/NodePool.h"
 
 #include "loco/ADT/ObjectPool.h"
 
@@ -149,27 +150,12 @@ class Graph final
 public:
   /**
    * @brief Node Pool
+   *
+   * This alias confines the impact of changes to loco internals.
+   *
+   * TODO Remove this alias
    */
-  class NodeContext final : public ObjectPool<Node>
-  {
-  public:
-    ~NodeContext();
-
-  public:
-    template <typename Derived, typename... Args> Derived *create(Args &&... args)
-    {
-      std::unique_ptr<Derived> ptr{new Derived(std::forward<Args>(args)...)};
-      return ObjectPool<Node>::take<Derived>(std::move(ptr));
-    }
-
-    void destroy(Node *node)
-    {
-      if (!ObjectPool<Node>::erase(node))
-      {
-        throw std::invalid_argument{"node"};
-      }
-    }
-  };
+  using NodeContext = NodePool;
 
   /**
    * @brief Object Pool with Simple Factory Method
@@ -200,7 +186,11 @@ public:
   };
 
 public:
-  Graph() = default;
+  Graph()
+  {
+    // Associate "NodeContext" and the current "Graph"
+    _node_ctx.graph(this);
+  }
 
   // Copy/Move is not allowed for Graph
   Graph(const Graph &) = delete;
index 2d35c0a..fd9104e 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "loco/IR/Use.h"
 #include "loco/IR/Dialect.h"
+#include "loco/IR/NodePool.forward.h"
+#include "loco/IR/Graph.forward.h"
 
 #include <array>
 #include <memory>
@@ -52,6 +54,7 @@ class Node : public AnnotatedItem<NodeAnnotation>
 public:
   friend class Use;
   friend class Subst<SubstQualifier::Default>;
+  friend class NodePool;
   friend std::set<Node *> succs(const Node *node);
 
 public:
@@ -63,6 +66,18 @@ public:
   virtual ~Node();
 
 public:
+  Graph *graph(void) { return _graph; }
+  const Graph *graph(void) const { return _graph; }
+
+private:
+  /**
+   * @brief Set associated "Graph"
+   *
+   * @note Only "NodePool" class is permitted to invoke this private method.
+   */
+  void graph(Graph *g) { _graph = g; }
+
+public:
   /**
    * @brief Return "Dialect" identifier that this node belongs to
    *
@@ -88,6 +103,13 @@ public:
 
 private:
   /**
+   * @brief Associated Graph
+   *
+   * May be nullptr if no associated Graph exists.
+   */
+  Graph *_graph = nullptr;
+
+  /**
    * @brief The edges to a node that uses this node as its argument
    *
    * @note "succs" function below accesses this private field.
diff --git a/compiler/loco/include/loco/IR/NodePool.forward.h b/compiler/loco/include/loco/IR/NodePool.forward.h
new file mode 100644 (file)
index 0000000..87bf013
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LOCO_IR_NODE_POOL_FORWARD_H__
+#define __LOCO_IR_NODE_POOL_FORWARD_H__
+
+namespace loco
+{
+
+// This forward declaration SHOULD BE aligned with the actual declaration in "NodePool.h".
+class NodePool;
+
+} // namespace loco
+
+#endif // __LOCO_IR_NODE_POOL_FORWARD_H__
diff --git a/compiler/loco/include/loco/IR/NodePool.h b/compiler/loco/include/loco/IR/NodePool.h
new file mode 100644 (file)
index 0000000..4db4caa
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LOCO_IR_NODE_POOL_H__
+#define __LOCO_IR_NODE_POOL_H__
+
+#include "loco/IR/Node.h"
+#include "loco/IR/Graph.forward.h"
+
+#include "loco/ADT/ObjectPool.h"
+
+namespace loco
+{
+
+class NodePool final : public ObjectPool<Node>
+{
+public:
+  friend class Graph;
+
+public:
+  ~NodePool();
+
+public:
+  template <typename Derived, typename... Args> Derived *create(Args &&... args)
+  {
+    std::unique_ptr<Derived> ptr{new Derived(std::forward<Args>(args)...)};
+    ptr->graph(_graph);
+    return ObjectPool<Node>::take<Derived>(std::move(ptr));
+  }
+
+  void destroy(Node *node)
+  {
+    if (!ObjectPool<Node>::erase(node))
+    {
+      throw std::invalid_argument{"node"};
+    }
+  }
+
+private:
+  /// Only "Graph" is permitted to invoke this private method.
+  void graph(Graph *g) { _graph = g; }
+
+private:
+  Graph *_graph = nullptr;
+};
+
+} // namespace loco
+
+#endif // __LOCO_IR_NODE_POOL_H__
index 0837183..e9e2004 100644 (file)
 namespace loco
 {
 
-Graph::NodeContext::~NodeContext()
-{
-  // Drop all the references before deallocation
-  for (uint32_t n = 0; n < size(); ++n)
-  {
-    at(n)->drop();
-  }
-}
-
 std::set<loco::Node *> all_nodes(loco::Graph *g)
 {
   std::set<loco::Node *> res;
index d36cc16..319ee6d 100644 (file)
@@ -117,6 +117,9 @@ TEST(GraphTest, consturctor_with_param_node)
 
   auto test_node = g->nodes()->create<ParamCtorNode>(22, 11.11);
 
+  ASSERT_EQ(test_node->graph(), g.get());
+  ASSERT_EQ(const_cast<const ParamCtorNode *>(test_node)->graph(), g.get());
+
   ASSERT_EQ(test_node->i(), 22);
   ASSERT_FLOAT_EQ(test_node->f(), 11.11);
 
index 61d0931..554543c 100644 (file)
@@ -76,6 +76,14 @@ TEST(NodeTest, replace_with)
   ASSERT_EQ(node_4.in(), &node_2);
 }
 
+TEST(NodeTest, constructor)
+{
+  MockupNode node;
+
+  // graph() SHOULD return nullptr if node is not constructed through "Graph"
+  ASSERT_EQ(node.graph(), nullptr);
+}
+
 TEST(FixedArityNodeTest, constructor)
 {
   struct DerivedNode final : public loco::FixedArityNode<1, loco::Node>
diff --git a/compiler/loco/src/IR/NodePool.cpp b/compiler/loco/src/IR/NodePool.cpp
new file mode 100644 (file)
index 0000000..553f15e
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "loco/IR/NodePool.h"
+
+namespace loco
+{
+
+NodePool::~NodePool()
+{
+  // Drop all the references before deallocation
+  for (uint32_t n = 0; n < size(); ++n)
+  {
+    at(n)->drop();
+  }
+}
+
+} // namespace loco