#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
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
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;
}
} // 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
#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);
// 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);
// 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);
coco::UnitF ins{&link};
ASSERT_EQ(ins.op(), nullptr);
+ ASSERT_TRUE(ins.reads().empty());
+ ASSERT_TRUE(ins.updates().empty());
}
TEST(IR_UNIT_F, asUnitF)