From 4f4689fd58d685a894c1ac6c7d79a57fc86a228c Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=B0=95=EC=A2=85=ED=98=84/On-Device=20Lab=28SR=29/Staff?= =?utf8?q?=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Mon, 29 Jul 2019 08:37:41 +0900 Subject: [PATCH] [loco] Support traversal to Graph from Node (#5910) This commit extends Node class to provide "graph" method which returns a pointer to associated Graph object. Signed-off-by: Jonghyun Park --- compiler/loco/include/loco/IR/Graph.forward.h | 28 +++++++++++ compiler/loco/include/loco/IR/Graph.h | 32 +++++------- compiler/loco/include/loco/IR/Node.h | 22 +++++++++ compiler/loco/include/loco/IR/NodePool.forward.h | 28 +++++++++++ compiler/loco/include/loco/IR/NodePool.h | 62 ++++++++++++++++++++++++ compiler/loco/src/IR/Graph.cpp | 9 ---- compiler/loco/src/IR/Graph.test.cpp | 3 ++ compiler/loco/src/IR/Node.test.cpp | 8 +++ compiler/loco/src/IR/NodePool.cpp | 31 ++++++++++++ 9 files changed, 193 insertions(+), 30 deletions(-) create mode 100644 compiler/loco/include/loco/IR/Graph.forward.h create mode 100644 compiler/loco/include/loco/IR/NodePool.forward.h create mode 100644 compiler/loco/include/loco/IR/NodePool.h create mode 100644 compiler/loco/src/IR/NodePool.cpp diff --git a/compiler/loco/include/loco/IR/Graph.forward.h b/compiler/loco/include/loco/IR/Graph.forward.h new file mode 100644 index 0000000..2a43be9 --- /dev/null +++ b/compiler/loco/include/loco/IR/Graph.forward.h @@ -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__ diff --git a/compiler/loco/include/loco/IR/Graph.h b/compiler/loco/include/loco/IR/Graph.h index 4163f47..9b98c0d 100644 --- a/compiler/loco/include/loco/IR/Graph.h +++ b/compiler/loco/include/loco/IR/Graph.h @@ -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 - { - public: - ~NodeContext(); - - public: - template Derived *create(Args &&... args) - { - std::unique_ptr ptr{new Derived(std::forward(args)...)}; - return ObjectPool::take(std::move(ptr)); - } - - void destroy(Node *node) - { - if (!ObjectPool::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; diff --git a/compiler/loco/include/loco/IR/Node.h b/compiler/loco/include/loco/IR/Node.h index 2d35c0a..fd9104e 100644 --- a/compiler/loco/include/loco/IR/Node.h +++ b/compiler/loco/include/loco/IR/Node.h @@ -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 #include @@ -52,6 +54,7 @@ class Node : public AnnotatedItem public: friend class Use; friend class Subst; + friend class NodePool; friend std::set 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 index 0000000..87bf013 --- /dev/null +++ b/compiler/loco/include/loco/IR/NodePool.forward.h @@ -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 index 0000000..4db4caa --- /dev/null +++ b/compiler/loco/include/loco/IR/NodePool.h @@ -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 +{ +public: + friend class Graph; + +public: + ~NodePool(); + +public: + template Derived *create(Args &&... args) + { + std::unique_ptr ptr{new Derived(std::forward(args)...)}; + ptr->graph(_graph); + return ObjectPool::take(std::move(ptr)); + } + + void destroy(Node *node) + { + if (!ObjectPool::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__ diff --git a/compiler/loco/src/IR/Graph.cpp b/compiler/loco/src/IR/Graph.cpp index 0837183..e9e2004 100644 --- a/compiler/loco/src/IR/Graph.cpp +++ b/compiler/loco/src/IR/Graph.cpp @@ -19,15 +19,6 @@ namespace loco { -Graph::NodeContext::~NodeContext() -{ - // Drop all the references before deallocation - for (uint32_t n = 0; n < size(); ++n) - { - at(n)->drop(); - } -} - std::set all_nodes(loco::Graph *g) { std::set res; diff --git a/compiler/loco/src/IR/Graph.test.cpp b/compiler/loco/src/IR/Graph.test.cpp index d36cc16..319ee6d 100644 --- a/compiler/loco/src/IR/Graph.test.cpp +++ b/compiler/loco/src/IR/Graph.test.cpp @@ -117,6 +117,9 @@ TEST(GraphTest, consturctor_with_param_node) auto test_node = g->nodes()->create(22, 11.11); + ASSERT_EQ(test_node->graph(), g.get()); + ASSERT_EQ(const_cast(test_node)->graph(), g.get()); + ASSERT_EQ(test_node->i(), 22); ASSERT_FLOAT_EQ(test_node->f(), 11.11); diff --git a/compiler/loco/src/IR/Node.test.cpp b/compiler/loco/src/IR/Node.test.cpp index 61d0931..554543c 100644 --- a/compiler/loco/src/IR/Node.test.cpp +++ b/compiler/loco/src/IR/Node.test.cpp @@ -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 index 0000000..553f15e --- /dev/null +++ b/compiler/loco/src/IR/NodePool.cpp @@ -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 -- 2.7.4