3 #include <utils/Assert.h>
9 #include <unordered_set>
11 #include "tir/Context.h"
27 valueID_{ctx.getNextValueID()} {}
28 tir::
Context& ctx() {
return ctx_; }
29 auto users() {
return std::views::all(users_); }
30 auto users()
const {
return std::views::all(users_); }
31 Type* type()
const {
return type_; }
32 void addUser(
User* user) { users_.insert(user); }
33 void removeUser(
User* user) { users_.erase(user); }
34 std::string_view name()
const {
return name_.value(); }
35 auto nameOpt()
const {
return name_.value(); }
36 void replaceAllUsesWith(
Value* newValue);
37 void setName(std::string_view name) {
38 name_ = std::pmr::string{name, ctx_.alloc()};
40 std::ostream& printName(std::ostream& os)
const {
42 if(name_) os << name_.value() <<
".";
46 virtual std::ostream& print(std::ostream&)
const = 0;
48 virtual ~Value() =
default;
52 tir::
Type*
const type_;
53 std::pmr::unordered_set<
User*> users_;
54 std::optional<std::pmr::string> name_;
65 auto children()
const {
return std::views::all(children_); }
66 auto numChildren()
const {
return children_.size(); }
67 Value* getChild(
unsigned idx)
const {
68 assert(idx < numChildren() &&
"Index out of bounds");
69 return children_[idx];
73 void addChild(
Value* operand) {
74 children_.push_back(operand);
75 operand->addUser(
this);
77 void replaceChild(
unsigned idx,
Value* operand) {
78 assert(idx < numChildren() &&
"Index out of bounds");
79 children_[idx]->removeUser(
this);
80 children_[idx] = operand;
81 operand->addUser(
this);
85 for(
auto child : children_) {
86 child->removeUser(
this);
89 bool isDestroyed()
const {
return destroyed_; }
92 std::pmr::vector<
Value*> children_;
93 bool destroyed_ =
false;
96 std::ostream& operator<<(std::ostream& os,
const Value& val);