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
766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com#include "compiler/depgraph/DependencyGraphBuilder.h"
866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.comvoid 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
1566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.combool TDependencyGraphBuilder::visitAggregate(Visit visit, TIntermAggregate* intermAggregate)
1666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
1766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    switch (intermAggregate->getOp()) {
1866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        case EOpFunction: visitFunctionDefinition(intermAggregate); break;
1966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        case EOpFunctionCall: visitFunctionCall(intermAggregate); break;
2066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        default: visitAggregateChildren(intermAggregate); break;
2166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
2266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
2366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return false;
2466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
2566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
2666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.comvoid TDependencyGraphBuilder::visitFunctionDefinition(TIntermAggregate* intermAggregate)
2766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
2866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // Currently, we do not support user defined functions.
2966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (intermAggregate->getName() != "main(")
3066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        return;
3166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
3266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    visitAggregateChildren(intermAggregate);
3366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
3466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
3566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com// Takes an expression like "f(x)" and creates a dependency graph like
3666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com// "x -> argument 0 -> function call".
3766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.comvoid TDependencyGraphBuilder::visitFunctionCall(TIntermAggregate* intermFunctionCall)
3866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
3966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    TGraphFunctionCall* functionCall = mGraph->createFunctionCall(intermFunctionCall);
4066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
4166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // Run through the function call arguments.
4266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    int argumentNumber = 0;
4366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    TIntermSequence& intermArguments = intermFunctionCall->getSequence();
4466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    for (TIntermSequence::const_iterator iter = intermArguments.begin();
4566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com         iter != intermArguments.end();
4666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com         ++iter, ++argumentNumber)
4766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    {
4866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetMaintainer nodeSetMaintainer(this);
4966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
5066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TIntermNode* intermArgument = *iter;
5166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermArgument->traverse(this);
5266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
5366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        if (TParentNodeSet* argumentNodes = mNodeSets.getTopSet()) {
5466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            TGraphArgument* argument = mGraph->createArgument(intermFunctionCall, argumentNumber);
5566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(argumentNodes, argument);
5666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            argument->addDependentNode(functionCall);
5766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
5866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
5966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
6066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // Push the leftmost symbol of this function call into the current set of dependent symbols to
6166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // represent the result of this function call.
6266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // Thus, an expression like "y = f(x)" will yield a dependency graph like
6366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // "x -> argument 0 -> function call -> y".
6466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // This line essentially passes the function call node back up to an earlier visitAssignment
6566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // call, which will create the connection "function call -> y".
6666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    mNodeSets.insertIntoTopSet(functionCall);
6766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
6866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
6966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.comvoid TDependencyGraphBuilder::visitAggregateChildren(TIntermAggregate* intermAggregate)
7066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
7166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    TIntermSequence& sequence = intermAggregate->getSequence();
7266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    for(TIntermSequence::const_iterator iter = sequence.begin(); iter != sequence.end(); ++iter)
7366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    {
7466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TIntermNode* intermChild = *iter;
7566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermChild->traverse(this);
7666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
7766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
7866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
7966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.comvoid TDependencyGraphBuilder::visitSymbol(TIntermSymbol* intermSymbol)
8066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
8166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // Push this symbol into the set of dependent symbols for the current assignment or condition
8266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // that we are traversing.
8377222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com    TGraphSymbol* symbol = mGraph->getOrCreateSymbol(intermSymbol);
8466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    mNodeSets.insertIntoTopSet(symbol);
8566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
8666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // If this symbol is the current leftmost symbol under an assignment, replace the previous
8766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // leftmost symbol with this symbol.
88999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com    if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree) {
8966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        mLeftmostSymbols.pop();
9066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        mLeftmostSymbols.push(symbol);
9166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
9266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
9366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
9466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.combool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary* intermBinary)
9566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
9666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    TOperator op = intermBinary->getOp();
9766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (op == EOpInitialize || intermBinary->modifiesState())
9866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        visitAssignment(intermBinary);
9966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    else if (op == EOpLogicalAnd || op == EOpLogicalOr)
10066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        visitLogicalOp(intermBinary);
10166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    else
10266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        visitBinaryChildren(intermBinary);
10366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
10466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return false;
10566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
10666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
10766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.comvoid TDependencyGraphBuilder::visitAssignment(TIntermBinary* intermAssignment)
10866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
10966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    TIntermTyped* intermLeft = intermAssignment->getLeft();
11066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (!intermLeft)
11166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        return;
11266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
11366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    TGraphSymbol* leftmostSymbol = NULL;
11466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
11566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    {
11666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetMaintainer nodeSetMaintainer(this);
11766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
11866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        {
119999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com            TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mLeftSubtree);
12066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            intermLeft->traverse(this);
12166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            leftmostSymbol = mLeftmostSymbols.top();
12266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
12366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            // After traversing the left subtree of this assignment, we should have found a real
12466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            // leftmost symbol, and the leftmost symbol should not be a placeholder.
125999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com            ASSERT(leftmostSymbol != &mLeftSubtree);
126999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com            ASSERT(leftmostSymbol != &mRightSubtree);
12766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
12866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
12966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        if (TIntermTyped* intermRight = intermAssignment->getRight()) {
130999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com            TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
13166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            intermRight->traverse(this);
13266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
13366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
13466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        if (TParentNodeSet* assignmentNodes = mNodeSets.getTopSet())
13566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol);
13666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
13766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
13866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // Push the leftmost symbol of this assignment into the current set of dependent symbols to
13966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // represent the result of this assignment.
14066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // An expression like "a = (b = c)" will yield a dependency graph like "c -> b -> a".
14166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // This line essentially passes the leftmost symbol of the nested assignment ("b" in this
14266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // example) back up to the earlier visitAssignment call for the outer assignment, which will
14366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    // create the connection "b -> a".
14466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    mNodeSets.insertIntoTopSet(leftmostSymbol);
14566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
14666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
14766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.comvoid TDependencyGraphBuilder::visitLogicalOp(TIntermBinary* intermLogicalOp)
14866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
14966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermTyped* intermLeft = intermLogicalOp->getLeft()) {
15066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetPropagatingMaintainer nodeSetMaintainer(this);
15166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
15266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermLeft->traverse(this);
15366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        if (TParentNodeSet* leftNodes = mNodeSets.getTopSet()) {
15466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            TGraphLogicalOp* logicalOp = mGraph->createLogicalOp(intermLogicalOp);
15566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(leftNodes, logicalOp);
15666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
15766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
15866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
15966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermTyped* intermRight = intermLogicalOp->getRight()) {
160999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com        TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
16166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermRight->traverse(this);
16266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
16366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
16466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
16566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.comvoid TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary* intermBinary)
16666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
16766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermTyped* intermLeft = intermBinary->getLeft())
16866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermLeft->traverse(this);
16966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
17066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermTyped* intermRight = intermBinary->getRight()) {
171999f0ff612b779da8deb22214a750fcad526d8d4maxvujovic@gmail.com        TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
17266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermRight->traverse(this);
17366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
17466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
17566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
17666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.combool TDependencyGraphBuilder::visitSelection(Visit visit, TIntermSelection* intermSelection)
17766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
17866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermNode* intermCondition = intermSelection->getCondition()) {
17966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetMaintainer nodeSetMaintainer(this);
18066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
18166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermCondition->traverse(this);
18266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) {
18366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            TGraphSelection* selection = mGraph->createSelection(intermSelection);
18466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(conditionNodes, selection);
18566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
18666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
18766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
18866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermNode* intermTrueBlock = intermSelection->getTrueBlock())
18966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermTrueBlock->traverse(this);
19066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
19166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermNode* intermFalseBlock = intermSelection->getFalseBlock())
19266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermFalseBlock->traverse(this);
19366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
19466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return false;
19566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
19666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
19766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.combool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop* intermLoop)
19866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
19966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermTyped* intermCondition = intermLoop->getCondition()) {
20066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TNodeSetMaintainer nodeSetMaintainer(this);
20166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
20266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermCondition->traverse(this);
20366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) {
20466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            TGraphLoop* loop = mGraph->createLoop(intermLoop);
20566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            connectMultipleNodesToSingleNode(conditionNodes, loop);
20666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
20766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
20866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
20966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermNode* intermBody = intermLoop->getBody())
21066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermBody->traverse(this);
21166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
21266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    if (TIntermTyped* intermExpression = intermLoop->getExpression())
21366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        intermExpression->traverse(this);
21466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
21566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return false;
21666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
21766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
21866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
21966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.comvoid TDependencyGraphBuilder::connectMultipleNodesToSingleNode(TParentNodeSet* nodes,
22066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com                                                               TGraphNode* node) const
22166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
22266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    for (TParentNodeSet::const_iterator iter = nodes->begin(); iter != nodes->end(); ++iter)
22366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    {
22466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TGraphParentNode* currentNode = *iter;
22566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        currentNode->addDependentNode(node);
22666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
22766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
228