Speed up intrinsic table registration

Reserve enough memory for overloads, and avoid copies. Opportunistically
avoid copying Source instances in ProgramBuilder API.

Speeds up runs of test_unittests.exe by about 20% (33s to 26s on my
Windows desktop).

Change-Id: I6ba26043d7750eb1f123e29c53d253614974f960
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47060
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/intrinsic_table.cc b/src/intrinsic_table.cc
index 393f05b..f9d19c7 100644
--- a/src/intrinsic_table.cc
+++ b/src/intrinsic_table.cc
@@ -778,7 +778,7 @@
                 Builder* return_type,
                 std::vector<Parameter> parameters) {
     Overload overload{type, return_type, std::move(parameters), {}};
-    overloads_.emplace_back(overload);
+    overloads_.emplace_back(std::move(overload));
   }
 
   /// Registers an overload with the given intrinsic type, return type Matcher /
@@ -791,7 +791,7 @@
                 std::pair<OpenType, Matcher*> open_type_matcher) {
     Overload overload{
         type, return_type, std::move(parameters), {open_type_matcher}};
-    overloads_.emplace_back(overload);
+    overloads_.emplace_back(std::move(overload));
   }
 };
 
@@ -824,6 +824,9 @@
   auto* ptr_vecN_T = ptr(vecN_T);      // ptr<vecN<T>>
   auto* ptr_vecN_f32 = ptr(vecN_f32);  // ptr<vecN<f32>>
 
+  constexpr size_t overloads_reserve_size = 300;
+  overloads_.reserve(overloads_reserve_size);
+
   // Intrinsic overloads are registered with a call to the Register().
   //
   // The best way to explain Register() and the lookup process is by example.
@@ -1252,6 +1255,9 @@
   Register(I::kTextureLoad, vec4_T, {{t, tex_storage_ro_3d_FT},      {coords, vec3_i32},                                                         }); // NOLINT
 
   // clang-format on
+
+  // If this assert trips, increase the reserve size.
+  TINT_ASSERT(overloads_.size() <= overloads_reserve_size);
 }
 
 /// @returns a human readable string representation of the overload
diff --git a/src/program_builder.h b/src/program_builder.h
index 857bd4d..ae197cc 100644
--- a/src/program_builder.h
+++ b/src/program_builder.h
@@ -955,7 +955,8 @@
   /// @param source the source information
   /// @param val the size value
   /// @returns the size decoration pointer
-  ast::StructMemberSizeDecoration* MemberSize(Source source, uint32_t val) {
+  ast::StructMemberSizeDecoration* MemberSize(const Source& source,
+                                              uint32_t val) {
     return create<ast::StructMemberSizeDecoration>(source, val);
   }
 
@@ -970,7 +971,8 @@
   /// @param source the source information
   /// @param val the align value
   /// @returns the align decoration pointer
-  ast::StructMemberAlignDecoration* MemberAlign(Source source, uint32_t val) {
+  ast::StructMemberAlignDecoration* MemberAlign(const Source& source,
+                                                uint32_t val) {
     return create<ast::StructMemberAlignDecoration>(source, val);
   }
 
@@ -992,7 +994,7 @@
   /// decorations
   /// @returns the function pointer
   template <typename NAME>
-  ast::Function* Func(Source source,
+  ast::Function* Func(const Source& source,
                       NAME&& name,
                       ast::VariableList params,
                       type::Type* type,
@@ -1217,7 +1219,7 @@
   /// @param source the source information
   /// @param builtin the builtin value
   /// @returns the builtin decoration pointer
-  ast::BuiltinDecoration* Builtin(Source source, ast::Builtin builtin) {
+  ast::BuiltinDecoration* Builtin(const Source& source, ast::Builtin builtin) {
     return create<ast::BuiltinDecoration>(source, builtin);
   }
 
@@ -1232,7 +1234,7 @@
   /// @param source the source information
   /// @param location the location value
   /// @returns the location decoration pointer
-  ast::LocationDecoration* Location(Source source, uint32_t location) {
+  ast::LocationDecoration* Location(const Source& source, uint32_t location) {
     return create<ast::LocationDecoration>(source, location);
   }
 
@@ -1247,7 +1249,7 @@
   /// @param source the source information
   /// @param stage the pipeline stage
   /// @returns the stage decoration pointer
-  ast::StageDecoration* Stage(Source source, ast::PipelineStage stage) {
+  ast::StageDecoration* Stage(const Source& source, ast::PipelineStage stage) {
     return create<ast::StageDecoration>(source, stage);
   }