summaryrefslogtreecommitdiff
path: root/willow/include/willow/IR/Value.h
blob: 1e07fe4a165093ec7781bb64363cc4c3d318c3d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#ifndef _WILLOW_IR_VALUE_HPP
#define _WILLOW_IR_VALUE_HPP

#include <willow/IR/Types.h>

#include <cassert>
#include <string>
#include <string_view>
#include <unordered_map>

namespace willow {

class Instruction;

enum class ValueKind {
  Instruction, ///< the identified result of an instruction
  Parameter,   ///< the named parameter to a function
  Literal,     ///< an anonymous typed literal
};

/// An SSA value that may be used.
class Value {
  ValueKind value_type;
  std::string name;
  Type type;

  // Instructions that use this value
  std::unordered_map<Instruction *, std::size_t> uses;

public:
  virtual ~Value() = default;

  Value(ValueKind valuetype, std::string name, Type type)
      : value_type(valuetype), name(std::move(name)), type(type) {}
  Value(ValueKind valuetype, Type type) : value_type(valuetype), type(type) {}

  bool hasName() const { return !name.empty(); }

  std::string_view getName() const { return name; }
  void setName(std::string name) { this->name = std::move(name); }

  Type getType() const { return type; }
  ValueKind getValueType() const { return value_type; }

  bool isVoid() const { return type.isVoid(); }

  /// Get the instructions that use this value, and the number of times they use
  /// it.
  ///
  /// \return map of Instruction* -> num uses
  std::unordered_map<Instruction *, std::size_t> &getUses() { return uses; }
  const std::unordered_map<Instruction *, std::size_t> &getUses() const {
    return uses;
  }

  void addUse(Instruction *i) {
    auto [it, inserted] = uses.try_emplace(i, 1);

    if (!inserted)
      it->second += 1;
  }

  /// Remove a use of the instruction from te use list.
  void delUse(Instruction *instruction) {
    assert(uses.contains(instruction) && "No uses to remove");
    auto it = uses.find(instruction);
    it->second -= 1;
    if (it->second == 0)
      uses.erase(it);
  }
};

class Parameter : public Value {
public:
  Parameter(std::string name, Type type)
      : Value(ValueKind::Parameter, std::move(name), type) {}
};

} // namespace willow

#endif // _WILLOW_IR_VALUE_HPP