[ir] Move ir::Builder to hold module reference

This CL moves the module from being owned by the builder, to be passed
into the builder and stored as a reference. This allows the transforms
to create builders based on the same module as needed.

Bug: tint:1718
Change-Id: I4863f368582242626c2a2c6996fd62f053314bb1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/132862
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc
index fe350cd..d8d456a 100644
--- a/src/tint/ir/builder.cc
+++ b/src/tint/ir/builder.cc
@@ -20,9 +20,7 @@
 
 namespace tint::ir {
 
-Builder::Builder() {}
-
-Builder::Builder(Module&& mod) : ir(std::move(mod)) {}
+Builder::Builder(Module& mod) : ir(mod) {}
 
 Builder::~Builder() = default;
 
diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h
index 87a256b..6dd555d 100644
--- a/src/tint/ir/builder.h
+++ b/src/tint/ir/builder.h
@@ -50,10 +50,8 @@
 class Builder {
   public:
     /// Constructor
-    Builder();
-    /// Constructor
     /// @param mod the ir::Module to wrap with this builder
-    explicit Builder(Module&& mod);
+    explicit Builder(Module& mod);
     /// Destructor
     ~Builder();
 
@@ -363,7 +361,7 @@
     ir::Block* CreateRootBlockIfNeeded();
 
     /// The IR module.
-    Module ir;
+    Module& ir;
 };
 
 }  // namespace tint::ir
diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc
index 4ac0c7c..46b4cb3 100644
--- a/src/tint/ir/builder_impl.cc
+++ b/src/tint/ir/builder_impl.cc
@@ -198,7 +198,7 @@
         return utils::Failure;
     }
 
-    return ResultType{std::move(builder.ir)};
+    return ResultType{std::move(mod)};
 }
 
 void BuilderImpl::EmitFunction(const ast::Function* ast_func) {
diff --git a/src/tint/ir/builder_impl.h b/src/tint/ir/builder_impl.h
index f6bed12..a83b76b 100644
--- a/src/tint/ir/builder_impl.h
+++ b/src/tint/ir/builder_impl.h
@@ -209,8 +209,10 @@
     /// The stack of flow control blocks.
     utils::Vector<FlowNode*, 8> flow_stack;
 
+    /// The IR module being built
+    Module mod;
     /// The IR builder being used by the impl.
-    Builder builder;
+    Builder builder{mod};
 
     /// The current flow block for expressions
     Block* current_flow_block = nullptr;
diff --git a/src/tint/writer/spirv/generator_impl_binary_test.cc b/src/tint/writer/spirv/generator_impl_binary_test.cc
index d5cd2bb..3b2f5eb 100644
--- a/src/tint/writer/spirv/generator_impl_binary_test.cc
+++ b/src/tint/writer/spirv/generator_impl_binary_test.cc
@@ -20,13 +20,13 @@
 namespace {
 
 TEST_F(SpvGeneratorImplTest, Binary_Add_I32) {
-    auto* func = CreateFunction();
-    func->name = ir.symbols.Register("foo");
-    func->return_type = ir.types.Get<type::Void>();
+    auto* func = b.CreateFunction();
+    func->name = mod.symbols.Register("foo");
+    func->return_type = mod.types.Get<type::Void>();
     func->start_target->branch.target = func->end_target;
 
-    func->start_target->instructions.Push(CreateBinary(
-        ir::Binary::Kind::kAdd, ir.types.Get<type::I32>(), Constant(1_i), Constant(2_i)));
+    func->start_target->instructions.Push(b.CreateBinary(
+        ir::Binary::Kind::kAdd, mod.types.Get<type::I32>(), b.Constant(1_i), b.Constant(2_i)));
 
     generator_.EmitFunction(func);
     EXPECT_EQ(DumpModule(generator_.Module()), R"(OpName %1 "foo"
@@ -44,13 +44,13 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Binary_Add_U32) {
-    auto* func = CreateFunction();
-    func->name = ir.symbols.Register("foo");
-    func->return_type = ir.types.Get<type::Void>();
+    auto* func = b.CreateFunction();
+    func->name = mod.symbols.Register("foo");
+    func->return_type = mod.types.Get<type::Void>();
     func->start_target->branch.target = func->end_target;
 
-    func->start_target->instructions.Push(CreateBinary(
-        ir::Binary::Kind::kAdd, ir.types.Get<type::U32>(), Constant(1_u), Constant(2_u)));
+    func->start_target->instructions.Push(b.CreateBinary(
+        ir::Binary::Kind::kAdd, mod.types.Get<type::U32>(), b.Constant(1_u), b.Constant(2_u)));
 
     generator_.EmitFunction(func);
     EXPECT_EQ(DumpModule(generator_.Module()), R"(OpName %1 "foo"
@@ -68,13 +68,13 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Binary_Add_F32) {
-    auto* func = CreateFunction();
-    func->name = ir.symbols.Register("foo");
-    func->return_type = ir.types.Get<type::Void>();
+    auto* func = b.CreateFunction();
+    func->name = mod.symbols.Register("foo");
+    func->return_type = mod.types.Get<type::Void>();
     func->start_target->branch.target = func->end_target;
 
-    func->start_target->instructions.Push(CreateBinary(
-        ir::Binary::Kind::kAdd, ir.types.Get<type::F32>(), Constant(1_f), Constant(2_f)));
+    func->start_target->instructions.Push(b.CreateBinary(
+        ir::Binary::Kind::kAdd, mod.types.Get<type::F32>(), b.Constant(1_f), b.Constant(2_f)));
 
     generator_.EmitFunction(func);
     EXPECT_EQ(DumpModule(generator_.Module()), R"(OpName %1 "foo"
@@ -92,16 +92,16 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Binary_Add_Chain) {
-    auto* func = CreateFunction();
-    func->name = ir.symbols.Register("foo");
-    func->return_type = ir.types.Get<type::Void>();
+    auto* func = b.CreateFunction();
+    func->name = mod.symbols.Register("foo");
+    func->return_type = mod.types.Get<type::Void>();
     func->start_target->branch.target = func->end_target;
 
-    auto* a = CreateBinary(ir::Binary::Kind::kAdd, ir.types.Get<type::I32>(), Constant(1_i),
-                           Constant(2_i));
+    auto* a = b.CreateBinary(ir::Binary::Kind::kAdd, mod.types.Get<type::I32>(), b.Constant(1_i),
+                             b.Constant(2_i));
     func->start_target->instructions.Push(a);
     func->start_target->instructions.Push(
-        CreateBinary(ir::Binary::Kind::kAdd, ir.types.Get<type::I32>(), a, a));
+        b.CreateBinary(ir::Binary::Kind::kAdd, mod.types.Get<type::I32>(), a, a));
 
     generator_.EmitFunction(func);
     EXPECT_EQ(DumpModule(generator_.Module()), R"(OpName %1 "foo"
diff --git a/src/tint/writer/spirv/generator_impl_constant_test.cc b/src/tint/writer/spirv/generator_impl_constant_test.cc
index c8d7a10..10244f9 100644
--- a/src/tint/writer/spirv/generator_impl_constant_test.cc
+++ b/src/tint/writer/spirv/generator_impl_constant_test.cc
@@ -18,8 +18,8 @@
 namespace {
 
 TEST_F(SpvGeneratorImplTest, Type_Bool) {
-    generator_.Constant(Constant(true));
-    generator_.Constant(Constant(false));
+    generator_.Constant(b.Constant(true));
+    generator_.Constant(b.Constant(false));
     EXPECT_EQ(DumpTypes(), R"(%2 = OpTypeBool
 %1 = OpConstantTrue %2
 %3 = OpConstantFalse %2
@@ -27,8 +27,8 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Constant_I32) {
-    generator_.Constant(Constant(i32(42)));
-    generator_.Constant(Constant(i32(-1)));
+    generator_.Constant(b.Constant(i32(42)));
+    generator_.Constant(b.Constant(i32(-1)));
     EXPECT_EQ(DumpTypes(), R"(%2 = OpTypeInt 32 1
 %1 = OpConstant %2 42
 %3 = OpConstant %2 -1
@@ -36,8 +36,8 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Constant_U32) {
-    generator_.Constant(Constant(u32(42)));
-    generator_.Constant(Constant(u32(4000000000)));
+    generator_.Constant(b.Constant(u32(42)));
+    generator_.Constant(b.Constant(u32(4000000000)));
     EXPECT_EQ(DumpTypes(), R"(%2 = OpTypeInt 32 0
 %1 = OpConstant %2 42
 %3 = OpConstant %2 4000000000
@@ -45,8 +45,8 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Constant_F32) {
-    generator_.Constant(Constant(f32(42)));
-    generator_.Constant(Constant(f32(-1)));
+    generator_.Constant(b.Constant(f32(42)));
+    generator_.Constant(b.Constant(f32(-1)));
     EXPECT_EQ(DumpTypes(), R"(%2 = OpTypeFloat 32
 %1 = OpConstant %2 42
 %3 = OpConstant %2 -1
@@ -54,8 +54,8 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Constant_F16) {
-    generator_.Constant(Constant(f16(42)));
-    generator_.Constant(Constant(f16(-1)));
+    generator_.Constant(b.Constant(f16(42)));
+    generator_.Constant(b.Constant(f16(-1)));
     EXPECT_EQ(DumpTypes(), R"(%2 = OpTypeFloat 16
 %1 = OpConstant %2 0x1.5p+5
 %3 = OpConstant %2 -0x1p+0
@@ -64,9 +64,9 @@
 
 // Test that we do not emit the same constant more than once.
 TEST_F(SpvGeneratorImplTest, Constant_Deduplicate) {
-    generator_.Constant(Constant(i32(42)));
-    generator_.Constant(Constant(i32(42)));
-    generator_.Constant(Constant(i32(42)));
+    generator_.Constant(b.Constant(i32(42)));
+    generator_.Constant(b.Constant(i32(42)));
+    generator_.Constant(b.Constant(i32(42)));
     EXPECT_EQ(DumpTypes(), R"(%2 = OpTypeInt 32 1
 %1 = OpConstant %2 42
 )");
diff --git a/src/tint/writer/spirv/generator_impl_function_test.cc b/src/tint/writer/spirv/generator_impl_function_test.cc
index a1ce3cc..fd08165 100644
--- a/src/tint/writer/spirv/generator_impl_function_test.cc
+++ b/src/tint/writer/spirv/generator_impl_function_test.cc
@@ -18,9 +18,9 @@
 namespace {
 
 TEST_F(SpvGeneratorImplTest, Function_Empty) {
-    auto* func = CreateFunction();
-    func->name = ir.symbols.Register("foo");
-    func->return_type = ir.types.Get<type::Void>();
+    auto* func = b.CreateFunction();
+    func->name = mod.symbols.Register("foo");
+    func->return_type = mod.types.Get<type::Void>();
     func->start_target->branch.target = func->end_target;
 
     generator_.EmitFunction(func);
@@ -36,8 +36,8 @@
 
 // Test that we do not emit the same function type more than once.
 TEST_F(SpvGeneratorImplTest, Function_DeduplicateType) {
-    auto* func = CreateFunction();
-    func->return_type = ir.types.Get<type::Void>();
+    auto* func = b.CreateFunction();
+    func->return_type = mod.types.Get<type::Void>();
     func->start_target->branch.target = func->end_target;
 
     generator_.EmitFunction(func);
@@ -49,9 +49,9 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Function_EntryPoint_Compute) {
-    auto* func = CreateFunction();
-    func->name = ir.symbols.Register("main");
-    func->return_type = ir.types.Get<type::Void>();
+    auto* func = b.CreateFunction();
+    func->name = mod.symbols.Register("main");
+    func->return_type = mod.types.Get<type::Void>();
     func->pipeline_stage = ir::Function::PipelineStage::kCompute;
     func->workgroup_size = {32, 4, 1};
     func->start_target->branch.target = func->end_target;
@@ -70,9 +70,9 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Function_EntryPoint_Fragment) {
-    auto* func = CreateFunction();
-    func->name = ir.symbols.Register("main");
-    func->return_type = ir.types.Get<type::Void>();
+    auto* func = b.CreateFunction();
+    func->name = mod.symbols.Register("main");
+    func->return_type = mod.types.Get<type::Void>();
     func->pipeline_stage = ir::Function::PipelineStage::kFragment;
     func->start_target->branch.target = func->end_target;
 
@@ -90,9 +90,9 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Function_EntryPoint_Vertex) {
-    auto* func = CreateFunction();
-    func->name = ir.symbols.Register("main");
-    func->return_type = ir.types.Get<type::Void>();
+    auto* func = b.CreateFunction();
+    func->name = mod.symbols.Register("main");
+    func->return_type = mod.types.Get<type::Void>();
     func->pipeline_stage = ir::Function::PipelineStage::kVertex;
     func->start_target->branch.target = func->end_target;
 
@@ -109,23 +109,23 @@
 }
 
 TEST_F(SpvGeneratorImplTest, Function_EntryPoint_Multiple) {
-    auto* f1 = CreateFunction();
-    f1->name = ir.symbols.Register("main1");
-    f1->return_type = ir.types.Get<type::Void>();
+    auto* f1 = b.CreateFunction();
+    f1->name = mod.symbols.Register("main1");
+    f1->return_type = mod.types.Get<type::Void>();
     f1->pipeline_stage = ir::Function::PipelineStage::kCompute;
     f1->workgroup_size = {32, 4, 1};
     f1->start_target->branch.target = f1->end_target;
 
-    auto* f2 = CreateFunction();
-    f2->name = ir.symbols.Register("main2");
-    f2->return_type = ir.types.Get<type::Void>();
+    auto* f2 = b.CreateFunction();
+    f2->name = mod.symbols.Register("main2");
+    f2->return_type = mod.types.Get<type::Void>();
     f2->pipeline_stage = ir::Function::PipelineStage::kCompute;
     f2->workgroup_size = {8, 2, 16};
     f2->start_target->branch.target = f2->end_target;
 
-    auto* f3 = CreateFunction();
-    f3->name = ir.symbols.Register("main3");
-    f3->return_type = ir.types.Get<type::Void>();
+    auto* f3 = b.CreateFunction();
+    f3->name = mod.symbols.Register("main3");
+    f3->return_type = mod.types.Get<type::Void>();
     f3->pipeline_stage = ir::Function::PipelineStage::kFragment;
     f3->start_target->branch.target = f3->end_target;
 
diff --git a/src/tint/writer/spirv/generator_impl_type_test.cc b/src/tint/writer/spirv/generator_impl_type_test.cc
index f8f4734..46c54e8 100644
--- a/src/tint/writer/spirv/generator_impl_type_test.cc
+++ b/src/tint/writer/spirv/generator_impl_type_test.cc
@@ -25,37 +25,37 @@
 namespace {
 
 TEST_F(SpvGeneratorImplTest, Type_Void) {
-    auto id = generator_.Type(ir.types.Get<type::Void>());
+    auto id = generator_.Type(mod.types.Get<type::Void>());
     EXPECT_EQ(id, 1u);
     EXPECT_EQ(DumpTypes(), "%1 = OpTypeVoid\n");
 }
 
 TEST_F(SpvGeneratorImplTest, Type_Bool) {
-    auto id = generator_.Type(ir.types.Get<type::Bool>());
+    auto id = generator_.Type(mod.types.Get<type::Bool>());
     EXPECT_EQ(id, 1u);
     EXPECT_EQ(DumpTypes(), "%1 = OpTypeBool\n");
 }
 
 TEST_F(SpvGeneratorImplTest, Type_I32) {
-    auto id = generator_.Type(ir.types.Get<type::I32>());
+    auto id = generator_.Type(mod.types.Get<type::I32>());
     EXPECT_EQ(id, 1u);
     EXPECT_EQ(DumpTypes(), "%1 = OpTypeInt 32 1\n");
 }
 
 TEST_F(SpvGeneratorImplTest, Type_U32) {
-    auto id = generator_.Type(ir.types.Get<type::U32>());
+    auto id = generator_.Type(mod.types.Get<type::U32>());
     EXPECT_EQ(id, 1u);
     EXPECT_EQ(DumpTypes(), "%1 = OpTypeInt 32 0\n");
 }
 
 TEST_F(SpvGeneratorImplTest, Type_F32) {
-    auto id = generator_.Type(ir.types.Get<type::F32>());
+    auto id = generator_.Type(mod.types.Get<type::F32>());
     EXPECT_EQ(id, 1u);
     EXPECT_EQ(DumpTypes(), "%1 = OpTypeFloat 32\n");
 }
 
 TEST_F(SpvGeneratorImplTest, Type_F16) {
-    auto id = generator_.Type(ir.types.Get<type::F16>());
+    auto id = generator_.Type(mod.types.Get<type::F16>());
     EXPECT_EQ(id, 1u);
     EXPECT_EQ(DumpTypes(), "%1 = OpTypeFloat 16\n");
 }
@@ -108,10 +108,10 @@
 // Test that we can emit multiple types.
 // Includes types with the same opcode but different parameters.
 TEST_F(SpvGeneratorImplTest, Type_Multiple) {
-    EXPECT_EQ(generator_.Type(ir.types.Get<type::I32>()), 1u);
-    EXPECT_EQ(generator_.Type(ir.types.Get<type::U32>()), 2u);
-    EXPECT_EQ(generator_.Type(ir.types.Get<type::F32>()), 3u);
-    EXPECT_EQ(generator_.Type(ir.types.Get<type::F16>()), 4u);
+    EXPECT_EQ(generator_.Type(mod.types.Get<type::I32>()), 1u);
+    EXPECT_EQ(generator_.Type(mod.types.Get<type::U32>()), 2u);
+    EXPECT_EQ(generator_.Type(mod.types.Get<type::F32>()), 3u);
+    EXPECT_EQ(generator_.Type(mod.types.Get<type::F16>()), 4u);
     EXPECT_EQ(DumpTypes(), R"(%1 = OpTypeInt 32 1
 %2 = OpTypeInt 32 0
 %3 = OpTypeFloat 32
@@ -121,7 +121,7 @@
 
 // Test that we do not emit the same type more than once.
 TEST_F(SpvGeneratorImplTest, Type_Deduplicate) {
-    auto* i32 = ir.types.Get<type::I32>();
+    auto* i32 = mod.types.Get<type::I32>();
     EXPECT_EQ(generator_.Type(i32), 1u);
     EXPECT_EQ(generator_.Type(i32), 1u);
     EXPECT_EQ(generator_.Type(i32), 1u);
diff --git a/src/tint/writer/spirv/test_helper_ir.h b/src/tint/writer/spirv/test_helper_ir.h
index 6de6f48..3574645 100644
--- a/src/tint/writer/spirv/test_helper_ir.h
+++ b/src/tint/writer/spirv/test_helper_ir.h
@@ -26,9 +26,14 @@
 
 /// Base helper class for testing the SPIR-V generator implementation.
 template <typename BASE>
-class SpvGeneratorTestHelperBase : public ir::Builder, public BASE {
+class SpvGeneratorTestHelperBase : public BASE {
   public:
-    SpvGeneratorTestHelperBase() : generator_(&ir, false) {}
+    SpvGeneratorTestHelperBase() : generator_(&mod, false) {}
+
+    /// The test module
+    ir::Module mod;
+    /// The test builder
+    ir::Builder b{mod};
 
   protected:
     /// The SPIR-V generator.