Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 //
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 //
16 #ifndef __INTERMEDIATE_H
17 #define __INTERMEDIATE_H
19 #include "GLSLANG/ShaderLang.h"
21 #include <algorithm>
22 #include "compiler/Common.h"
23 #include "compiler/Types.h"
24 #include "compiler/ConstantUnion.h"
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
36 EOpDeclaration,
37 EOpPrototype,
39 //
40 // Unary operators
41 //
43 EOpNegative,
44 EOpLogicalNot,
45 EOpVectorLogicalNot,
47 EOpPostIncrement,
48 EOpPostDecrement,
49 EOpPreIncrement,
50 EOpPreDecrement,
52 EOpConvIntToBool,
53 EOpConvFloatToBool,
54 EOpConvBoolToFloat,
55 EOpConvIntToFloat,
56 EOpConvFloatToInt,
57 EOpConvBoolToInt,
59 //
60 // binary operations
61 //
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,
77 EOpVectorTimesScalar,
78 EOpVectorTimesMatrix,
79 EOpMatrixTimesVector,
80 EOpMatrixTimesScalar,
82 EOpLogicalOr,
83 EOpLogicalXor,
84 EOpLogicalAnd,
86 EOpIndexDirect,
87 EOpIndexIndirect,
88 EOpIndexDirectStruct,
90 EOpVectorSwizzle,
92 //
93 // Built-in functions potentially mapped to operators
94 //
96 EOpRadians,
97 EOpDegrees,
98 EOpSin,
99 EOpCos,
100 EOpTan,
101 EOpAsin,
102 EOpAcos,
103 EOpAtan,
105 EOpPow,
106 EOpExp,
107 EOpLog,
108 EOpExp2,
109 EOpLog2,
110 EOpSqrt,
111 EOpInverseSqrt,
113 EOpAbs,
114 EOpSign,
115 EOpFloor,
116 EOpCeil,
117 EOpFract,
118 EOpMod,
119 EOpMin,
120 EOpMax,
121 EOpClamp,
122 EOpMix,
123 EOpStep,
124 EOpSmoothStep,
126 EOpLength,
127 EOpDistance,
128 EOpDot,
129 EOpCross,
130 EOpNormalize,
131 EOpFaceForward,
132 EOpReflect,
133 EOpRefract,
135 EOpDFdx, // Fragment only, OES_standard_derivatives extension
136 EOpDFdy, // Fragment only, OES_standard_derivatives extension
137 EOpFwidth, // Fragment only, OES_standard_derivatives extension
139 EOpMatrixTimesMatrix,
141 EOpAny,
142 EOpAll,
144 //
145 // Branch
146 //
148 EOpKill, // Fragment only
149 EOpReturn,
150 EOpBreak,
151 EOpContinue,
153 //
154 // Constructors
155 //
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,
174 //
175 // moves
176 //
178 EOpAssign,
179 EOpInitialize,
180 EOpAddAssign,
181 EOpSubAssign,
182 EOpMulAssign,
183 EOpVectorTimesMatrixAssign,
184 EOpVectorTimesScalarAssign,
185 EOpMatrixTimesScalarAssign,
186 EOpMatrixTimesMatrixAssign,
187 EOpDivAssign
188 };
190 extern const char* getOperatorString(TOperator op);
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;
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() { }
217 const TSourceLoc& getLine() const { return line; }
218 void setLine(const TSourceLoc& l) { line = l; }
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; }
230 protected:
231 TSourceLoc line;
232 };
234 //
235 // This is just to help yacc.
236 //
237 struct TIntermNodePair {
238 TIntermNode* node1;
239 TIntermNode* node2;
240 };
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; }
250 void setType(const TType& t) { type = t; }
251 const TType& getType() const { return type; }
252 TType* getTypePointer() { return &type; }
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(); }
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(); }
267 int totalRegisterCount() const { return type.totalRegisterCount(); }
268 int elementRegisterCount() const { return type.elementRegisterCount(); }
269 int getArraySize() const { return type.getArraySize(); }
271 protected:
272 TType type;
273 };
275 //
276 // Handle for, do-while, and while loops.
277 //
278 enum TLoopType {
279 ELoopFor,
280 ELoopWhile,
281 ELoopDoWhile
282 };
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) { }
296 virtual TIntermLoop* getAsLoopNode() { return this; }
297 virtual void traverse(TIntermTraverser*);
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; }
305 void setUnrollFlag(bool flag) { unrollFlag = flag; }
306 bool getUnrollFlag() { return unrollFlag; }
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
315 bool unrollFlag; // Whether the loop should be unrolled or not.
316 };
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) { }
327 virtual void traverse(TIntermTraverser*);
329 TOperator getFlowOp() { return flowOp; }
330 TIntermTyped* getExpression() { return expression; }
332 protected:
333 TOperator flowOp;
334 TIntermTyped* expression; // non-zero except for "return exp;" statements
335 };
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; }
348 int getId() const { return id; }
349 const TString& getSymbol() const { return symbol; }
351 void setId(int newId) { id = newId; }
352 void setSymbol(const TString& sym) { symbol = sym; }
354 const TString& getOriginalSymbol() const { return originalSymbol; }
356 virtual void traverse(TIntermTraverser*);
357 virtual TIntermSymbol* getAsSymbolNode() { return this; }
359 protected:
360 int id;
361 TString symbol;
362 TString originalSymbol;
363 };
365 class TIntermConstantUnion : public TIntermTyped {
366 public:
367 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
369 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
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; }
375 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
376 virtual void traverse(TIntermTraverser*);
378 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
380 protected:
381 ConstantUnion *unionArrayPointer;
382 };
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; }
392 bool modifiesState() const;
393 bool isConstructor() const;
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 };
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) {}
408 virtual TIntermBinary* getAsBinaryNode() { return this; }
409 virtual void traverse(TIntermTraverser*);
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&);
417 void setAddIndexClamp() { addIndexClamp = true; }
418 bool getAddIndexClamp() { return addIndexClamp; }
420 protected:
421 TIntermTyped* left;
422 TIntermTyped* right;
424 // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
425 bool addIndexClamp;
426 };
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) {}
436 virtual void traverse(TIntermTraverser*);
437 virtual TIntermUnary* getAsUnaryNode() { return this; }
439 void setOperand(TIntermTyped* o) { operand = o; }
440 TIntermTyped* getOperand() { return operand; }
441 bool promote(TInfoSink&);
443 void setUseEmulatedFunction() { useEmulatedFunction = true; }
444 bool getUseEmulatedFunction() { return useEmulatedFunction; }
446 protected:
447 TIntermTyped* operand;
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 };
454 typedef TVector<TIntermNode*> TIntermSequence;
455 typedef TVector<int> TQualifierList;
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() { }
466 virtual TIntermAggregate* getAsAggregate() { return this; }
467 virtual void traverse(TIntermTraverser*);
469 TIntermSequence& getSequence() { return sequence; }
471 void setName(const TString& n) { name = n; }
472 const TString& getName() const { return name; }
474 void setUserDefined() { userDefined = true; }
475 bool isUserDefined() const { return userDefined; }
477 void setOptimize(bool o) { optimize = o; }
478 bool getOptimize() { return optimize; }
479 void setDebug(bool d) { debug = d; }
480 bool getDebug() { return debug; }
482 void setUseEmulatedFunction() { useEmulatedFunction = true; }
483 bool getUseEmulatedFunction() { return useEmulatedFunction; }
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
492 bool optimize;
493 bool debug;
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 };
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) {}
510 virtual void traverse(TIntermTraverser*);
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; }
518 protected:
519 TIntermTyped* condition;
520 TIntermNode* trueBlock;
521 TIntermNode* falseBlock;
522 };
524 enum Visit
525 {
526 PreVisit,
527 InVisit,
528 PostVisit
529 };
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() {};
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;}
561 int getMaxDepth() const {return maxDepth;}
562 void incrementDepth() {depth++; maxDepth = std::max(maxDepth, depth); }
563 void decrementDepth() {depth--;}
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);
569 const bool preVisit;
570 const bool inVisit;
571 const bool postVisit;
572 const bool rightToLeft;
574 protected:
575 int depth;
576 int maxDepth;
577 };
579 #endif // __INTERMEDIATE_H