2
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
5
//Redistribution and use in source and binary forms, with or without
6
//modification, are permitted provided that the following conditions
9
// Redistributions of source code must retain the above copyright
10
// notice, this list of conditions and the following disclaimer.
12
// Redistributions in binary form must reproduce the above
13
// copyright notice, this list of conditions and the following
14
// disclaimer in the documentation and/or other materials provided
15
// with the distribution.
17
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
18
// contributors may be used to endorse or promote products derived
19
// from this software without specific prior written permission.
21
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
//POSSIBILITY OF SUCH DAMAGE.
36
// Definition of the in-memory high-level intermediate representation
37
// of shaders. This is a tree that parser creates.
39
// Nodes in the tree are defined as a hierarchy of classes derived from
40
// TIntermNode. Each is a node in a tree. There is no preset branching factor;
41
// each node can have it's own type of list of children.
44
#ifndef __INTERMEDIATE_H
45
#define __INTERMEDIATE_H
47
#include "../Include/Common.h"
48
#include "../Include/Types.h"
49
#include "../Include/ConstantUnion.h"
52
// Operators used by the high-level (parse tree) representation.
55
EOpNull, // if in a node, should only mean a node is still being built
56
EOpSequence, // denotes a list of statements, or parameters, etc.
58
EOpFunction, // For function definition
59
EOpParameters, // an aggregate listing the parameters to a function
106
EOpVectorTimesScalar,
107
EOpVectorTimesMatrix,
108
EOpMatrixTimesVector,
109
EOpMatrixTimesScalar,
117
EOpIndexDirectStruct,
122
// Built-in functions potentially mapped to operators
163
EOpDPdx, // Fragment only
164
EOpDPdy, // Fragment only
165
EOpFwidth, // Fragment only
167
EOpMatrixTimesMatrix,
172
EOpItof, // pack/unpack only
173
EOpFtoi, // pack/unpack only
174
EOpSkipPixels, // pack/unpack only
175
EOpReadInput, // unpack only
176
EOpWritePixel, // unpack only
177
EOpBitmapLsb, // unpack only
178
EOpBitmapMsb, // unpack only
179
EOpWriteOutput, // pack only
180
EOpReadPixel, // pack only
186
EOpKill, // Fragment only
220
EOpVectorTimesMatrixAssign,
221
EOpVectorTimesScalarAssign,
222
EOpMatrixTimesScalarAssign,
223
EOpMatrixTimesMatrixAssign,
227
EOpInclusiveOrAssign,
228
EOpExclusiveOrAssign,
233
class TIntermTraverser;
234
class TIntermAggregate;
236
class TIntermConstantUnion;
237
class TIntermSelection;
243
// Base class for the tree nodes
247
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
249
TIntermNode() : line(0) {}
250
virtual TSourceLoc getLine() const { return line; }
251
virtual void setLine(TSourceLoc l) { line = l; }
252
virtual void traverse(TIntermTraverser*) = 0;
253
virtual TIntermTyped* getAsTyped() { return 0; }
254
virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
255
virtual TIntermAggregate* getAsAggregate() { return 0; }
256
virtual TIntermBinary* getAsBinaryNode() { return 0; }
257
virtual TIntermSelection* getAsSelectionNode() { return 0; }
258
virtual TIntermSymbol* getAsSymbolNode() { return 0; }
259
virtual ~TIntermNode() { }
265
// This is just to help yacc.
267
struct TIntermNodePair {
276
// Intermediate class for nodes that have a type.
278
class TIntermTyped : public TIntermNode {
280
TIntermTyped(const TType& t) : type(t) { }
281
virtual TIntermTyped* getAsTyped() { return this; }
282
virtual void setType(const TType& t) { type = t; }
283
virtual TType getType() const { return type; }
284
virtual TType* getTypePointer() { return &type; }
286
virtual TBasicType getBasicType() const { return type.getBasicType(); }
287
virtual TQualifier getQualifier() const { return type.getQualifier(); }
288
virtual int getNominalSize() const { return type.getNominalSize(); }
289
virtual int getSize() const { return type.getInstanceSize(); }
290
virtual bool isMatrix() const { return type.isMatrix(); }
291
virtual bool isArray() const { return type.isArray(); }
292
virtual bool isVector() const { return type.isVector(); }
293
const char* getBasicString() const { return type.getBasicString(); }
294
const char* getQualifierString() const { return type.getQualifierString(); }
295
TString getCompleteString() const { return type.getCompleteString(); }
302
// Handle for, do-while, and while loops.
304
class TIntermLoop : public TIntermNode {
306
TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
311
virtual void traverse(TIntermTraverser*);
312
TIntermNode* getBody() { return body; }
313
TIntermTyped* getTest() { return test; }
314
TIntermTyped* getTerminal() { return terminal; }
315
bool testFirst() { return first; }
317
TIntermNode* body; // code to loop over
318
TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
319
TIntermTyped* terminal; // exists for for-loops
320
bool first; // true for while and for, not for do-while
324
// Handle break, continue, return, and kill.
326
class TIntermBranch : public TIntermNode {
328
TIntermBranch(TOperator op, TIntermTyped* e) :
331
virtual void traverse(TIntermTraverser*);
332
TOperator getFlowOp() { return flowOp; }
333
TIntermTyped* getExpression() { return expression; }
336
TIntermTyped* expression; // non-zero except for "return exp;" statements
340
// Nodes that correspond to symbols or constants in the source code.
342
class TIntermSymbol : public TIntermTyped {
344
// if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
345
// per process globalpoolallocator, then it causes increased memory usage per compile
346
// it is essential to use "symbol = sym" to assign to symbol
347
TIntermSymbol(int i, const TString& sym, const TType& t) :
348
TIntermTyped(t), id(i) { symbol = sym;}
349
virtual int getId() const { return id; }
350
virtual const TString& getSymbol() const { return symbol; }
351
virtual void traverse(TIntermTraverser*);
352
virtual TIntermSymbol* getAsSymbolNode() { return this; }
358
class TIntermConstantUnion : public TIntermTyped {
360
TIntermConstantUnion(constUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
361
constUnion* getUnionArrayPointer() const { return unionArrayPointer; }
362
void setUnionArrayPointer(constUnion *c) { unionArrayPointer = c; }
363
virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
364
virtual void traverse(TIntermTraverser* );
365
virtual TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&, bool);
367
constUnion *unionArrayPointer;
371
// Intermediate class for node types that hold operators.
373
class TIntermOperator : public TIntermTyped {
375
TOperator getOp() { return op; }
376
bool modifiesState() const;
377
bool isConstructor() const;
378
virtual bool promote(TInfoSink&) { return true; }
380
TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat)), op(o) {}
381
TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
386
// Nodes for all the basic binary math operators.
388
class TIntermBinary : public TIntermOperator {
390
TIntermBinary(TOperator o) : TIntermOperator(o) {}
391
virtual void traverse(TIntermTraverser*);
392
virtual void setLeft(TIntermTyped* n) { left = n; }
393
virtual void setRight(TIntermTyped* n) { right = n; }
394
virtual TIntermTyped* getLeft() const { return left; }
395
virtual TIntermTyped* getRight() const { return right; }
396
virtual TIntermBinary* getAsBinaryNode() { return this; }
397
virtual bool promote(TInfoSink&);
404
// Nodes for unary math operators.
406
class TIntermUnary : public TIntermOperator {
408
TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
409
TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
410
virtual void traverse(TIntermTraverser*);
411
virtual void setOperand(TIntermTyped* o) { operand = o; }
412
virtual TIntermTyped* getOperand() { return operand; }
413
virtual bool promote(TInfoSink&);
415
TIntermTyped* operand;
418
typedef TVector<TIntermNode*> TIntermSequence;
419
typedef TVector<int> TQualifierList;
421
// Nodes that operate on an arbitrary sized set of children.
423
class TIntermAggregate : public TIntermOperator {
425
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
426
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
427
~TIntermAggregate() { delete pragmaTable; }
428
virtual TIntermAggregate* getAsAggregate() { return this; }
429
virtual void setOperator(TOperator o) { op = o; }
430
virtual TIntermSequence& getSequence() { return sequence; }
431
virtual void setName(const TString& n) { name = n; }
432
virtual const TString& getName() const { return name; }
433
virtual void traverse(TIntermTraverser*);
434
virtual void setUserDefined() { userDefined = true; }
435
virtual bool isUserDefined() { return userDefined; }
436
virtual TQualifierList& getQualifier() { return qualifier; }
437
void setOptimize(bool o) { optimize = o; }
438
void setDebug(bool d) { debug = d; }
439
bool getOptimize() { return optimize; }
440
bool getDebug() { return debug; }
441
void addToPragmaTable(const TPragmaTable& pTable);
442
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
444
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
445
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
446
TIntermSequence sequence;
447
TQualifierList qualifier;
449
bool userDefined; // used for user defined function names
452
TPragmaTable *pragmaTable;
456
// For if tests. Simplified since there is no switch statement.
458
class TIntermSelection : public TIntermTyped {
460
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
461
TIntermTyped(TType(EbtVoid)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
462
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
463
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
464
virtual void traverse(TIntermTraverser*);
465
virtual TIntermNode* getCondition() const { return condition; }
466
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
467
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
468
virtual TIntermSelection* getAsSelectionNode() { return this; }
470
TIntermTyped* condition;
471
TIntermNode* trueBlock;
472
TIntermNode* falseBlock;
476
// For traversing the tree. User should derive from this,
477
// put their traversal specific data in it, and then pass
478
// it to a Traverse method.
480
// When using this, just fill in the methods for nodes you want visited.
481
// Return false from a pre-visit to skip visiting that node's subtree.
483
class TIntermTraverser {
485
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
489
visitConstantUnion(0),
499
rightToLeft(false) {}
501
void (*visitSymbol)(TIntermSymbol*, TIntermTraverser*);
502
void (*visitConstantUnion)(TIntermConstantUnion*, TIntermTraverser*);
503
bool (*visitBinary)(bool preVisit, TIntermBinary*, TIntermTraverser*);
504
bool (*visitUnary)(bool preVisit, TIntermUnary*, TIntermTraverser*);
505
bool (*visitSelection)(bool preVisit, TIntermSelection*, TIntermTraverser*);
506
bool (*visitAggregate)(bool preVisit, TIntermAggregate*, TIntermTraverser*);
507
bool (*visitLoop)(bool preVisit, TIntermLoop*, TIntermTraverser*);
508
bool (*visitBranch)(bool preVisit, TIntermBranch*, TIntermTraverser*);
516
#endif // __INTERMEDIATE_H