Eliminate unreachable code in dehydrated modules.
At present this has no effect. There isn't any dead path in the built-in
code (as you would hope) and we don't do any sufficiently-interesting
transformations that might cause unreachable code to appear.
Change-Id: I6798ae21f8721cf9f6f61ecb1765c8d8df7a9d0d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/540039
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 29cce65..2211089 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -602,12 +602,13 @@
std::unique_ptr<ProgramUsage> usage = Analysis::GetUsage(module, base);
+ // Remove any unreachable code.
+ Transform::EliminateUnreachableCode(module, usage.get());
+
while (Transform::EliminateDeadLocalVariables(*fContext, module, usage.get())) {
// Removing dead variables may cause more variables to become unreferenced. Try again.
}
- // TODO: run EliminateUnreachableCode pass
-
// Note that we intentionally don't attempt to eliminate unreferenced global variables or
// functions here, since those can be referenced by the finished program even if they're
// unreferenced now. We also don't run the inliner to avoid growing the program; that is done in
diff --git a/src/sksl/transform/BUILD.bazel b/src/sksl/transform/BUILD.bazel
index ef08690..9d1944f 100644
--- a/src/sksl/transform/BUILD.bazel
+++ b/src/sksl/transform/BUILD.bazel
@@ -92,9 +92,11 @@
deps = [
":SkSLProgramWriter_hdr",
":SkSLTransform_hdr",
+ "//include/core:SkSpan_hdr",
"//include/private:SkSLProgramElement_hdr",
"//include/private:SkSLStatement_hdr",
"//include/private:SkTArray_hdr",
+ "//src/sksl:SkSLCompiler_hdr",
"//src/sksl/ir:SkSLFunctionDefinition_hdr",
"//src/sksl/ir:SkSLIfStatement_hdr",
"//src/sksl/ir:SkSLNop_hdr",
diff --git a/src/sksl/transform/SkSLEliminateUnreachableCode.cpp b/src/sksl/transform/SkSLEliminateUnreachableCode.cpp
index 9c9ecc7..2e44912 100644
--- a/src/sksl/transform/SkSLEliminateUnreachableCode.cpp
+++ b/src/sksl/transform/SkSLEliminateUnreachableCode.cpp
@@ -5,9 +5,11 @@
* found in the LICENSE file.
*/
+#include "include/core/SkSpan.h"
#include "include/private/SkSLProgramElement.h"
#include "include/private/SkSLStatement.h"
#include "include/private/SkTArray.h"
+#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/ir/SkSLFunctionDefinition.h"
#include "src/sksl/ir/SkSLIfStatement.h"
#include "src/sksl/ir/SkSLNop.h"
@@ -16,17 +18,16 @@
#include "src/sksl/transform/SkSLTransform.h"
#include <memory>
-#include <vector>
namespace SkSL {
class Expression;
-void Transform::EliminateUnreachableCode(Program& program, ProgramUsage* usage) {
+static void eliminate_unreachable_code(SkSpan<std::unique_ptr<ProgramElement>> elements,
+ ProgramUsage* usage) {
class UnreachableCodeEliminator : public ProgramWriter {
public:
- UnreachableCodeEliminator(ProgramUsage* usage)
- : fUsage(usage) {
+ UnreachableCodeEliminator(ProgramUsage* usage) : fUsage(usage) {
fFoundFunctionExit.push_back(false);
fFoundLoopExit.push_back(false);
}
@@ -41,9 +42,7 @@
// If we already found an exit in this section, anything beyond it is dead code.
if (!stmt->is<Nop>()) {
// Eliminate the dead statement by substituting a Nop.
- if (fUsage) {
- fUsage->remove(stmt.get());
- }
+ fUsage->remove(stmt.get());
stmt = Nop::Make();
}
return false;
@@ -138,7 +137,7 @@
using INHERITED = ProgramWriter;
};
- for (std::unique_ptr<ProgramElement>& pe : program.fOwnedElements) {
+ for (std::unique_ptr<ProgramElement>& pe : elements) {
if (pe->is<FunctionDefinition>()) {
UnreachableCodeEliminator visitor{usage};
visitor.visitStatementPtr(pe->as<FunctionDefinition>().body());
@@ -146,4 +145,12 @@
}
}
+void Transform::EliminateUnreachableCode(LoadedModule& module, ProgramUsage* usage) {
+ return eliminate_unreachable_code(SkMakeSpan(module.fElements), usage);
+}
+
+void Transform::EliminateUnreachableCode(Program& program, ProgramUsage* usage) {
+ return eliminate_unreachable_code(SkMakeSpan(program.fOwnedElements), usage);
+}
+
} // namespace SkSL
diff --git a/src/sksl/transform/SkSLTransform.h b/src/sksl/transform/SkSLTransform.h
index 99fad7c..2bc317d 100644
--- a/src/sksl/transform/SkSLTransform.h
+++ b/src/sksl/transform/SkSLTransform.h
@@ -35,7 +35,8 @@
* Eliminates statements in a block which cannot be reached; for example, a statement
* immediately after a `return` or `continue` can safely be eliminated.
*/
-void EliminateUnreachableCode(Program& program, ProgramUsage* usage = nullptr);
+void EliminateUnreachableCode(LoadedModule& module, ProgramUsage* usage);
+void EliminateUnreachableCode(Program& program, ProgramUsage* usage);
/**
* Eliminates functions in a program which are never called. Returns true if any changes were made.