[coco] Require reads and updates for Instr classes (#922)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Wed, 8 Aug 2018 01:00:53 +0000 (10:00 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Wed, 8 Aug 2018 01:00:53 +0000 (10:00 +0900)
This commit requires all of Instr classes to implement reads and updates
methods which returns a set of Bags read/updated during execution.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/coco/core/include/coco/IR/Instr.h
contrib/coco/core/src/IR/Instr.cpp
contrib/coco/core/src/IR/Instr.test.cpp

index 3b094cb..67745b5 100644 (file)
@@ -1,11 +1,14 @@
 #ifndef __COCO_IR_INSTR_H__
 #define __COCO_IR_INSTR_H__
 
+#include "coco/IR/Bag.h"
 #include "coco/IR/Block.forward.h"
 #include "coco/IR/Instr.forward.h"
 
 #include "coco/ADT/DLinkedList.h"
 
+#include <set>
+
 #include <stdexcept>
 
 namespace coco
@@ -111,6 +114,12 @@ public:
 
   void accept(Mutator &m) { return accept(&m); }
   void accept(Mutator &&m) { return accept(&m); }
+
+public:
+  /** @brief Returns a set of bags that Instr reads during execution */
+  virtual std::set<Bag *> reads(void) const = 0;
+  /** @brief Returns a set of bags that Instr updates during execution */
+  virtual std::set<Bag *> updates(void) const = 0;
 };
 
 } // namespace coco
@@ -178,6 +187,10 @@ public:
   UnitF *asUnitF(void) override { return this; }
   const UnitF *asUnitF(void) const override { return this; }
 
+public:
+  std::set<Bag *> reads(void) const override;
+  std::set<Bag *> updates(void) const override;
+
 private:
   Op *_op;
 
index 6e7ba79..b015f9e 100644 (file)
@@ -30,3 +30,51 @@ void FeatureInstr::ofm(FeatureObject *ofm)
 }
 
 } // namespace coco
+
+//
+// UnitF
+//
+#include "coco/IR/Op.h"
+
+namespace
+{
+std::set<coco::Bag *> &operator+=(std::set<coco::Bag *> &res, const coco::Object *o)
+{
+  if (o != nullptr && o->bag() != nullptr)
+  {
+    res.insert(o->bag());
+  }
+  return res;
+}
+} // namespace
+
+namespace coco
+{
+
+std::set<Bag *> UnitF::reads(void) const
+{
+  std::set<Bag *> res;
+
+  res += ifm();
+
+  if (op() != nullptr)
+  {
+    for (auto obj : op()->uses())
+    {
+      res += obj;
+    }
+  }
+
+  return res;
+}
+
+std::set<Bag *> UnitF::updates(void) const
+{
+  std::set<Bag *> res;
+
+  res += ofm();
+
+  return res;
+}
+
+} // namespace coco
index 97d53b8..e11db7e 100644 (file)
@@ -3,10 +3,30 @@
 
 #include <gtest/gtest.h>
 
+namespace
+{
+namespace mock
+{
+struct FeatureInstr : public coco::FeatureInstr
+{
+public:
+  FeatureInstr(const coco::PtrLink<coco::Instr, coco::Block> *ins_link)
+      : coco::FeatureInstr{ins_link}
+  {
+
+  }
+
+public:
+  std::set<coco::Bag *> reads(void) const override { return std::set<coco::Bag *>(); }
+  std::set<coco::Bag *> updates(void) const override { return std::set<coco::Bag *>(); }
+};
+} // namespace mock
+} // namespace
+
 TEST(IR_FEATURE_INSTR, ctor)
 {
   coco::PtrLink<coco::Instr, coco::Block> link;
-  coco::FeatureInstr ins{&link};
+  ::mock::FeatureInstr ins{&link};
 
   // IFM and OFM should be initialized as nullptr
   ASSERT_EQ(ins.ifm(), nullptr);
@@ -23,7 +43,7 @@ TEST(IR_FEATURE_INSTR, ifm_update)
 
   // Test 'FeatureInstr' class
   coco::PtrLink<coco::Instr, coco::Block> link;
-  coco::FeatureInstr ins{&link};
+  ::mock::FeatureInstr ins{&link};
 
   // 'ifm(FeatureObject *)' method should affect 'ifm()' method
   ins.ifm(obj);
@@ -40,7 +60,7 @@ TEST(IR_FEATURE_INSTR, ofm_update)
 
   // Test 'FeatureInstr' class
   coco::PtrLink<coco::Instr, coco::Block> link;
-  coco::FeatureInstr ins{&link};
+  ::mock::FeatureInstr ins{&link};
 
   // 'ofm(FeatureObject *)' method should affect 'ofm()' method
   ins.ofm(obj);
@@ -81,6 +101,8 @@ TEST(IR_UNIT_F, ctor)
   coco::UnitF ins{&link};
 
   ASSERT_EQ(ins.op(), nullptr);
+  ASSERT_TRUE(ins.reads().empty());
+  ASSERT_TRUE(ins.updates().empty());
 }
 
 TEST(IR_UNIT_F, asUnitF)