RetroArch
LiveTraverser.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2016 LunarG, Inc.
3 //
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions
8 // are met:
9 //
10 // Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //
13 // Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following
15 // disclaimer in the documentation and/or other materials provided
16 // with the distribution.
17 //
18 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
19 // contributors may be used to endorse or promote products derived
20 // from this software without specific prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 // POSSIBILITY OF SUCH DAMAGE.
34 //
35 
36 #ifndef _MACHINE_INDEPENDENT_LIVE_TRAVERSER_H
37 #define _MACHINE_INDEPENDENT_LIVE_TRAVERSER_H
38 
39 #pragma once
40 
41 #include "../Include/Common.h"
42 #include "reflection.h"
43 #include "localintermediate.h"
44 
45 #include "gl_types.h"
46 
47 #include <list>
48 #include <unordered_set>
49 
50 namespace glslang {
51 
52 //
53 // The traverser: mostly pass through, except
54 // - processing function-call nodes to push live functions onto the stack of functions to process
55 // - processing selection nodes to trim semantically dead code
56 //
57 // This is in the glslang namespace directly so it can be a friend of TReflection.
58 // This can be derived from to implement reflection database traversers or
59 // binding mappers: anything that wants to traverse the live subset of the tree.
60 //
61 
63 public:
64  TLiveTraverser(const TIntermediate& i, bool traverseAll = false,
65  bool preVisit = true, bool inVisit = false, bool postVisit = false) :
68  { }
69 
70  //
71  // Given a function name, find its subroot in the tree, and push it onto the stack of
72  // functions left to process.
73  //
74  void pushFunction(const TString& name)
75  {
77  for (unsigned int f = 0; f < globals.size(); ++f) {
78  TIntermAggregate* candidate = globals[f]->getAsAggregate();
79  if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
80  functions.push_back(candidate);
81  break;
82  }
83  }
84  }
85 
86  typedef std::list<TIntermAggregate*> TFunctionStack;
88 
89 protected:
90  // To catch which function calls are not dead, and hence which functions must be visited.
91  virtual bool visitAggregate(TVisit, TIntermAggregate* node)
92  {
93  if (!traverseAll)
94  if (node->getOp() == EOpFunctionCall)
95  addFunctionCall(node);
96 
97  return true; // traverse this subtree
98  }
99 
100  // To prune semantically dead paths.
101  virtual bool visitSelection(TVisit /* visit */, TIntermSelection* node)
102  {
103  if (traverseAll)
104  return true; // traverse all code
105 
107  if (constant) {
108  // cull the path that is dead
109  if (constant->getConstArray()[0].getBConst() == true && node->getTrueBlock())
110  node->getTrueBlock()->traverse(this);
111  if (constant->getConstArray()[0].getBConst() == false && node->getFalseBlock())
112  node->getFalseBlock()->traverse(this);
113 
114  return false; // don't traverse any more, we did it all above
115  } else
116  return true; // traverse the whole subtree
117  }
118 
119  // Track live functions as well as uniforms, so that we don't visit dead functions
120  // and only visit each function once.
122  {
123  // // just use the map to ensure we process each function at most once
124  if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
125  liveFunctions.insert(call->getName());
126  pushFunction(call->getName());
127  }
128  }
129 
131  typedef std::unordered_set<TString> TLiveFunctions;
134 
135 private:
136  // prevent copy & copy construct
139 };
140 
141 } // namespace glslang
142 
143 #endif
Definition: intermediate.h:1194
GLuint const GLchar * name
Definition: glext.h:6671
Definition: intermediate.h:1520
const bool inVisit
Definition: intermediate.h:1653
const TIntermediate & intermediate
Definition: LiveTraverser.h:130
virtual bool visitSelection(TVisit, TIntermSelection *node)
Definition: LiveTraverser.h:101
const bool preVisit
Definition: intermediate.h:1652
virtual TIntermNode * getTrueBlock() const
Definition: intermediate.h:1532
Definition: intermediate.h:1610
GLfloat f
Definition: glext.h:8207
Definition: localintermediate.h:210
bool traverseAll
Definition: LiveTraverser.h:133
const bool postVisit
Definition: intermediate.h:1654
const TConstUnionArray & getConstArray() const
Definition: intermediate.h:1197
virtual const TString & getName() const
Definition: intermediate.h:1493
virtual glslang::TIntermAggregate * getAsAggregate()
Definition: intermediate.h:999
virtual glslang::TIntermConstantUnion * getAsConstantUnion()
Definition: intermediate.h:998
TLiveTraverser & operator=(TLiveTraverser &)
TIntermNode * getTreeRoot() const
Definition: localintermediate.h:404
virtual TIntermTyped * getCondition() const
Definition: intermediate.h:1531
Definition: intermediate.h:1482
Definition: arrays.h:46
TLiveTraverser(const TIntermediate &i, bool traverseAll=false, bool preVisit=true, bool inVisit=false, bool postVisit=false)
Definition: LiveTraverser.h:64
TVisit
Definition: intermediate.h:1582
Definition: LiveTraverser.h:62
std::list< TIntermAggregate * > TFunctionStack
Definition: LiveTraverser.h:86
virtual TIntermSequence & getSequence()
Definition: intermediate.h:1490
std::unordered_set< TString > TLiveFunctions
Definition: LiveTraverser.h:131
virtual bool visitAggregate(TVisit, TIntermAggregate *node)
Definition: LiveTraverser.h:91
Definition: intermediate.h:70
virtual TIntermNode * getFalseBlock() const
Definition: intermediate.h:1533
Definition: intermediate.h:71
TFunctionStack functions
Definition: LiveTraverser.h:87
TLiveFunctions liveFunctions
Definition: LiveTraverser.h:132
void pushFunction(const TString &name)
Definition: LiveTraverser.h:74
virtual void traverse(glslang::TIntermTraverser *)=0
TOperator getOp() const
Definition: intermediate.h:1238
any call(F fn, Args &&... args)
Definition: peglib.h:337
void addFunctionCall(TIntermAggregate *call)
Definition: LiveTraverser.h:121
Definition: lobject.h:303