blob: bdce469baefcaf83b4091cb164771c9423f1d4bd [file] [log] [blame]
Michael Ludwig8f3a8362020-06-29 17:27:00 -04001/*
2 * Copyright 2020 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#ifndef SkSLAnalysis_DEFINED
9#define SkSLAnalysis_DEFINED
10
Brian Osman1298bc42020-06-30 13:39:35 -040011#include "include/private/SkSLSampleUsage.h"
Michael Ludwig8f3a8362020-06-29 17:27:00 -040012#include "src/sksl/SkSLDefines.h"
13
Brian Osman010ce6a2020-10-19 16:34:10 -040014#include <memory>
15
Michael Ludwig8f3a8362020-06-29 17:27:00 -040016namespace SkSL {
17
John Stilesdce4d3e2020-09-25 14:35:13 -040018class ErrorReporter;
Ethan Nicholas1e9f7f32020-10-08 05:28:32 -040019class Expression;
Brian Osman77ba8102021-01-12 17:15:30 -050020class ForStatement;
Brian Osman2e25ff42020-10-15 10:32:04 -040021class FunctionDeclaration;
Ethan Nicholas6f87de72020-10-26 15:06:46 -040022class FunctionDefinition;
Brian Osman0006ad02020-11-18 15:38:39 -050023struct LoadedModule;
Michael Ludwig8f3a8362020-06-29 17:27:00 -040024struct Program;
Ethan Nicholas1e9f7f32020-10-08 05:28:32 -040025class ProgramElement;
Brian Osman010ce6a2020-10-19 16:34:10 -040026class ProgramUsage;
Ethan Nicholas1e9f7f32020-10-08 05:28:32 -040027class Statement;
Ethan Nicholas041fd0a2020-10-07 16:42:04 -040028class Variable;
Ethan Nicholas78686922020-10-08 06:46:27 -040029class VariableReference;
Michael Ludwig8f3a8362020-06-29 17:27:00 -040030
31/**
32 * Provides utilities for analyzing SkSL statically before it's composed into a full program.
33 */
34struct Analysis {
Brian Osman1298bc42020-06-30 13:39:35 -040035 static SampleUsage GetSampleUsage(const Program& program, const Variable& fp);
Michael Ludwig8f3a8362020-06-29 17:27:00 -040036
Brian Osman92aac1e2020-08-05 16:48:58 -040037 static bool ReferencesBuiltin(const Program& program, int builtin);
38
Michael Ludwig8f3a8362020-06-29 17:27:00 -040039 static bool ReferencesSampleCoords(const Program& program);
Brian Osman92aac1e2020-08-05 16:48:58 -040040 static bool ReferencesFragCoords(const Program& program);
Ethan Nicholas6e0fa402020-08-20 14:08:23 -040041
John Stiles9b9415e2020-11-23 14:48:06 -050042 static int NodeCountUpToLimit(const FunctionDefinition& function, int limit);
Ethan Nicholas765d2fe2020-08-26 08:29:55 -040043
Brian Osman010ce6a2020-10-19 16:34:10 -040044 static std::unique_ptr<ProgramUsage> GetUsage(const Program& program);
Brian Osman0006ad02020-11-18 15:38:39 -050045 static std::unique_ptr<ProgramUsage> GetUsage(const LoadedModule& module);
Brian Osman2e25ff42020-10-15 10:32:04 -040046
Ethan Nicholas765d2fe2020-08-26 08:29:55 -040047 static bool StatementWritesToVariable(const Statement& stmt, const Variable& var);
John Stilesb21fac22020-12-04 15:36:49 -050048
49 struct AssignmentInfo {
50 VariableReference* fAssignedVar = nullptr;
51 bool fIsSwizzled = false;
52 };
53 static bool IsAssignable(Expression& expr, AssignmentInfo* info,
John Stilesa976da72020-09-25 23:06:26 -040054 ErrorReporter* errors = nullptr);
John Stilesc30fbca2020-11-19 16:25:49 -050055
56 // A "trivial" expression is one where we'd feel comfortable cloning it multiple times in
57 // the code, without worrying about incurring a performance penalty. Examples:
58 // - true
59 // - 3.14159265
60 // - myIntVariable
61 // - myColor.rgb
62 // - myArray[123]
63 // - myStruct.myField
64 // - half4(0)
65 //
66 // Trivial-ness is stackable. Somewhat large expressions can occasionally make the cut:
67 // - half4(myColor.a)
68 // - myStruct.myArrayField[7].xyz
69 static bool IsTrivialExpression(const Expression& expr);
Brian Osman77ba8102021-01-12 17:15:30 -050070
71 struct UnrollableLoopInfo {
72 const Variable* fIndex;
73 double fStart;
74 double fDelta;
75 int fCount;
76 };
77
78 // Ensures that 'loop' meets the strict requirements of The OpenGL ES Shading Language 1.00,
79 // Appendix A, Section 4.
80 // Information about the loop's structure are placed in outLoopInfo (if not nullptr).
81 // If the function returns false, specific reasons are reported via errors (if not nullptr).
82 static bool ForLoopIsValidForES2(const ForStatement& loop,
83 UnrollableLoopInfo* outLoopInfo,
84 ErrorReporter* errors);
Brian Osmanea485e52021-01-15 13:20:32 -050085
86 static void ValidateIndexingForES2(const ProgramElement& pe, ErrorReporter& errors);
Michael Ludwig8f3a8362020-06-29 17:27:00 -040087};
88
89/**
90 * Utility class to visit every element, statement, and expression in an SkSL program IR.
91 * This is intended for simple analysis and accumulation, where custom visitation behavior is only
92 * needed for a limited set of expression kinds.
93 *
94 * Subclasses should override visitExpression/visitStatement/visitProgramElement as needed and
95 * intercept elements of interest. They can then invoke the base class's function to visit all
96 * sub expressions. They can also choose not to call the base function to arrest recursion, or
97 * implement custom recursion.
98 *
99 * The visit functions return a bool that determines how the default implementation recurses. Once
100 * any visit call returns true, the default behavior stops recursing and propagates true up the
101 * stack.
102 */
103
John Stiles70b82422020-09-30 10:55:12 -0400104template <typename PROG, typename EXPR, typename STMT, typename ELEM>
105class TProgramVisitor {
Michael Ludwig8f3a8362020-06-29 17:27:00 -0400106public:
John Stiles70b82422020-09-30 10:55:12 -0400107 virtual ~TProgramVisitor() = default;
Michael Ludwig8f3a8362020-06-29 17:27:00 -0400108
Michael Ludwig8f3a8362020-06-29 17:27:00 -0400109protected:
John Stiles70b82422020-09-30 10:55:12 -0400110 virtual bool visitExpression(EXPR expression);
111 virtual bool visitStatement(STMT statement);
112 virtual bool visitProgramElement(ELEM programElement);
Michael Ludwig8f3a8362020-06-29 17:27:00 -0400113};
114
John Stiles70b82422020-09-30 10:55:12 -0400115// Squelch bogus Clang warning about template vtables: https://bugs.llvm.org/show_bug.cgi?id=18733
116#if defined(__clang__)
117#pragma clang diagnostic push
118#pragma clang diagnostic ignored "-Wweak-template-vtables"
119#endif
120extern template class TProgramVisitor<const Program&, const Expression&,
121 const Statement&, const ProgramElement&>;
122extern template class TProgramVisitor<Program&, Expression&, Statement&, ProgramElement&>;
123#if defined(__clang__)
124#pragma clang diagnostic pop
125#endif
126
Brian Osman133724c2020-10-28 14:14:39 -0400127class ProgramVisitor : public TProgramVisitor<const Program&,
128 const Expression&,
129 const Statement&,
130 const ProgramElement&> {
131public:
132 bool visit(const Program& program);
133};
134
John Stiles70b82422020-09-30 10:55:12 -0400135using ProgramWriter = TProgramVisitor<Program&, Expression&, Statement&, ProgramElement&>;
136
John Stilesa6841be2020-08-06 14:11:56 -0400137} // namespace SkSL
Michael Ludwig8f3a8362020-06-29 17:27:00 -0400138
139#endif