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 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