xref: /aosp_15_r20/external/angle/src/compiler/translator/tree_util/IntermNode_util.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // IntermNode_util.h: High-level utilities for creating AST nodes and node hierarchies. Mostly meant
7 // to be used in AST transforms.
8 
9 #ifndef COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
10 #define COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
11 
12 #include "compiler/translator/IntermNode.h"
13 #include "compiler/translator/tree_util/FindFunction.h"
14 
15 namespace sh
16 {
17 
18 class TSymbolTable;
19 class TVariable;
20 
21 TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TFunction &func);
22 TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TFunction &func,
23                                                                 TIntermBlock *functionBody);
24 
25 TIntermTyped *CreateZeroNode(const TType &type);
26 TIntermConstantUnion *CreateFloatNode(float value, TPrecision precision);
27 TIntermConstantUnion *CreateVecNode(const float values[],
28                                     unsigned int vecSize,
29                                     TPrecision precision);
30 TIntermConstantUnion *CreateUVecNode(const unsigned int values[],
31                                      unsigned int vecSize,
32                                      TPrecision precision);
33 TIntermConstantUnion *CreateIndexNode(int index);
34 TIntermConstantUnion *CreateUIntNode(unsigned int value);
35 TIntermConstantUnion *CreateBoolNode(bool value);
36 
37 // Create temporary variable of known type |type|.
38 TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type);
39 
40 // Create temporary variable compatible with user-provide type |type|.
41 // Possibly creates a new type. The qualifer of the new type of the new variable is |qualifier|.
42 TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier);
43 
44 TIntermSymbol *CreateTempSymbolNode(const TVariable *tempVariable);
45 TIntermDeclaration *CreateTempDeclarationNode(const TVariable *tempVariable);
46 TIntermDeclaration *CreateTempInitDeclarationNode(const TVariable *tempVariable,
47                                                   TIntermTyped *initializer);
48 TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTyped *rightNode);
49 
50 TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
51                                const TType *type,
52                                TQualifier qualifier,
53                                TIntermDeclaration **declarationOut);
54 TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
55                                TIntermTyped *initializer,
56                                TQualifier qualifier,
57                                TIntermDeclaration **declarationOut);
58 std::pair<const TVariable *, const TVariable *> DeclareStructure(
59     TIntermBlock *root,
60     TSymbolTable *symbolTable,
61     TFieldList *fieldList,
62     TQualifier qualifier,
63     const TMemoryQualifier &memoryQualifier,
64     uint32_t arraySize,
65     const ImmutableString &structTypeName,
66     const ImmutableString *structInstanceName);
67 const TVariable *DeclareInterfaceBlock(TIntermBlock *root,
68                                        TSymbolTable *symbolTable,
69                                        TFieldList *fieldList,
70                                        TQualifier qualifier,
71                                        const TLayoutQualifier &layoutQualifier,
72                                        const TMemoryQualifier &memoryQualifier,
73                                        uint32_t arraySize,
74                                        const ImmutableString &blockTypeName,
75                                        const ImmutableString &blockVariableName);
76 
77 // If the input node is nullptr, return nullptr.
78 // If the input node is a block node, return it.
79 // If the input node is not a block node, put it inside a block node and return that.
80 TIntermBlock *EnsureBlock(TIntermNode *node);
81 
82 // If the input node is nullptr, return a new block.
83 // If the input node is a block node, return it.
84 // If the input node is not a block node, put it inside a block node and return that.
85 TIntermBlock *EnsureLoopBodyBlock(TIntermNode *node);
86 
87 // Should be called from inside Compiler::compileTreeImpl() where the global level is in scope.
88 TIntermSymbol *ReferenceGlobalVariable(const ImmutableString &name,
89                                        const TSymbolTable &symbolTable);
90 
91 TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
92                                         const TSymbolTable &symbolTable,
93                                         int shaderVersion);
94 
95 TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
96                                             TIntermSequence *arguments,
97                                             const TSymbolTable &symbolTable,
98                                             int shaderVersion);
99 TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
100                                             const std::initializer_list<TIntermNode *> &arguments,
101                                             const TSymbolTable &symbolTable,
102                                             int shaderVersion);
103 TIntermTyped *CreateBuiltInUnaryFunctionCallNode(const char *name,
104                                                  TIntermTyped *argument,
105                                                  const TSymbolTable &symbolTable,
106                                                  int shaderVersion);
107 
GetSwizzleIndex(TVector<int> * indexOut)108 inline void GetSwizzleIndex(TVector<int> *indexOut) {}
109 
110 template <typename T, typename... ArgsT>
GetSwizzleIndex(TVector<int> * indexOut,T arg,ArgsT...args)111 void GetSwizzleIndex(TVector<int> *indexOut, T arg, ArgsT... args)
112 {
113     indexOut->push_back(arg);
114     GetSwizzleIndex(indexOut, args...);
115 }
116 
117 template <typename... ArgsT>
CreateSwizzle(TIntermTyped * reference,ArgsT...args)118 TIntermSwizzle *CreateSwizzle(TIntermTyped *reference, ArgsT... args)
119 {
120     TVector<int> swizzleIndex;
121     GetSwizzleIndex(&swizzleIndex, args...);
122     return new TIntermSwizzle(reference, swizzleIndex);
123 }
124 
125 // Returns true if a block ends in a branch (break, continue, return, etc).  This is only correct
126 // after PruneNoOps, because it expects empty blocks after a branch to have been already pruned,
127 // i.e. a block can only end in a branch if its last statement is a branch or is a block ending in
128 // branch.
129 bool EndsInBranch(TIntermBlock *block);
130 
131 }  // namespace sh
132 
133 #endif  // COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
134