Hash :
e40d1e9c
Author :
Date :
2014-07-16T17:40:36
Fix style violations. BUG=angle:650 TEST=no behavior change Change-Id: I3096615a181b1ec2c18ce60566c3d6249975b84e Reviewed-on: https://chromium-review.googlesource.com/208569 Tested-by: Zhenyao Mo <zmo@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/translator/depgraph/DependencyGraphBuilder.h"
void TDependencyGraphBuilder::build(TIntermNode *node, TDependencyGraph *graph)
{
TDependencyGraphBuilder builder(graph);
builder.build(node);
}
bool TDependencyGraphBuilder::visitAggregate(
Visit visit, TIntermAggregate *intermAggregate)
{
switch (intermAggregate->getOp())
{
case EOpFunction:
visitFunctionDefinition(intermAggregate);
break;
case EOpFunctionCall:
visitFunctionCall(intermAggregate);
break;
default:
visitAggregateChildren(intermAggregate);
break;
}
return false;
}
void TDependencyGraphBuilder::visitFunctionDefinition(
TIntermAggregate *intermAggregate)
{
// Currently, we do not support user defined functions.
if (intermAggregate->getName() != "main(")
return;
visitAggregateChildren(intermAggregate);
}
// Takes an expression like "f(x)" and creates a dependency graph like
// "x -> argument 0 -> function call".
void TDependencyGraphBuilder::visitFunctionCall(
TIntermAggregate *intermFunctionCall)
{
TGraphFunctionCall *functionCall =
mGraph->createFunctionCall(intermFunctionCall);
// Run through the function call arguments.
int argumentNumber = 0;
TIntermSequence *intermArguments = intermFunctionCall->getSequence();
for (TIntermSequence::const_iterator iter = intermArguments->begin();
iter != intermArguments->end();
++iter, ++argumentNumber)
{
TNodeSetMaintainer nodeSetMaintainer(this);
TIntermNode *intermArgument = *iter;
intermArgument->traverse(this);
if (TParentNodeSet *argumentNodes = mNodeSets.getTopSet())
{
TGraphArgument *argument = mGraph->createArgument(
intermFunctionCall, argumentNumber);
connectMultipleNodesToSingleNode(argumentNodes, argument);
argument->addDependentNode(functionCall);
}
}
// Push the leftmost symbol of this function call into the current set of
// dependent symbols to represent the result of this function call.
// Thus, an expression like "y = f(x)" will yield a dependency graph like
// "x -> argument 0 -> function call -> y".
// This line essentially passes the function call node back up to an earlier
// visitAssignment call, which will create the connection "function call -> y".
mNodeSets.insertIntoTopSet(functionCall);
}
void TDependencyGraphBuilder::visitAggregateChildren(
TIntermAggregate *intermAggregate)
{
TIntermSequence *sequence = intermAggregate->getSequence();
for (TIntermSequence::const_iterator iter = sequence->begin();
iter != sequence->end(); ++iter)
{
TIntermNode *intermChild = *iter;
intermChild->traverse(this);
}
}
void TDependencyGraphBuilder::visitSymbol(TIntermSymbol *intermSymbol)
{
// Push this symbol into the set of dependent symbols for the current
// assignment or condition that we are traversing.
TGraphSymbol *symbol = mGraph->getOrCreateSymbol(intermSymbol);
mNodeSets.insertIntoTopSet(symbol);
// If this symbol is the current leftmost symbol under an assignment, replace
// the previous leftmost symbol with this symbol.
if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree)
{
mLeftmostSymbols.pop();
mLeftmostSymbols.push(symbol);
}
}
bool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary *intermBinary)
{
TOperator op = intermBinary->getOp();
if (op == EOpInitialize || intermBinary->isAssignment())
visitAssignment(intermBinary);
else if (op == EOpLogicalAnd || op == EOpLogicalOr)
visitLogicalOp(intermBinary);
else
visitBinaryChildren(intermBinary);
return false;
}
void TDependencyGraphBuilder::visitAssignment(TIntermBinary *intermAssignment)
{
TIntermTyped *intermLeft = intermAssignment->getLeft();
if (!intermLeft)
return;
TGraphSymbol *leftmostSymbol = NULL;
{
TNodeSetMaintainer nodeSetMaintainer(this);
{
TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mLeftSubtree);
intermLeft->traverse(this);
leftmostSymbol = mLeftmostSymbols.top();
// After traversing the left subtree of this assignment, we should
// have found a real leftmost symbol, and the leftmost symbol should
// not be a placeholder.
ASSERT(leftmostSymbol != &mLeftSubtree);
ASSERT(leftmostSymbol != &mRightSubtree);
}
if (TIntermTyped *intermRight = intermAssignment->getRight())
{
TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
intermRight->traverse(this);
}
if (TParentNodeSet *assignmentNodes = mNodeSets.getTopSet())
connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol);
}
// Push the leftmost symbol of this assignment into the current set of dependent
// symbols to represent the result of this assignment.
// An expression like "a = (b = c)" will yield a dependency graph like
// "c -> b -> a".
// This line essentially passes the leftmost symbol of the nested assignment
// ("b" in this example) back up to the earlier visitAssignment call for the
// outer assignment, which will create the connection "b -> a".
mNodeSets.insertIntoTopSet(leftmostSymbol);
}
void TDependencyGraphBuilder::visitLogicalOp(TIntermBinary *intermLogicalOp)
{
if (TIntermTyped *intermLeft = intermLogicalOp->getLeft())
{
TNodeSetPropagatingMaintainer nodeSetMaintainer(this);
intermLeft->traverse(this);
if (TParentNodeSet *leftNodes = mNodeSets.getTopSet())
{
TGraphLogicalOp *logicalOp = mGraph->createLogicalOp(intermLogicalOp);
connectMultipleNodesToSingleNode(leftNodes, logicalOp);
}
}
if (TIntermTyped *intermRight = intermLogicalOp->getRight())
{
TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
intermRight->traverse(this);
}
}
void TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary *intermBinary)
{
if (TIntermTyped *intermLeft = intermBinary->getLeft())
intermLeft->traverse(this);
if (TIntermTyped *intermRight = intermBinary->getRight())
{
TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
intermRight->traverse(this);
}
}
bool TDependencyGraphBuilder::visitSelection(
Visit visit, TIntermSelection *intermSelection)
{
if (TIntermNode *intermCondition = intermSelection->getCondition())
{
TNodeSetMaintainer nodeSetMaintainer(this);
intermCondition->traverse(this);
if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet())
{
TGraphSelection *selection = mGraph->createSelection(intermSelection);
connectMultipleNodesToSingleNode(conditionNodes, selection);
}
}
if (TIntermNode *intermTrueBlock = intermSelection->getTrueBlock())
intermTrueBlock->traverse(this);
if (TIntermNode *intermFalseBlock = intermSelection->getFalseBlock())
intermFalseBlock->traverse(this);
return false;
}
bool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop *intermLoop)
{
if (TIntermTyped *intermCondition = intermLoop->getCondition())
{
TNodeSetMaintainer nodeSetMaintainer(this);
intermCondition->traverse(this);
if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet())
{
TGraphLoop *loop = mGraph->createLoop(intermLoop);
connectMultipleNodesToSingleNode(conditionNodes, loop);
}
}
if (TIntermNode* intermBody = intermLoop->getBody())
intermBody->traverse(this);
if (TIntermTyped *intermExpression = intermLoop->getExpression())
intermExpression->traverse(this);
return false;
}
void TDependencyGraphBuilder::connectMultipleNodesToSingleNode(
TParentNodeSet *nodes, TGraphNode *node) const
{
for (TParentNodeSet::const_iterator iter = nodes->begin();
iter != nodes->end(); ++iter)
{
TGraphParentNode *currentNode = *iter;
currentNode->addDependentNode(node);
}
}