1 /* 2 * Copyright 2024 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "include/core/SkSpan.h" 9 #include "src/sksl/SkSLCompiler.h" 10 #include "src/sksl/SkSLDefines.h" 11 #include "src/sksl/ir/SkSLBlock.h" 12 #include "src/sksl/ir/SkSLDoStatement.h" 13 #include "src/sksl/ir/SkSLForStatement.h" 14 #include "src/sksl/ir/SkSLFunctionDefinition.h" 15 #include "src/sksl/ir/SkSLIRNode.h" 16 #include "src/sksl/ir/SkSLIfStatement.h" 17 #include "src/sksl/ir/SkSLNop.h" 18 #include "src/sksl/ir/SkSLProgramElement.h" 19 #include "src/sksl/ir/SkSLStatement.h" 20 #include "src/sksl/transform/SkSLProgramWriter.h" 21 #include "src/sksl/transform/SkSLTransform.h" 22 23 #include <memory> 24 #include <utility> 25 #include <vector> 26 27 namespace SkSL { 28 29 class Expression; 30 eliminate_unnecessary_braces(SkSpan<std::unique_ptr<ProgramElement>> elements)31static void eliminate_unnecessary_braces(SkSpan<std::unique_ptr<ProgramElement>> elements) { 32 class UnnecessaryBraceEliminator : public ProgramWriter { 33 public: 34 bool visitExpressionPtr(std::unique_ptr<Expression>& expr) override { 35 // We don't need to look inside expressions at all. 36 return false; 37 } 38 39 bool visitStatementPtr(std::unique_ptr<Statement>& stmt) override { 40 // Work from the innermost blocks to the outermost. 41 INHERITED::visitStatementPtr(stmt); 42 43 switch (stmt->kind()) { 44 case StatementKind::kIf: { 45 IfStatement& ifStmt = stmt->as<IfStatement>(); 46 EliminateBracesFrom(ifStmt.ifTrue()); 47 EliminateBracesFrom(ifStmt.ifFalse()); 48 break; 49 } 50 case StatementKind::kFor: { 51 ForStatement& forStmt = stmt->as<ForStatement>(); 52 EliminateBracesFrom(forStmt.statement()); 53 break; 54 } 55 case StatementKind::kDo: { 56 DoStatement& doStmt = stmt->as<DoStatement>(); 57 EliminateBracesFrom(doStmt.statement()); 58 break; 59 } 60 default: 61 break; 62 } 63 64 // We always check the entire program. 65 return false; 66 } 67 68 static void EliminateBracesFrom(std::unique_ptr<Statement>& stmt) { 69 if (!stmt || !stmt->is<Block>()) { 70 return; 71 } 72 Block& block = stmt->as<Block>(); 73 std::unique_ptr<Statement>* usefulStmt = nullptr; 74 for (std::unique_ptr<Statement>& childStmt : block.children()) { 75 if (childStmt->isEmpty()) { 76 continue; 77 } 78 if (usefulStmt) { 79 // We found two non-empty statements. We can't eliminate braces from 80 // this block. 81 return; 82 } 83 // We found one non-empty statement. 84 usefulStmt = &childStmt; 85 } 86 87 if (!usefulStmt) { 88 // This block held zero useful statements. Replace the block with a nop. 89 stmt = Nop::Make(); 90 } else { 91 // This block held one useful statement. Replace the block with that statement. 92 stmt = std::move(*usefulStmt); 93 } 94 } 95 96 using INHERITED = ProgramWriter; 97 }; 98 99 for (std::unique_ptr<ProgramElement>& pe : elements) { 100 if (pe->is<FunctionDefinition>()) { 101 UnnecessaryBraceEliminator visitor; 102 visitor.visitStatementPtr(pe->as<FunctionDefinition>().body()); 103 } 104 } 105 } 106 EliminateUnnecessaryBraces(Module & module)107void Transform::EliminateUnnecessaryBraces(Module& module) { 108 return eliminate_unnecessary_braces(SkSpan(module.fElements)); 109 } 110 111 } // namespace SkSL 112