166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com//
266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com// Use of this source code is governed by a BSD-style license that can be
466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com// found in the LICENSE file.
566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com//
666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
717732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/depgraph/DependencyGraphBuilder.h"
866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
9e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Movoid TDependencyGraphBuilder::build(TIntermNode *node, TDependencyGraph *graph)
1066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
1166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    TDependencyGraphBuilder builder(graph);
1266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    builder.build(node);
1366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
1466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
15e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mobool TDependencyGraphBuilder::visitAggregate(
16e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    Visit visit, TIntermAggregate *intermAggregate)
1766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
18e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    switch (intermAggregate->getOp())
19e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    {
20e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo      case EOpFunction:
21e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        visitFunctionDefinition(intermAggregate);
22e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        break;
23e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo      case EOpFunctionCall:
24e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        visitFunctionCall(intermAggregate);
25e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        break;
26e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo      default:
27e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        visitAggregateChildren(intermAggregate);
28e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        break;
2966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
3066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return false;
3166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
3266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
33e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Movoid TDependencyGraphBuilder::visitFunctionDefinition(
34e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TIntermAggregate *intermAggregate)
3566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
3666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // Currently, we do not support user defined functions.
3766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (intermAggregate->getName() != "main(")
3866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        return;
3966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
4066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    visitAggregateChildren(intermAggregate);
4166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
4266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
4366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com// Takes an expression like "f(x)" and creates a dependency graph like
4466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com// "x -> argument 0 -> function call".
45e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Movoid TDependencyGraphBuilder::visitFunctionCall(
46e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TIntermAggregate *intermFunctionCall)
4766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
48e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TGraphFunctionCall *functionCall =
49e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        mGraph->createFunctionCall(intermFunctionCall);
5066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
5166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // Run through the function call arguments.
5266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    int argumentNumber = 0;
53e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TIntermSequence *intermArguments = intermFunctionCall->getSequence();
54e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    for (TIntermSequence::const_iterator iter = intermArguments->begin();
55e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo         iter != intermArguments->end();
5666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com         ++iter, ++argumentNumber)
5766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    {
5866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetMaintainer nodeSetMaintainer(this);
5966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
60e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        TIntermNode *intermArgument = *iter;
6166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermArgument->traverse(this);
6266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
63e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        if (TParentNodeSet *argumentNodes = mNodeSets.getTopSet())
64e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        {
65e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo            TGraphArgument *argument = mGraph->createArgument(
66e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo                intermFunctionCall, argumentNumber);
6766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(argumentNodes, argument);
6866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            argument->addDependentNode(functionCall);
6966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
7066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
7166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
72e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // Push the leftmost symbol of this function call into the current set of
73e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // dependent symbols to represent the result of this function call.
7466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // Thus, an expression like "y = f(x)" will yield a dependency graph like
7566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // "x -> argument 0 -> function call -> y".
76e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // This line essentially passes the function call node back up to an earlier
77e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // visitAssignment call, which will create the connection "function call -> y".
7866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    mNodeSets.insertIntoTopSet(functionCall);
7966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
8066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
81e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Movoid TDependencyGraphBuilder::visitAggregateChildren(
82e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TIntermAggregate *intermAggregate)
8366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
84e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TIntermSequence *sequence = intermAggregate->getSequence();
85e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    for (TIntermSequence::const_iterator iter = sequence->begin();
86e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo         iter != sequence->end(); ++iter)
8766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    {
88e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        TIntermNode *intermChild = *iter;
8966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermChild->traverse(this);
9066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
9166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
9266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
93e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Movoid TDependencyGraphBuilder::visitSymbol(TIntermSymbol *intermSymbol)
9466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
95e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // Push this symbol into the set of dependent symbols for the current
96e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // assignment or condition that we are traversing.
97e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TGraphSymbol *symbol = mGraph->getOrCreateSymbol(intermSymbol);
9866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    mNodeSets.insertIntoTopSet(symbol);
9966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
100e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // If this symbol is the current leftmost symbol under an assignment, replace
101e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // the previous leftmost symbol with this symbol.
102e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree)
103e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    {
10466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        mLeftmostSymbols.pop();
10566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        mLeftmostSymbols.push(symbol);
10666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
10766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
10866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
109e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mobool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary *intermBinary)
11066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
11166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    TOperator op = intermBinary->getOp();
112f4b79ba83c82253c012571ab07433692858562e2Jamie Madill    if (op == EOpInitialize || intermBinary->isAssignment())
11366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        visitAssignment(intermBinary);
11466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    else if (op == EOpLogicalAnd || op == EOpLogicalOr)
11566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        visitLogicalOp(intermBinary);
11666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    else
11766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        visitBinaryChildren(intermBinary);
11866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
11966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return false;
12066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
12166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
122e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Movoid TDependencyGraphBuilder::visitAssignment(TIntermBinary *intermAssignment)
12366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
124e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TIntermTyped *intermLeft = intermAssignment->getLeft();
12566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (!intermLeft)
12666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        return;
12766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
128e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TGraphSymbol *leftmostSymbol = NULL;
12966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
13066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    {
13166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetMaintainer nodeSetMaintainer(this);
13266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
13366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        {
134999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com            TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mLeftSubtree);
13566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            intermLeft->traverse(this);
13666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            leftmostSymbol = mLeftmostSymbols.top();
13766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
138e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo            // After traversing the left subtree of this assignment, we should
139e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo            // have found a real leftmost symbol, and the leftmost symbol should
140e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo            // not be a placeholder.
141999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com            ASSERT(leftmostSymbol != &mLeftSubtree);
142999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com            ASSERT(leftmostSymbol != &mRightSubtree);
14366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
14466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
145e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        if (TIntermTyped *intermRight = intermAssignment->getRight())
146e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        {
147999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com            TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
14866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            intermRight->traverse(this);
14966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
15066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
151e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        if (TParentNodeSet *assignmentNodes = mNodeSets.getTopSet())
15266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol);
15366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
15466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
155e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // Push the leftmost symbol of this assignment into the current set of dependent
156e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // symbols to represent the result of this assignment.
157e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // An expression like "a = (b = c)" will yield a dependency graph like
158e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // "c -> b -> a".
159e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // This line essentially passes the leftmost symbol of the nested assignment
160e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // ("b" in this example) back up to the earlier visitAssignment call for the
161e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    // outer assignment, which will create the connection "b -> a".
16266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    mNodeSets.insertIntoTopSet(leftmostSymbol);
16366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
16466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
165e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Movoid TDependencyGraphBuilder::visitLogicalOp(TIntermBinary *intermLogicalOp)
16666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
167e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (TIntermTyped *intermLeft = intermLogicalOp->getLeft())
168e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    {
16966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetPropagatingMaintainer nodeSetMaintainer(this);
17066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
17166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermLeft->traverse(this);
172e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        if (TParentNodeSet *leftNodes = mNodeSets.getTopSet())
173e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        {
174e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo            TGraphLogicalOp *logicalOp = mGraph->createLogicalOp(intermLogicalOp);
17566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(leftNodes, logicalOp);
17666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
17766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
17866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
179e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (TIntermTyped *intermRight = intermLogicalOp->getRight())
180e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    {
181999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com        TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
18266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermRight->traverse(this);
18366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
18466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
18566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
186e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Movoid TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary *intermBinary)
18766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
188e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (TIntermTyped *intermLeft = intermBinary->getLeft())
18966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermLeft->traverse(this);
19066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
191e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (TIntermTyped *intermRight = intermBinary->getRight())
192e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    {
193999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com        TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
19466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermRight->traverse(this);
19566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
19666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
19766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
198e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mobool TDependencyGraphBuilder::visitSelection(
199e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    Visit visit, TIntermSelection *intermSelection)
20066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
201e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (TIntermNode *intermCondition = intermSelection->getCondition())
202e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    {
20366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetMaintainer nodeSetMaintainer(this);
20466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
20566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermCondition->traverse(this);
206e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet())
207e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        {
208e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo            TGraphSelection *selection = mGraph->createSelection(intermSelection);
20966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(conditionNodes, selection);
21066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
21166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
21266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
213e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (TIntermNode *intermTrueBlock = intermSelection->getTrueBlock())
21466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermTrueBlock->traverse(this);
21566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
216e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (TIntermNode *intermFalseBlock = intermSelection->getFalseBlock())
21766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermFalseBlock->traverse(this);
21866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
21966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return false;
22066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
22166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
222e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mobool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop *intermLoop)
22366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
224e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (TIntermTyped *intermCondition = intermLoop->getCondition())
225e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    {
22666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetMaintainer nodeSetMaintainer(this);
22766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
22866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermCondition->traverse(this);
229e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet())
230e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        {
231e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo            TGraphLoop *loop = mGraph->createLoop(intermLoop);
23266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(conditionNodes, loop);
23366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
23466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
23566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
23666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermNode* intermBody = intermLoop->getBody())
23766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermBody->traverse(this);
23866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
239e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    if (TIntermTyped *intermExpression = intermLoop->getExpression())
24066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermExpression->traverse(this);
24166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
24266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return false;
24366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
24466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
24566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
246e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Movoid TDependencyGraphBuilder::connectMultipleNodesToSingleNode(
247e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    TParentNodeSet *nodes, TGraphNode *node) const
24866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
249e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo    for (TParentNodeSet::const_iterator iter = nodes->begin();
250e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo         iter != nodes->end(); ++iter)
25166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    {
252e40d1e9c70f1d1d5d0d92f24f8868fcf0b610639Zhenyao Mo        TGraphParentNode *currentNode = *iter;
25366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        currentNode->addDependentNode(node);
25466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
25566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
256