[ir] Spit `instruction` and `value` allocators.

This Cl splits the allocator into one for instructions and one for
values.

Bug: tint:1718
Change-Id: If507ffa261f0f38f58df9738dbb8df2fd55f4ac0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/137481
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index b975fc1..009bea1 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -1268,6 +1268,8 @@
       "ir/if.h",
       "ir/instruction.cc",
       "ir/instruction.h",
+      "ir/instruction_result.cc",
+      "ir/instruction_result.h",
       "ir/load.cc",
       "ir/load.h",
       "ir/location.h",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 3345626..f8286d0 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -772,6 +772,8 @@
     ir/if.h
     ir/instruction.cc
     ir/instruction.h
+    ir/instruction_result.cc
+    ir/instruction_result.h
     ir/load.cc
     ir/load.h
     ir/location.h
diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc
index fcf4b28..6fd1e62 100644
--- a/src/tint/ir/builder.cc
+++ b/src/tint/ir/builder.cc
@@ -55,7 +55,7 @@
 
 ir::Loop* Builder::Loop() {
     return Append(
-        ir.values.Create<ir::Loop>(Block(), MultiInBlock(), MultiInBlock(), MultiInBlock()));
+        ir.instructions.Create<ir::Loop>(Block(), MultiInBlock(), MultiInBlock(), MultiInBlock()));
 }
 
 Block* Builder::Case(ir::Switch* s, utils::VectorRef<Switch::CaseSelector> selectors) {
@@ -70,11 +70,11 @@
 }
 
 ir::Discard* Builder::Discard() {
-    return Append(ir.values.Create<ir::Discard>(ir.Types().void_()));
+    return Append(ir.instructions.Create<ir::Discard>(ir.Types().void_()));
 }
 
 ir::Var* Builder::Var(const type::Pointer* type) {
-    return Append(ir.values.Create<ir::Var>(type));
+    return Append(ir.instructions.Create<ir::Var>(type));
 }
 
 ir::BlockParam* Builder::BlockParam(const type::Type* type) {
@@ -88,13 +88,14 @@
 ir::Swizzle* Builder::Swizzle(const type::Type* type,
                               ir::Value* object,
                               utils::VectorRef<uint32_t> indices) {
-    return Append(ir.values.Create<ir::Swizzle>(type, object, std::move(indices)));
+    return Append(ir.instructions.Create<ir::Swizzle>(type, object, std::move(indices)));
 }
 
 ir::Swizzle* Builder::Swizzle(const type::Type* type,
                               ir::Value* object,
                               std::initializer_list<uint32_t> indices) {
-    return Append(ir.values.Create<ir::Swizzle>(type, object, utils::Vector<uint32_t, 4>(indices)));
+    return Append(
+        ir.instructions.Create<ir::Swizzle>(type, object, utils::Vector<uint32_t, 4>(indices)));
 }
 
 }  // namespace tint::ir
diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h
index 97ab9a8..561ed99 100644
--- a/src/tint/ir/builder.h
+++ b/src/tint/ir/builder.h
@@ -35,6 +35,7 @@
 #include "src/tint/ir/function.h"
 #include "src/tint/ir/function_param.h"
 #include "src/tint/ir/if.h"
+#include "src/tint/ir/instruction_result.h"
 #include "src/tint/ir/load.h"
 #include "src/tint/ir/loop.h"
 #include "src/tint/ir/module.h"
@@ -122,8 +123,8 @@
     /// @returns the flow node
     template <typename T>
     ir::If* If(T&& condition) {
-        return Append(ir.values.Create<ir::If>(Value(std::forward<T>(condition)), Block(), Block(),
-                                               MultiInBlock()));
+        return Append(ir.instructions.Create<ir::If>(Value(std::forward<T>(condition)), Block(),
+                                                     Block(), MultiInBlock()));
     }
 
     /// Creates a loop flow node
@@ -136,7 +137,7 @@
     template <typename T>
     ir::Switch* Switch(T&& condition) {
         return Append(
-            ir.values.Create<ir::Switch>(Value(std::forward<T>(condition)), MultiInBlock()));
+            ir.instructions.Create<ir::Switch>(Value(std::forward<T>(condition)), MultiInBlock()));
     }
 
     /// Creates a case flow node for the given case branch.
@@ -232,8 +233,8 @@
     /// @returns the operation
     template <typename LHS, typename RHS>
     ir::Binary* Binary(enum Binary::Kind kind, const type::Type* type, LHS&& lhs, RHS&& rhs) {
-        return Append(ir.values.Create<ir::Binary>(kind, type, Value(std::forward<LHS>(lhs)),
-                                                   Value(std::forward<RHS>(rhs))));
+        return Append(ir.instructions.Create<ir::Binary>(kind, type, Value(std::forward<LHS>(lhs)),
+                                                         Value(std::forward<RHS>(rhs))));
     }
 
     /// Creates an And operation
@@ -415,7 +416,7 @@
     /// @returns the operation
     template <typename VAL>
     ir::Unary* Unary(enum Unary::Kind kind, const type::Type* type, VAL&& val) {
-        return Append(ir.values.Create<ir::Unary>(kind, type, Value(std::forward<VAL>(val))));
+        return Append(ir.instructions.Create<ir::Unary>(kind, type, Value(std::forward<VAL>(val))));
     }
 
     /// Creates a Complement operation
@@ -451,7 +452,7 @@
     /// @returns the instruction
     template <typename VAL>
     ir::Bitcast* Bitcast(const type::Type* type, VAL&& val) {
-        return Append(ir.values.Create<ir::Bitcast>(type, Value(std::forward<VAL>(val))));
+        return Append(ir.instructions.Create<ir::Bitcast>(type, Value(std::forward<VAL>(val))));
     }
 
     /// Creates a discard instruction
@@ -466,7 +467,7 @@
     template <typename... ARGS>
     ir::UserCall* Call(const type::Type* type, ir::Function* func, ARGS&&... args) {
         return Append(
-            ir.values.Create<ir::UserCall>(type, func, Values(std::forward<ARGS>(args)...)));
+            ir.instructions.Create<ir::UserCall>(type, func, Values(std::forward<ARGS>(args)...)));
     }
 
     /// Creates a builtin call instruction
@@ -476,8 +477,8 @@
     /// @returns the instruction
     template <typename... ARGS>
     ir::BuiltinCall* Call(const type::Type* type, builtin::Function func, ARGS&&... args) {
-        return Append(
-            ir.values.Create<ir::BuiltinCall>(type, func, Values(std::forward<ARGS>(args)...)));
+        return Append(ir.instructions.Create<ir::BuiltinCall>(type, func,
+                                                              Values(std::forward<ARGS>(args)...)));
     }
 
     /// Creates a value conversion instruction
@@ -486,7 +487,7 @@
     /// @returns the instruction
     template <typename VAL>
     ir::Convert* Convert(const type::Type* to, VAL&& val) {
-        return Append(ir.values.Create<ir::Convert>(to, Value(std::forward<VAL>(val))));
+        return Append(ir.instructions.Create<ir::Convert>(to, Value(std::forward<VAL>(val))));
     }
 
     /// Creates a value constructor instruction
@@ -495,7 +496,8 @@
     /// @returns the instruction
     template <typename... ARGS>
     ir::Construct* Construct(const type::Type* type, ARGS&&... args) {
-        return Append(ir.values.Create<ir::Construct>(type, Values(std::forward<ARGS>(args)...)));
+        return Append(
+            ir.instructions.Create<ir::Construct>(type, Values(std::forward<ARGS>(args)...)));
     }
 
     /// Creates a load instruction
@@ -503,7 +505,7 @@
     /// @returns the instruction
     template <typename VAL>
     ir::Load* Load(VAL&& from) {
-        return Append(ir.values.Create<ir::Load>(Value(std::forward<VAL>(from))));
+        return Append(ir.instructions.Create<ir::Load>(Value(std::forward<VAL>(from))));
     }
 
     /// Creates a store instruction
@@ -512,7 +514,7 @@
     /// @returns the instruction
     template <typename ARG>
     ir::Store* Store(ir::Value* to, ARG&& from) {
-        return Append(ir.values.Create<ir::Store>(to, Value(std::forward<ARG>(from))));
+        return Append(ir.instructions.Create<ir::Store>(to, Value(std::forward<ARG>(from))));
     }
 
     /// Creates a new `var` declaration
@@ -523,7 +525,9 @@
     /// Creates a return instruction
     /// @param func the function being returned
     /// @returns the instruction
-    ir::Return* Return(ir::Function* func) { return Append(ir.values.Create<ir::Return>(func)); }
+    ir::Return* Return(ir::Function* func) {
+        return Append(ir.instructions.Create<ir::Return>(func));
+    }
 
     /// Creates a return instruction
     /// @param func the function being returned
@@ -531,7 +535,7 @@
     /// @returns the instruction
     template <typename ARG>
     ir::Return* Return(ir::Function* func, ARG&& value) {
-        return Append(ir.values.Create<ir::Return>(func, Value(std::forward<ARG>(value))));
+        return Append(ir.instructions.Create<ir::Return>(func, Value(std::forward<ARG>(value))));
     }
 
     /// Creates a loop next iteration instruction
@@ -541,7 +545,7 @@
     template <typename... ARGS>
     ir::NextIteration* NextIteration(ir::Loop* loop, ARGS&&... args) {
         return Append(
-            ir.values.Create<ir::NextIteration>(loop, Values(std::forward<ARGS>(args)...)));
+            ir.instructions.Create<ir::NextIteration>(loop, Values(std::forward<ARGS>(args)...)));
     }
 
     /// Creates a loop break-if instruction
@@ -551,8 +555,8 @@
     /// @returns the instruction
     template <typename CONDITION, typename... ARGS>
     ir::BreakIf* BreakIf(CONDITION&& condition, ir::Loop* loop, ARGS&&... args) {
-        return Append(ir.values.Create<ir::BreakIf>(Value(std::forward<CONDITION>(condition)), loop,
-                                                    Values(std::forward<ARGS>(args)...)));
+        return Append(ir.instructions.Create<ir::BreakIf>(
+            Value(std::forward<CONDITION>(condition)), loop, Values(std::forward<ARGS>(args)...)));
     }
 
     /// Creates a continue instruction
@@ -561,7 +565,8 @@
     /// @returns the instruction
     template <typename... ARGS>
     ir::Continue* Continue(ir::Loop* loop, ARGS&&... args) {
-        return Append(ir.values.Create<ir::Continue>(loop, Values(std::forward<ARGS>(args)...)));
+        return Append(
+            ir.instructions.Create<ir::Continue>(loop, Values(std::forward<ARGS>(args)...)));
     }
 
     /// Creates an exit switch instruction
@@ -570,7 +575,8 @@
     /// @returns the instruction
     template <typename... ARGS>
     ir::ExitSwitch* ExitSwitch(ir::Switch* sw, ARGS&&... args) {
-        return Append(ir.values.Create<ir::ExitSwitch>(sw, Values(std::forward<ARGS>(args)...)));
+        return Append(
+            ir.instructions.Create<ir::ExitSwitch>(sw, Values(std::forward<ARGS>(args)...)));
     }
 
     /// Creates an exit loop instruction
@@ -579,7 +585,8 @@
     /// @returns the instruction
     template <typename... ARGS>
     ir::ExitLoop* ExitLoop(ir::Loop* loop, ARGS&&... args) {
-        return Append(ir.values.Create<ir::ExitLoop>(loop, Values(std::forward<ARGS>(args)...)));
+        return Append(
+            ir.instructions.Create<ir::ExitLoop>(loop, Values(std::forward<ARGS>(args)...)));
     }
 
     /// Creates an exit if instruction
@@ -588,7 +595,7 @@
     /// @returns the instruction
     template <typename... ARGS>
     ir::ExitIf* ExitIf(ir::If* i, ARGS&&... args) {
-        return Append(ir.values.Create<ir::ExitIf>(i, Values(std::forward<ARGS>(args)...)));
+        return Append(ir.instructions.Create<ir::ExitIf>(i, Values(std::forward<ARGS>(args)...)));
     }
 
     /// Creates a new `BlockParam`
@@ -608,8 +615,8 @@
     /// @returns the instruction
     template <typename... ARGS>
     ir::Access* Access(const type::Type* type, ir::Value* object, ARGS&&... indices) {
-        return Append(
-            ir.values.Create<ir::Access>(type, object, Values(std::forward<ARGS>(indices)...)));
+        return Append(ir.instructions.Create<ir::Access>(type, object,
+                                                         Values(std::forward<ARGS>(indices)...)));
     }
 
     /// Creates a new `Swizzle`
@@ -634,6 +641,13 @@
     /// @returns the root block
     ir::Block* RootBlock();
 
+    /// Creates a new runtime value
+    /// @param type the return type
+    /// @returns the value
+    ir::InstructionResult* InstructionResult(const type::Type* type) {
+        return ir.values.Create<ir::InstructionResult>(type);
+    }
+
     /// The IR module.
     Module& ir;
 };
diff --git a/src/tint/ir/from_program_test.cc b/src/tint/ir/from_program_test.cc
index 679ec8a..5197e07 100644
--- a/src/tint/ir/from_program_test.cc
+++ b/src/tint/ir/from_program_test.cc
@@ -31,10 +31,10 @@
 /// If multiple flow nodes are found with the type T, then an error is raised and the first is
 /// returned.
 template <typename T>
-T* FindSingleValue(Module& mod) {
+T* FindSingleInstruction(Module& mod) {
     T* found = nullptr;
     size_t count = 0;
-    for (auto* node : mod.values.Objects()) {
+    for (auto* node : mod.instructions.Objects()) {
         if (auto* as = node->As<T>()) {
             count++;
             if (!found) {
@@ -43,7 +43,7 @@
         }
     }
     if (count > 1) {
-        ADD_FAILURE() << "FindSingleValue() found " << count << " nodes of type "
+        ADD_FAILURE() << "FindSingleInstruction() found " << count << " nodes of type "
                       << utils::TypeInfo::Of<T>().name;
     }
     return found;
@@ -135,7 +135,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* if_ = FindSingleValue<ir::If>(m);
+    auto* if_ = FindSingleInstruction<ir::If>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -173,7 +173,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* if_ = FindSingleValue<ir::If>(m);
+    auto* if_ = FindSingleInstruction<ir::If>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -211,7 +211,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* if_ = FindSingleValue<ir::If>(m);
+    auto* if_ = FindSingleInstruction<ir::If>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -249,7 +249,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* if_ = FindSingleValue<ir::If>(m);
+    auto* if_ = FindSingleInstruction<ir::If>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -326,7 +326,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -362,7 +362,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -418,7 +418,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -493,7 +493,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -543,7 +543,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -582,7 +582,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -613,7 +613,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -784,7 +784,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -839,7 +839,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -907,7 +907,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -926,7 +926,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -967,7 +967,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* loop = FindSingleValue<ir::Loop>(m);
+    auto* loop = FindSingleInstruction<ir::Loop>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -1005,7 +1005,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* flow = FindSingleValue<ir::Switch>(m);
+    auto* flow = FindSingleInstruction<ir::Switch>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -1068,7 +1068,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* flow = FindSingleValue<ir::Switch>(m);
+    auto* flow = FindSingleInstruction<ir::Switch>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -1114,7 +1114,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* flow = FindSingleValue<ir::Switch>(m);
+    auto* flow = FindSingleInstruction<ir::Switch>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -1154,7 +1154,7 @@
     ASSERT_TRUE(res) << (!res ? res.Failure() : "");
 
     auto m = res.Move();
-    auto* flow = FindSingleValue<ir::Switch>(m);
+    auto* flow = FindSingleInstruction<ir::Switch>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
@@ -1207,7 +1207,7 @@
 
     auto m = res.Move();
 
-    auto* flow = FindSingleValue<ir::Switch>(m);
+    auto* flow = FindSingleInstruction<ir::Switch>(m);
 
     ASSERT_EQ(1u, m.functions.Length());
 
diff --git a/src/tint/ir/instruction_result.cc b/src/tint/ir/instruction_result.cc
new file mode 100644
index 0000000..39c7dd9
--- /dev/null
+++ b/src/tint/ir/instruction_result.cc
@@ -0,0 +1,28 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/instruction_result.h"
+
+#include "src/tint/ir/constant.h"
+#include "src/tint/ir/instruction.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::ir::InstructionResult);
+
+namespace tint::ir {
+
+InstructionResult::InstructionResult(const type::Type* type) : type_(type) {}
+
+InstructionResult::~InstructionResult() = default;
+
+}  // namespace tint::ir
diff --git a/src/tint/ir/instruction_result.h b/src/tint/ir/instruction_result.h
new file mode 100644
index 0000000..b68f46c
--- /dev/null
+++ b/src/tint/ir/instruction_result.h
@@ -0,0 +1,42 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_IR_INSTRUCTION_RESULT_H_
+#define SRC_TINT_IR_INSTRUCTION_RESULT_H_
+
+#include "src/tint/ir/value.h"
+#include "src/tint/utils/string_stream.h"
+
+namespace tint::ir {
+
+/// An instruction result in the IR.
+class InstructionResult : public utils::Castable<InstructionResult, Value> {
+  public:
+    /// Constructor
+    /// @param type the type of the value
+    explicit InstructionResult(const type::Type* type);
+
+    /// Destructor
+    ~InstructionResult() override;
+
+    /// @returns the type of the value
+    const type::Type* Type() override { return type_; }
+
+  private:
+    const type::Type* type_ = nullptr;
+};
+
+}  // namespace tint::ir
+
+#endif  // SRC_TINT_IR_INSTRUCTION_RESULT_H_
diff --git a/src/tint/ir/module.h b/src/tint/ir/module.h
index 4f33f26..c7a82b4 100644
--- a/src/tint/ir/module.h
+++ b/src/tint/ir/module.h
@@ -76,6 +76,9 @@
     /// The constant value manager
     constant::Manager constant_values;
 
+    /// The instruction allocator
+    utils::BlockAllocator<Instruction> instructions;
+
     /// The value allocator
     utils::BlockAllocator<Value> values;
 
diff --git a/src/tint/ir/operand_instruction.h b/src/tint/ir/operand_instruction.h
index 249d31d..83ad6f2 100644
--- a/src/tint/ir/operand_instruction.h
+++ b/src/tint/ir/operand_instruction.h
@@ -20,8 +20,8 @@
 namespace tint::ir {
 
 /// An instruction in the IR that expects one or more operands.
-/// @tparam N the default number of operands
-/// @tparam R the default number of result values
+/// @tparam N the number of operands before spilling to the heap
+/// @tparam R the number of result values before spilling to the heap
 template <unsigned N, unsigned R>
 class OperandInstruction : public utils::Castable<OperandInstruction<N, R>, Instruction> {
   public:
diff --git a/src/tint/ir/transform/var_for_dynamic_index.cc b/src/tint/ir/transform/var_for_dynamic_index.cc
index b72dc34..ec39c11 100644
--- a/src/tint/ir/transform/var_for_dynamic_index.cc
+++ b/src/tint/ir/transform/var_for_dynamic_index.cc
@@ -101,7 +101,7 @@
 
     // Find the access instructions that need replacing.
     utils::Vector<AccessToReplace, 4> worklist;
-    for (auto* inst : ir->values.Objects()) {
+    for (auto* inst : ir->instructions.Objects()) {
         if (auto* access = inst->As<Access>()) {
             if (auto to_replace = ShouldReplace(access)) {
                 worklist.Push(to_replace.value());