optimizations: Implement transform::ShouldRun()

This change adds an override for Transform::ShouldRun() for many of the transforms that can trivially detect whether running would be a no-op or not. Most programs do not require all the transforms to be run, and by skipping those that are not needed, significant performance wins can be had.

This change also removes Transform::Requires() and Program::HasTransformApplied(). This makes little sense now that transforms can be skipped, and the usefulness of this information has been severely reduced since the introduction of transforms that need to be run more than once.
Instread, just document on the transform class what the expectations are.

Issue: tint:1383
Change-Id: I1a6f27cc4ba61ca1475a4ba912c465db619f76c7
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/77121
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/transform/calculate_array_length_test.cc b/src/transform/calculate_array_length_test.cc
index 88643ae..cebb276 100644
--- a/src/transform/calculate_array_length_test.cc
+++ b/src/transform/calculate_array_length_test.cc
@@ -24,16 +24,45 @@
 
 using CalculateArrayLengthTest = TransformTest;
 
-TEST_F(CalculateArrayLengthTest, Error_MissingCalculateArrayLength) {
-  auto* src = "";
+TEST_F(CalculateArrayLengthTest, ShouldRunEmptyModule) {
+  auto* src = R"()";
 
-  auto* expect =
-      "error: tint::transform::CalculateArrayLength depends on "
-      "tint::transform::SimplifyPointers but the dependency was not run";
+  EXPECT_FALSE(ShouldRun<CalculateArrayLength>(src));
+}
 
-  auto got = Run<CalculateArrayLength>(src);
+TEST_F(CalculateArrayLengthTest, ShouldRunNoArrayLength) {
+  auto* src = R"(
+struct SB {
+  x : i32;
+  arr : array<i32>;
+};
 
-  EXPECT_EQ(expect, str(got));
+[[group(0), binding(0)]] var<storage, read> sb : SB;
+
+[[stage(compute), workgroup_size(1)]]
+fn main() {
+}
+)";
+
+  EXPECT_FALSE(ShouldRun<CalculateArrayLength>(src));
+}
+
+TEST_F(CalculateArrayLengthTest, ShouldRunWithArrayLength) {
+  auto* src = R"(
+struct SB {
+  x : i32;
+  arr : array<i32>;
+};
+
+[[group(0), binding(0)]] var<storage, read> sb : SB;
+
+[[stage(compute), workgroup_size(1)]]
+fn main() {
+  var len : u32 = arrayLength(&sb.arr);
+}
+)";
+
+  EXPECT_TRUE(ShouldRun<CalculateArrayLength>(src));
 }
 
 TEST_F(CalculateArrayLengthTest, Basic) {