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 | String description() const override { |
52 | return fModifiers.description() + fType.fName + " " + fName; |
53 | } |
54 | |
55 | bool dead() const { |
56 | if ((fStorage != kLocal_Storage && fReadCount) || |
57 | (fModifiers.fFlags & (Modifiers::kIn_Flag | Modifiers::kOut_Flag | |
58 | Modifiers::kUniform_Flag | Modifiers::kVarying_Flag))) { |
59 | return false; |
60 | } |
61 | return !fWriteCount || |
62 | (!fReadCount && !(fModifiers.fFlags & (Modifiers::kPLS_Flag | |
63 | Modifiers::kPLSOut_Flag))); |
64 | } |
65 | |
66 | mutable Modifiers fModifiers; |
67 | const Type& fType; |
68 | const Storage fStorage; |
69 | |
70 | const Expression* fInitialValue = nullptr; |
71 | |
72 | // Tracks how many sites read from the variable. If this is zero for a non-out variable (or |
73 | // becomes zero during optimization), the variable is dead and may be eliminated. |
74 | mutable int fReadCount; |
75 | // Tracks how many sites write to the variable. If this is zero, the variable is dead and may be |
76 | // eliminated. |
77 | mutable int fWriteCount; |
78 | |
79 | typedef Symbol INHERITED; |
80 | }; |
81 | |
82 | } // namespace SkSL |
83 | |
84 | #endif |
85 | |