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