blob: f80691e3c099b6123038a0faa7626fea6ad002ca [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 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
7//
8// Definition of the in-memory high-level intermediate representation
9// of shaders. This is a tree that parser creates.
10//
11// Nodes in the tree are defined as a hierarchy of classes derived from
12// TIntermNode. Each is a node in a tree. There is no preset branching factor;
13// each node can have it's own type of list of children.
14//
15
16#ifndef __INTERMEDIATE_H
17#define __INTERMEDIATE_H
18
19#include "Common.h"
20#include "Types.h"
21#include "ConstantUnion.h"
22
23//
24// Operators used by the high-level (parse tree) representation.
25//
26enum TOperator {
27 EOpNull, // if in a node, should only mean a node is still being built
28 EOpSequence, // denotes a list of statements, or parameters, etc.
29 EOpFunctionCall,
30 EOpFunction, // For function definition
31 EOpParameters, // an aggregate listing the parameters to a function
32 EOpDeclaration,
33
34 //
35 // Unary operators
36 //
37
38 EOpNegative,
39 EOpLogicalNot,
40 EOpVectorLogicalNot,
41 EOpBitwiseNot,
42
43 EOpPostIncrement,
44 EOpPostDecrement,
45 EOpPreIncrement,
46 EOpPreDecrement,
47
48 EOpConvIntToBool,
49 EOpConvFloatToBool,
50 EOpConvBoolToFloat,
51 EOpConvIntToFloat,
52 EOpConvFloatToInt,
53 EOpConvBoolToInt,
54
55 //
56 // binary operations
57 //
58
59 EOpAdd,
60 EOpSub,
61 EOpMul,
62 EOpDiv,
63 EOpMod,
64 EOpRightShift,
65 EOpLeftShift,
66 EOpAnd,
67 EOpInclusiveOr,
68 EOpExclusiveOr,
69 EOpEqual,
70 EOpNotEqual,
71 EOpVectorEqual,
72 EOpVectorNotEqual,
73 EOpLessThan,
74 EOpGreaterThan,
75 EOpLessThanEqual,
76 EOpGreaterThanEqual,
77 EOpComma,
78
79 EOpVectorTimesScalar,
80 EOpVectorTimesMatrix,
81 EOpMatrixTimesVector,
82 EOpMatrixTimesScalar,
83
84 EOpLogicalOr,
85 EOpLogicalXor,
86 EOpLogicalAnd,
87
88 EOpIndexDirect,
89 EOpIndexIndirect,
90 EOpIndexDirectStruct,
91
92 EOpVectorSwizzle,
93
94 //
95 // Built-in functions potentially mapped to operators
96 //
97
98 EOpRadians,
99 EOpDegrees,
100 EOpSin,
101 EOpCos,
102 EOpTan,
103 EOpAsin,
104 EOpAcos,
105 EOpAtan,
106
107 EOpPow,
108 EOpExp,
109 EOpLog,
110 EOpExp2,
111 EOpLog2,
112 EOpSqrt,
113 EOpInverseSqrt,
114
115 EOpAbs,
116 EOpSign,
117 EOpFloor,
118 EOpCeil,
119 EOpFract,
120 EOpMin,
121 EOpMax,
122 EOpClamp,
123 EOpMix,
124 EOpStep,
125 EOpSmoothStep,
126
127 EOpLength,
128 EOpDistance,
129 EOpDot,
130 EOpCross,
131 EOpNormalize,
132 EOpFaceForward,
133 EOpReflect,
134 EOpRefract,
135
136// EOpDPdx, // Fragment only
137// EOpDPdy, // Fragment only
138// EOpFwidth, // Fragment only
139
140 EOpMatrixTimesMatrix,
141
142 EOpAny,
143 EOpAll,
144
145 EOpItof, // pack/unpack only
146 EOpFtoi, // pack/unpack only
147 EOpSkipPixels, // pack/unpack only
148 EOpReadInput, // unpack only
149 EOpWritePixel, // unpack only
150 EOpBitmapLsb, // unpack only
151 EOpBitmapMsb, // unpack only
152 EOpWriteOutput, // pack only
153 EOpReadPixel, // pack only
154
155 //
156 // Branch
157 //
158
159 EOpKill, // Fragment only
160 EOpReturn,
161 EOpBreak,
162 EOpContinue,
163
164 //
165 // Constructors
166 //
167
168 EOpConstructInt,
169 EOpConstructBool,
170 EOpConstructFloat,
171 EOpConstructVec2,
172 EOpConstructVec3,
173 EOpConstructVec4,
174 EOpConstructBVec2,
175 EOpConstructBVec3,
176 EOpConstructBVec4,
177 EOpConstructIVec2,
178 EOpConstructIVec3,
179 EOpConstructIVec4,
180 EOpConstructMat2,
181 EOpConstructMat3,
182 EOpConstructMat4,
183 EOpConstructStruct,
184
185 //
186 // moves
187 //
188
189 EOpAssign,
190 EOpInitialize,
191 EOpAddAssign,
192 EOpSubAssign,
193 EOpMulAssign,
194 EOpVectorTimesMatrixAssign,
195 EOpVectorTimesScalarAssign,
196 EOpMatrixTimesScalarAssign,
197 EOpMatrixTimesMatrixAssign,
198 EOpDivAssign,
199 EOpModAssign,
200 EOpAndAssign,
201 EOpInclusiveOrAssign,
202 EOpExclusiveOrAssign,
203 EOpLeftShiftAssign,
204 EOpRightShiftAssign,
205
206 //
207 // Array operators
208 //
209
210 EOpArrayLength,
211};
212
213class TIntermTraverser;
214class TIntermAggregate;
215class TIntermBinary;
216class TIntermConstantUnion;
217class TIntermSelection;
218class TIntermTyped;
219class TIntermSymbol;
220class TInfoSink;
221
222//
223// Base class for the tree nodes
224//
225class TIntermNode {
226public:
227 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
228
229 TIntermNode() : line(0) {}
230 virtual TSourceLoc getLine() const { return line; }
231 virtual void setLine(TSourceLoc l) { line = l; }
232 virtual void traverse(TIntermTraverser*) = 0;
233 virtual TIntermTyped* getAsTyped() { return 0; }
234 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
235 virtual TIntermAggregate* getAsAggregate() { return 0; }
236 virtual TIntermBinary* getAsBinaryNode() { return 0; }
237 virtual TIntermSelection* getAsSelectionNode() { return 0; }
238 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
239 virtual ~TIntermNode() { }
240protected:
241 TSourceLoc line;
242};
243
244//
245// This is just to help yacc.
246//
247struct TIntermNodePair {
248 TIntermNode* node1;
249 TIntermNode* node2;
250};
251
252class TIntermSymbol;
253class TIntermBinary;
254
255//
256// Intermediate class for nodes that have a type.
257//
258class TIntermTyped : public TIntermNode {
259public:
260 TIntermTyped(const TType& t) : type(t) { }
261 virtual TIntermTyped* getAsTyped() { return this; }
262 virtual void setType(const TType& t) { type = t; }
263 virtual TType getType() const { return type; }
264 virtual TType* getTypePointer() { return &type; }
265
266 virtual TBasicType getBasicType() const { return type.getBasicType(); }
267 virtual TQualifier getQualifier() const { return type.getQualifier(); }
268 virtual int getNominalSize() const { return type.getNominalSize(); }
269 virtual int getSize() const { return type.getInstanceSize(); }
270 virtual bool isMatrix() const { return type.isMatrix(); }
271 virtual bool isArray() const { return type.isArray(); }
272 virtual bool isVector() const { return type.isVector(); }
273 const char* getBasicString() const { return type.getBasicString(); }
274 const char* getQualifierString() const { return type.getQualifierString(); }
275 TString getCompleteString() const { return type.getCompleteString(); }
276
277protected:
278 TType type;
279};
280
281//
282// Handle for, do-while, and while loops.
283//
284class TIntermLoop : public TIntermNode {
285public:
286 TIntermLoop(TIntermNode *init, TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
287 init(init),
288 body(aBody),
289 test(aTest),
290 terminal(aTerminal),
291 first(testFirst) { }
292 virtual void traverse(TIntermTraverser*);
293 TIntermNode *getInit() { return init; }
294 TIntermNode *getBody() { return body; }
295 TIntermTyped *getTest() { return test; }
296 TIntermTyped *getTerminal() { return terminal; }
297 bool testFirst() { return first; }
298protected:
299 TIntermNode *init;
300 TIntermNode *body; // code to loop over
301 TIntermTyped *test; // exit condition associated with loop, could be 0 for 'for' loops
302 TIntermTyped *terminal; // exists for for-loops
303 bool first; // true for while and for, not for do-while
304};
305
306//
307// Handle break, continue, return, and kill.
308//
309class TIntermBranch : public TIntermNode {
310public:
311 TIntermBranch(TOperator op, TIntermTyped* e) :
312 flowOp(op),
313 expression(e) { }
314 virtual void traverse(TIntermTraverser*);
315 TOperator getFlowOp() { return flowOp; }
316 TIntermTyped* getExpression() { return expression; }
317protected:
318 TOperator flowOp;
319 TIntermTyped* expression; // non-zero except for "return exp;" statements
320};
321
322//
323// Nodes that correspond to symbols or constants in the source code.
324//
325class TIntermSymbol : public TIntermTyped {
326public:
327 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
328 // per process globalpoolallocator, then it causes increased memory usage per compile
329 // it is essential to use "symbol = sym" to assign to symbol
330 TIntermSymbol(int i, const TString& sym, const TType& t) :
331 TIntermTyped(t), id(i) { symbol = sym;}
332 virtual int getId() const { return id; }
333 virtual const TString& getSymbol() const { return symbol; }
334 virtual void traverse(TIntermTraverser*);
335 virtual TIntermSymbol* getAsSymbolNode() { return this; }
336protected:
337 int id;
338 TString symbol;
339};
340
341class TIntermConstantUnion : public TIntermTyped {
342public:
343 TIntermConstantUnion(constUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
344 constUnion* getUnionArrayPointer() const { return unionArrayPointer; }
345 void setUnionArrayPointer(constUnion *c) { unionArrayPointer = c; }
346 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
347 virtual void traverse(TIntermTraverser* );
348 virtual TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
349protected:
350 constUnion *unionArrayPointer;
351};
352
353//
354// Intermediate class for node types that hold operators.
355//
356class TIntermOperator : public TIntermTyped {
357public:
358 TOperator getOp() const { return op; }
359 bool modifiesState() const;
360 bool isConstructor() const;
361 virtual bool promote(TInfoSink&) { return true; }
362protected:
363 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat)), op(o) {}
364 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
365 TOperator op;
366};
367
368//
369// Nodes for all the basic binary math operators.
370//
371class TIntermBinary : public TIntermOperator {
372public:
373 TIntermBinary(TOperator o) : TIntermOperator(o) {}
374 virtual void traverse(TIntermTraverser*);
375 virtual void setLeft(TIntermTyped* n) { left = n; }
376 virtual void setRight(TIntermTyped* n) { right = n; }
377 virtual TIntermTyped* getLeft() const { return left; }
378 virtual TIntermTyped* getRight() const { return right; }
379 virtual TIntermBinary* getAsBinaryNode() { return this; }
380 virtual bool promote(TInfoSink&);
381protected:
382 TIntermTyped* left;
383 TIntermTyped* right;
384};
385
386//
387// Nodes for unary math operators.
388//
389class TIntermUnary : public TIntermOperator {
390public:
391 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
392 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
393 virtual void traverse(TIntermTraverser*);
394 virtual void setOperand(TIntermTyped* o) { operand = o; }
395 virtual TIntermTyped* getOperand() { return operand; }
396 virtual bool promote(TInfoSink&);
397protected:
398 TIntermTyped* operand;
399};
400
401typedef TVector<TIntermNode*> TIntermSequence;
402typedef TVector<int> TQualifierList;
403//
404// Nodes that operate on an arbitrary sized set of children.
405//
406class TIntermAggregate : public TIntermOperator {
407public:
408 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
409 TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
410 ~TIntermAggregate() { delete pragmaTable; }
411 virtual TIntermAggregate* getAsAggregate() { return this; }
412 virtual void setOperator(TOperator o) { op = o; }
413 virtual TIntermSequence& getSequence() { return sequence; }
414 virtual void setName(const TString& n) { name = n; }
415 virtual const TString& getName() const { return name; }
416 virtual void traverse(TIntermTraverser*);
417 virtual void setUserDefined() { userDefined = true; }
418 virtual bool isUserDefined() { return userDefined; }
419 virtual TQualifierList& getQualifier() { return qualifier; }
420 void setOptimize(bool o) { optimize = o; }
421 void setDebug(bool d) { debug = d; }
422 bool getOptimize() { return optimize; }
423 bool getDebug() { return debug; }
424 void addToPragmaTable(const TPragmaTable& pTable);
425 const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
426protected:
427 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
428 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
429 TIntermSequence sequence;
430 TQualifierList qualifier;
431 TString name;
432 bool userDefined; // used for user defined function names
433 bool optimize;
434 bool debug;
435 TPragmaTable *pragmaTable;
436};
437
438//
439// For if tests. Simplified since there is no switch statement.
440//
441class TIntermSelection : public TIntermTyped {
442public:
443 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
444 TIntermTyped(TType(EbtVoid)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
445 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
446 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
447 virtual void traverse(TIntermTraverser*);
448 virtual TIntermNode* getCondition() const { return condition; }
449 virtual TIntermNode* getTrueBlock() const { return trueBlock; }
450 virtual TIntermNode* getFalseBlock() const { return falseBlock; }
451 virtual TIntermSelection* getAsSelectionNode() { return this; }
452protected:
453 TIntermTyped* condition;
454 TIntermNode* trueBlock;
455 TIntermNode* falseBlock;
456};
457
458enum Visit
459{
460 PreVisit,
461 InVisit,
462 PostVisit
463};
464
465//
466// For traversing the tree. User should derive from this,
467// put their traversal specific data in it, and then pass
468// it to a Traverse method.
469//
470// When using this, just fill in the methods for nodes you want visited.
471// Return false from a pre-visit to skip visiting that node's subtree.
472//
473class TIntermTraverser
474{
475public:
476 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
477
478 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
479 preVisit(preVisit),
480 inVisit(inVisit),
481 postVisit(postVisit),
482 rightToLeft(rightToLeft)
483 {
484 depth = 0;
485 }
486
487 virtual void visitSymbol(TIntermSymbol*) {}
488 virtual void visitConstantUnion(TIntermConstantUnion*) {}
489 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
490 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
491 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
492 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
493 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
494 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
495
496 void incrementDepth() {depth++;}
497 void decrementDepth() {depth--;}
498
499 const bool preVisit;
500 const bool inVisit;
501 const bool postVisit;
502 const bool rightToLeft;
503
504protected:
505 int depth;
506};
507
508#endif // __INTERMEDIATE_H