1 | /* |
2 | * Copyright 2016 Google Inc. |
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 SKSL_VARIABLE |
9 | #define SKSL_VARIABLE |
10 | |
11 | #include "src/sksl/SkSLPosition.h" |
12 | #include "src/sksl/ir/SkSLModifiers.h" |
13 | #include "src/sksl/ir/SkSLSymbol.h" |
14 | #include "src/sksl/ir/SkSLType.h" |
15 | |
16 | namespace SkSL { |
17 | |
18 | struct Expression; |
19 | |
20 | /** |
21 | * Represents a variable, whether local, global, or a function parameter. This represents the |
22 | * variable itself (the storage location), which is shared between all VariableReferences which |
23 | * read or write that storage location. |
24 | */ |
25 | struct Variable : public Symbol { |
26 | enum Storage { |
27 | kGlobal_Storage, |
28 | kInterfaceBlock_Storage, |
29 | kLocal_Storage, |
30 | kParameter_Storage |
31 | }; |
32 | |
33 | Variable(int offset, Modifiers modifiers, StringFragment name, const Type& type, |
34 | Storage storage, Expression* initialValue = nullptr) |
35 | : INHERITED(offset, kVariable_Kind, name) |
36 | , fModifiers(modifiers) |
37 | , fType(type) |
38 | , fStorage(storage) |
39 | , fInitialValue(initialValue) |
40 | , fReadCount(0) |
41 | , fWriteCount(initialValue ? 1 : 0) {} |
42 | |
43 | ~Variable() override { |
44 | // can't destroy a variable while there are remaining references to it |
45 | if (fInitialValue) { |
46 | --fWriteCount; |
47 | } |
48 | SkASSERT(!fReadCount && !fWriteCount); |
49 | } |
50 | |
51 | #ifdef SK_DEBUG |
52 | virtual String description() const override { |
53 | return fModifiers.description() + fType.fName + " " + fName; |
54 | } |
55 | #endif |
56 | |
57 | bool dead() const { |
58 | if ((fStorage != kLocal_Storage && fReadCount) || |
59 | (fModifiers.fFlags & (Modifiers::kIn_Flag | Modifiers::kOut_Flag | |
60 | Modifiers::kUniform_Flag | Modifiers::kVarying_Flag))) { |
61 | return false; |
62 | } |
63 | return !fWriteCount || |
64 | (!fReadCount && !(fModifiers.fFlags & (Modifiers::kPLS_Flag | |
65 | Modifiers::kPLSOut_Flag))); |
66 | } |
67 | |
68 | mutable Modifiers fModifiers; |
69 | const Type& fType; |
70 | const Storage fStorage; |
71 | |
72 | Expression* fInitialValue = nullptr; |
73 | |
74 | // Tracks how many sites read from the variable. If this is zero for a non-out variable (or |
75 | // becomes zero during optimization), the variable is dead and may be eliminated. |
76 | mutable int fReadCount; |
77 | // Tracks how many sites write to the variable. If this is zero, the variable is dead and may be |
78 | // eliminated. |
79 | mutable int fWriteCount; |
80 | |
81 | typedef Symbol INHERITED; |
82 | }; |
83 | |
84 | } // namespace SkSL |
85 | |
86 | #endif |
87 | |