Home | History | Annotate | Download | only in compiler
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "intermediate.h"
     16 
     17 //
     18 // Traverse the intermediate representation tree, and
     19 // call a node type specific function for each node.
     20 // Done recursively through the member function Traverse().
     21 // Node types can be skipped if their function to call is 0,
     22 // but their subtree will still be traversed.
     23 // Nodes with children can have their whole subtree skipped
     24 // if preVisit is turned on and the type specific function
     25 // returns false.
     26 //
     27 // preVisit, postVisit, and rightToLeft control what order
     28 // nodes are visited in.
     29 //
     30 
     31 //
     32 // Traversal functions for terminals are straighforward....
     33 //
     34 void TIntermSymbol::traverse(TIntermTraverser* it)
     35 {
     36 	it->visitSymbol(this);
     37 }
     38 
     39 void TIntermConstantUnion::traverse(TIntermTraverser* it)
     40 {
     41 	it->visitConstantUnion(this);
     42 }
     43 
     44 //
     45 // Traverse a binary node.
     46 //
     47 void TIntermBinary::traverse(TIntermTraverser* it)
     48 {
     49 	bool visit = true;
     50 
     51 	//
     52 	// visit the node before children if pre-visiting.
     53 	//
     54 	if(it->preVisit)
     55 	{
     56 		visit = it->visitBinary(PreVisit, this);
     57 	}
     58 
     59 	//
     60 	// Visit the children, in the right order.
     61 	//
     62 	if(visit)
     63 	{
     64 		it->incrementDepth(this);
     65 
     66 		if(it->rightToLeft)
     67 		{
     68 			if(right)
     69 			{
     70 				right->traverse(it);
     71 			}
     72 
     73 			if(it->inVisit)
     74 			{
     75 				visit = it->visitBinary(InVisit, this);
     76 			}
     77 
     78 			if(visit && left)
     79 			{
     80 				left->traverse(it);
     81 			}
     82 		}
     83 		else
     84 		{
     85 			if(left)
     86 			{
     87 				left->traverse(it);
     88 			}
     89 
     90 			if(it->inVisit)
     91 			{
     92 				visit = it->visitBinary(InVisit, this);
     93 			}
     94 
     95 			if(visit && right)
     96 			{
     97 				right->traverse(it);
     98 			}
     99 		}
    100 
    101 		it->decrementDepth();
    102 	}
    103 
    104 	//
    105 	// Visit the node after the children, if requested and the traversal
    106 	// hasn't been cancelled yet.
    107 	//
    108 	if(visit && it->postVisit)
    109 	{
    110 		it->visitBinary(PostVisit, this);
    111 	}
    112 }
    113 
    114 //
    115 // Traverse a unary node.  Same comments in binary node apply here.
    116 //
    117 void TIntermUnary::traverse(TIntermTraverser* it)
    118 {
    119 	bool visit = true;
    120 
    121 	if (it->preVisit)
    122 		visit = it->visitUnary(PreVisit, this);
    123 
    124 	if (visit) {
    125 		it->incrementDepth(this);
    126 		operand->traverse(it);
    127 		it->decrementDepth();
    128 	}
    129 
    130 	if (visit && it->postVisit)
    131 		it->visitUnary(PostVisit, this);
    132 }
    133 
    134 //
    135 // Traverse an aggregate node.  Same comments in binary node apply here.
    136 //
    137 void TIntermAggregate::traverse(TIntermTraverser* it)
    138 {
    139 	bool visit = true;
    140 
    141 	if(it->preVisit)
    142 	{
    143 		visit = it->visitAggregate(PreVisit, this);
    144 	}
    145 
    146 	if(visit)
    147 	{
    148 		it->incrementDepth(this);
    149 
    150 		if(it->rightToLeft)
    151 		{
    152 			for(TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++)
    153 			{
    154 				(*sit)->traverse(it);
    155 
    156 				if(visit && it->inVisit)
    157 				{
    158 					if(*sit != sequence.front())
    159 					{
    160 						visit = it->visitAggregate(InVisit, this);
    161 					}
    162 				}
    163 			}
    164 		}
    165 		else
    166 		{
    167 			for(TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
    168 			{
    169 				(*sit)->traverse(it);
    170 
    171 				if(visit && it->inVisit)
    172 				{
    173 					if(*sit != sequence.back())
    174 					{
    175 						visit = it->visitAggregate(InVisit, this);
    176 					}
    177 				}
    178 			}
    179 		}
    180 
    181 		it->decrementDepth();
    182 	}
    183 
    184 	if(visit && it->postVisit)
    185 	{
    186 		it->visitAggregate(PostVisit, this);
    187 	}
    188 }
    189 
    190 //
    191 // Traverse a selection node.  Same comments in binary node apply here.
    192 //
    193 void TIntermSelection::traverse(TIntermTraverser* it)
    194 {
    195 	bool visit = true;
    196 
    197 	if (it->preVisit)
    198 		visit = it->visitSelection(PreVisit, this);
    199 
    200 	if (visit) {
    201 		it->incrementDepth(this);
    202 		if (it->rightToLeft) {
    203 			if (falseBlock)
    204 				falseBlock->traverse(it);
    205 			if (trueBlock)
    206 				trueBlock->traverse(it);
    207 			condition->traverse(it);
    208 		} else {
    209 			condition->traverse(it);
    210 			if (trueBlock)
    211 				trueBlock->traverse(it);
    212 			if (falseBlock)
    213 				falseBlock->traverse(it);
    214 		}
    215 		it->decrementDepth();
    216 	}
    217 
    218 	if (visit && it->postVisit)
    219 		it->visitSelection(PostVisit, this);
    220 }
    221 
    222 //
    223 // Traverse a switch node.  Same comments in binary node apply here.
    224 //
    225 void TIntermSwitch::traverse(TIntermTraverser *it)
    226 {
    227 	bool visit = true;
    228 
    229 	if(it->preVisit)
    230 		visit = it->visitSwitch(PreVisit, this);
    231 
    232 	if(visit)
    233 	{
    234 		it->incrementDepth(this);
    235 		if(it->inVisit)
    236 			visit = it->visitSwitch(InVisit, this);
    237 		it->decrementDepth();
    238 	}
    239 
    240 	if(visit && it->postVisit)
    241 		it->visitSwitch(PostVisit, this);
    242 }
    243 
    244 //
    245 // Traverse a switch node.  Same comments in binary node apply here.
    246 //
    247 void TIntermCase::traverse(TIntermTraverser *it)
    248 {
    249 	bool visit = true;
    250 
    251 	if(it->preVisit)
    252 		visit = it->visitCase(PreVisit, this);
    253 
    254 	if(visit && mCondition)
    255 		mCondition->traverse(it);
    256 
    257 	if(visit && it->postVisit)
    258 		it->visitCase(PostVisit, this);
    259 }
    260 
    261 //
    262 // Traverse a loop node.  Same comments in binary node apply here.
    263 //
    264 void TIntermLoop::traverse(TIntermTraverser* it)
    265 {
    266 	bool visit = true;
    267 
    268 	if(it->preVisit)
    269 	{
    270 		visit = it->visitLoop(PreVisit, this);
    271 	}
    272 
    273 	if(visit)
    274 	{
    275 		it->incrementDepth(this);
    276 
    277 		if(it->rightToLeft)
    278 		{
    279 			if(expr)
    280 			{
    281 				expr->traverse(it);
    282 			}
    283 
    284 			if(body)
    285 			{
    286 				body->traverse(it);
    287 			}
    288 
    289 			if(cond)
    290 			{
    291 				cond->traverse(it);
    292 			}
    293 		}
    294 		else
    295 		{
    296 			if(cond)
    297 			{
    298 				cond->traverse(it);
    299 			}
    300 
    301 			if(body)
    302 			{
    303 				body->traverse(it);
    304 			}
    305 
    306 			if(expr)
    307 			{
    308 				expr->traverse(it);
    309 			}
    310 		}
    311 
    312 		it->decrementDepth();
    313 	}
    314 
    315 	if(visit && it->postVisit)
    316 	{
    317 		it->visitLoop(PostVisit, this);
    318 	}
    319 }
    320 
    321 //
    322 // Traverse a branch node.  Same comments in binary node apply here.
    323 //
    324 void TIntermBranch::traverse(TIntermTraverser* it)
    325 {
    326 	bool visit = true;
    327 
    328 	if (it->preVisit)
    329 		visit = it->visitBranch(PreVisit, this);
    330 
    331 	if (visit && expression) {
    332 		it->incrementDepth(this);
    333 		expression->traverse(it);
    334 		it->decrementDepth();
    335 	}
    336 
    337 	if (visit && it->postVisit)
    338 		it->visitBranch(PostVisit, this);
    339 }
    340 
    341