gfx/angle/src/compiler/intermediate.h

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

mercurial