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
16namespace SkSL {
17
18struct 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 */
25struct 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