[tint][ir] Add EnumSet flags to Value and Instruction

Change-Id: I7d03b6b346c19aae5ef8b32e14dcd6ee10c35411
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/139204
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/ir/call.cc b/src/tint/ir/call.cc
index ead6124..cacdaa4 100644
--- a/src/tint/ir/call.cc
+++ b/src/tint/ir/call.cc
@@ -20,7 +20,9 @@
 
 namespace tint::ir {
 
-Call::Call() = default;
+Call::Call() {
+    flags_.Add(Flag::kSequenced);
+}
 
 Call::~Call() = default;
 
diff --git a/src/tint/ir/control_instruction.cc b/src/tint/ir/control_instruction.cc
index 6451622..27daec8 100644
--- a/src/tint/ir/control_instruction.cc
+++ b/src/tint/ir/control_instruction.cc
@@ -18,7 +18,9 @@
 
 namespace tint::ir {
 
-ControlInstruction::~ControlInstruction() = default;
+ControlInstruction::~ControlInstruction() {
+    flags_.Add(Flag::kSequenced);
+}
 
 void ControlInstruction::AddExit(Exit* exit) {
     exits_.Add(exit);
diff --git a/src/tint/ir/instruction.cc b/src/tint/ir/instruction.cc
index e8bc12c..635302f 100644
--- a/src/tint/ir/instruction.cc
+++ b/src/tint/ir/instruction.cc
@@ -34,7 +34,7 @@
         result->SetSource(nullptr);
         result->Destroy();
     }
-    alive_ = false;
+    flags_.Add(Flag::kDead);
 }
 
 void Instruction::InsertBefore(Instruction* before) {
diff --git a/src/tint/ir/instruction.h b/src/tint/ir/instruction.h
index 8145258..5b6a940 100644
--- a/src/tint/ir/instruction.h
+++ b/src/tint/ir/instruction.h
@@ -18,6 +18,7 @@
 #include "src/tint/ir/instruction_result.h"
 #include "src/tint/ir/value.h"
 #include "src/tint/utils/castable.h"
+#include "src/tint/utils/enum_set.h"
 
 // Forward declarations
 namespace tint::ir {
@@ -57,7 +58,11 @@
     virtual void Destroy();
 
     /// @returns true if the Instruction has not been destroyed with Destroy()
-    bool Alive() const { return alive_; }
+    bool Alive() const { return !flags_.Contains(Flag::kDead); }
+
+    /// @returns true if the Instruction is sequenced. Sequenced instructions cannot be implicitly
+    /// reordered with other sequenced instructions.
+    bool Sequenced() const { return flags_.Contains(Flag::kSequenced); }
 
     /// Sets the block that owns this instruction
     /// @param block the new owner block
@@ -92,14 +97,22 @@
     Instruction* prev = nullptr;
 
   protected:
+    /// Flags applied to an Instruction
+    enum class Flag {
+        /// The instruction has been destroyed
+        kDead,
+        /// The instruction must not be reordered with another sequenced instruction
+        kSequenced,
+    };
+
     /// Constructor
     Instruction();
 
     /// The block that owns this instruction
     ir::Block* block_ = nullptr;
 
-  private:
-    bool alive_ = true;
+    /// Bitset of instruction flags
+    utils::EnumSet<Flag> flags_;
 };
 
 }  // namespace tint::ir
diff --git a/src/tint/ir/load.cc b/src/tint/ir/load.cc
index 0918398..ac62f46 100644
--- a/src/tint/ir/load.cc
+++ b/src/tint/ir/load.cc
@@ -22,6 +22,8 @@
 namespace tint::ir {
 
 Load::Load(InstructionResult* result, Value* from) {
+    flags_.Add(Flag::kSequenced);
+
     TINT_ASSERT(IR, from->Type()->Is<type::Pointer>());
     TINT_ASSERT(IR, from && from->Type()->UnwrapPtr() == result->Type());
 
diff --git a/src/tint/ir/store.cc b/src/tint/ir/store.cc
index d1ea611..23b5f835 100644
--- a/src/tint/ir/store.cc
+++ b/src/tint/ir/store.cc
@@ -20,6 +20,8 @@
 namespace tint::ir {
 
 Store::Store(Value* to, Value* from) {
+    flags_.Add(Flag::kSequenced);
+
     AddOperand(Store::kToOperandOffset, to);
     AddOperand(Store::kFromOperandOffset, from);
 }
diff --git a/src/tint/ir/value.cc b/src/tint/ir/value.cc
index 1471681..dd93f4b 100644
--- a/src/tint/ir/value.cc
+++ b/src/tint/ir/value.cc
@@ -28,7 +28,7 @@
 void Value::Destroy() {
     TINT_ASSERT(IR, Alive());
     TINT_ASSERT(IR, Usages().Count() == 0);
-    alive_ = false;
+    flags_.Add(Flag::kDead);
 }
 
 void Value::ReplaceAllUsesWith(std::function<Value*(Usage use)> replacer) {
diff --git a/src/tint/ir/value.h b/src/tint/ir/value.h
index 0efa6d0..1f7f3b5 100644
--- a/src/tint/ir/value.h
+++ b/src/tint/ir/value.h
@@ -64,7 +64,7 @@
     virtual void Destroy();
 
     /// @returns true if the Value has not been destroyed with Destroy()
-    bool Alive() const { return alive_; }
+    bool Alive() const { return !flags_.Contains(Flag::kDead); }
 
     /// Adds a usage of this value.
     /// @param u the usage
@@ -91,8 +91,16 @@
     Value();
 
   private:
+    /// Flags applied to an Value
+    enum class Flag {
+        /// The value has been destroyed
+        kDead,
+    };
+
     utils::Hashset<Usage, 4, Usage::Hasher> uses_;
-    bool alive_ = true;
+
+    /// Bitset of value flags
+    utils::EnumSet<Flag> flags_;
 };
 }  // namespace tint::ir