template<typename A> Statement *Insert(A &&s) {
CHECK(GetInsertionPoint());
- auto *statement{new Statement(GetInsertionPoint(), std::forward<A>(s))};
+ auto *statement{Statement::Create(GetInsertionPoint(), std::forward<A>(s))};
return statement;
}
template<typename A, typename B> QualifiedStmt<A> QualifiedInsert(B &&s) {
CHECK(GetInsertionPoint());
- auto *statement{new Statement(GetInsertionPoint(), std::forward<B>(s))};
- return QualifiedStmt<A>{statement, s};
+ auto *statement{Statement::Create(GetInsertionPoint(), std::forward<B>(s))};
+ return MakeQualifiedStmt<A, B>(statement);
}
template<typename A> Statement *InsertTerminator(A &&s) {
CHECK(GetAddressable(addr));
}
-// Store ctors
-StoreInsn::StoreInsn(QualifiedStmt<Addressable_impl> addr, BasicBlock *val)
- : address_{addr}, value_{val} {
- CHECK(address_);
- CHECK(val);
-}
+// Store ctor
StoreInsn::StoreInsn(QualifiedStmt<Addressable_impl> addr, Value val)
: address_{addr}, value_{val} {
CHECK(address_);
-}
-StoreInsn::StoreInsn(
- QualifiedStmt<Addressable_impl> addr, QualifiedStmt<ApplyExprStmt> val)
- : address_{addr}, value_{val} {
- CHECK(address_);
- CHECK(val);
-}
-StoreInsn::StoreInsn(
- QualifiedStmt<Addressable_impl> addr, QualifiedStmt<Addressable_impl> val)
- : address_{addr}, value_{val} {
- CHECK(address_);
- CHECK(val);
-}
-
-static std::string dumpStoreValue(const StoreInsn::ValueType &v) {
- return std::visit(
- common::visitors{
- [](const Value &v) { return v.dump(); },
- [](const ApplyExprStmt *e) { return FIR::dump(e->expression()); },
- [](const Addressable_impl *e) { return FIR::dump(e->address()); },
- [](const BasicBlock *bb) { return ToString(bb); },
- },
- v);
+ CHECK(!IsNothing(value_));
}
// dump is intended for debugging rather than idiomatic FIR output
return '%' + ToString(&u) + ": load " + insn.address().dump();
},
[](const StoreInsn &insn) {
- std::string value{dumpStoreValue(insn.value())};
+ std::string value{insn.value().dump()};
return "store " + value + " to " +
FIR::dump(insn.address()->address());
},
// Some uses of a Statement should be constrained. These contraints are imposed
// at compile time.
-template<typename A = Stmt_impl> class QualifiedStmt {
+template<typename A> class QualifiedStmt {
public:
QualifiedStmt() = delete;
- template<typename B, std::enable_if_t<std::is_base_of_v<A, B>, int> = 0>
- QualifiedStmt(Statement *stmt, const B &) : stmt{stmt} {}
+ QualifiedStmt(Statement *stmt) : stmt{stmt} {}
// create a stub, where stmt == nullptr
QualifiedStmt(std::nullptr_t) : stmt{nullptr} {}
Statement *stmt;
};
+template<typename A, typename B,
+ std::enable_if_t<std::is_base_of_v<A, B>, int> = 0>
+QualifiedStmt<A> MakeQualifiedStmt(Statement *s) {
+ return QualifiedStmt<A>{s};
+}
+
// Every basic block must end in a terminator
class TerminatorStmt_impl : virtual public Stmt_impl {
public:
// Store value(s) from an applied expression to a location
class StoreInsn : public MemoryStmt_impl {
public:
- using ValueType = std::variant<Value, QualifiedStmt<ApplyExprStmt>,
- QualifiedStmt<Addressable_impl>, BasicBlock *>;
-
- template<typename A>
- static StoreInsn Create(QualifiedStmt<Addressable_impl> addr, A value) {
+ static StoreInsn Create(QualifiedStmt<Addressable_impl> addr, Value value) {
return StoreInsn{addr, value};
}
Addressable_impl *address() const { return address_; }
- ValueType value() const { return value_; }
+ Value value() const { return value_; }
private:
explicit StoreInsn(QualifiedStmt<Addressable_impl> addr, Value val);
- explicit StoreInsn(
- QualifiedStmt<Addressable_impl> addr, QualifiedStmt<ApplyExprStmt> val);
- explicit StoreInsn(QualifiedStmt<Addressable_impl> addr,
- QualifiedStmt<Addressable_impl> val);
- explicit StoreInsn(QualifiedStmt<Addressable_impl> addr, BasicBlock *val);
QualifiedStmt<Addressable_impl> address_;
- ValueType value_;
+ Value value_;
};
// NULLIFY - make pointer object disassociated
public ChildMixin<Statement, BasicBlock>,
public llvm::ilist_node<Statement> {
public:
+ template<typename A> static Statement *Create(BasicBlock *p, A &&t) {
+ return new Statement(p, std::forward<A>(t));
+ }
+ std::string dump() const; // LLVM expected name
+
+ void Dump(std::ostream &os) const { os << dump(); }
+
+private:
template<typename A>
- Statement(BasicBlock *p, A &&t)
+ explicit Statement(BasicBlock *p, A &&t)
: SumTypeMixin{std::forward<A>(t)}, ChildMixin{p} {
parent->insertBefore(this);
}
- std::string dump() const;
};
template<typename A> inline QualifiedStmt<A>::operator A *() const {