gfx/angle/src/compiler/depgraph/DependencyGraphBuilder.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 //
     2 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
     3 // Use of this source code is governed by a BSD-style license that can be
     4 // found in the LICENSE file.
     5 //
     7 #ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
     8 #define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
    10 #include "compiler/depgraph/DependencyGraph.h"
    12 //
    13 // Creates a dependency graph of symbols, function calls, conditions etc. by traversing a
    14 // intermediate tree.
    15 //
    16 class TDependencyGraphBuilder : public TIntermTraverser {
    17 public:
    18     static void build(TIntermNode* node, TDependencyGraph* graph);
    20     virtual void visitSymbol(TIntermSymbol*);
    21     virtual bool visitBinary(Visit visit, TIntermBinary*);
    22     virtual bool visitSelection(Visit visit, TIntermSelection*);
    23     virtual bool visitAggregate(Visit visit, TIntermAggregate*);
    24     virtual bool visitLoop(Visit visit, TIntermLoop*);
    26 private:
    27     typedef std::stack<TGraphSymbol*> TSymbolStack;
    28     typedef std::set<TGraphParentNode*> TParentNodeSet;
    30     //
    31     // For collecting the dependent nodes of assignments, conditions, etc.
    32     // while traversing the intermediate tree.
    33     //
    34     // This data structure is stack of sets. Each set contains dependency graph parent nodes.
    35     //
    36     class TNodeSetStack {
    37     public:
    38         TNodeSetStack() {};
    39         ~TNodeSetStack() { clear(); }
    41         // This should only be called after a pushSet.
    42         // Returns NULL if the top set is empty.
    43         TParentNodeSet* getTopSet() const
    44         {
    45             ASSERT(!nodeSets.empty());
    46             TParentNodeSet* topSet = nodeSets.top();
    47             return !topSet->empty() ? topSet : NULL;
    48         }
    50         void pushSet() { nodeSets.push(new TParentNodeSet()); }
    51         void popSet()
    52         {
    53             ASSERT(!nodeSets.empty());
    54             delete nodeSets.top();
    55             nodeSets.pop();
    56         }
    58         // Pops the top set and adds its contents to the new top set.
    59         // This should only be called after a pushSet.
    60         // If there is no set below the top set, the top set is just deleted.
    61         void popSetIntoNext()
    62         {
    63             ASSERT(!nodeSets.empty());
    64             TParentNodeSet* oldTopSet = nodeSets.top();
    65             nodeSets.pop();
    67             if (!nodeSets.empty()) {
    68                 TParentNodeSet* newTopSet = nodeSets.top();
    69                 newTopSet->insert(oldTopSet->begin(), oldTopSet->end());
    70             }
    72             delete oldTopSet;
    73         }
    75         // Does nothing if there is no top set.
    76         // This can be called when there is no top set if we are visiting
    77         // symbols that are not under an assignment or condition.
    78         // We don't need to track those symbols.
    79         void insertIntoTopSet(TGraphParentNode* node)
    80         {
    81             if (nodeSets.empty())
    82                 return;
    84             nodeSets.top()->insert(node);
    85         }
    87         void clear()
    88         {
    89             while (!nodeSets.empty())
    90                 popSet();
    91         }
    93     private:
    94         typedef std::stack<TParentNodeSet*> TParentNodeSetStack;
    96         TParentNodeSetStack nodeSets;
    97     };
    99     //
   100     // An instance of this class pushes a new node set when instantiated.
   101     // When the instance goes out of scope, it and pops the node set.
   102     //
   103     class TNodeSetMaintainer {
   104     public:
   105         TNodeSetMaintainer(TDependencyGraphBuilder* factory)
   106             : sets(factory->mNodeSets) { sets.pushSet(); }
   107         ~TNodeSetMaintainer() { sets.popSet(); }
   108     protected:
   109         TNodeSetStack& sets;
   110     };
   112     //
   113     // An instance of this class pushes a new node set when instantiated.
   114     // When the instance goes out of scope, it and pops the top node set and adds its contents to
   115     // the new top node set.
   116     //
   117     class TNodeSetPropagatingMaintainer {
   118     public:
   119         TNodeSetPropagatingMaintainer(TDependencyGraphBuilder* factory)
   120             : sets(factory->mNodeSets) { sets.pushSet(); }
   121         ~TNodeSetPropagatingMaintainer() { sets.popSetIntoNext(); }
   122     protected:
   123         TNodeSetStack& sets;
   124     };
   126     //
   127     // An instance of this class keeps track of the leftmost symbol while we're exploring an
   128     // assignment.
   129     // It will push the placeholder symbol kLeftSubtree when instantiated under a left subtree,
   130     // and kRightSubtree under a right subtree.
   131     // When it goes out of scope, it will pop the leftmost symbol at the top of the scope.
   132     // During traversal, the TDependencyGraphBuilder will replace kLeftSubtree with a real symbol.
   133     // kRightSubtree will never be replaced by a real symbol because we are tracking the leftmost
   134     // symbol.
   135     //
   136     class TLeftmostSymbolMaintainer {
   137     public:
   138         TLeftmostSymbolMaintainer(TDependencyGraphBuilder* factory, TGraphSymbol& subtree)
   139             : leftmostSymbols(factory->mLeftmostSymbols)
   140         {
   141             needsPlaceholderSymbol = leftmostSymbols.empty() || leftmostSymbols.top() != &subtree;
   142             if (needsPlaceholderSymbol)
   143                 leftmostSymbols.push(&subtree);
   144         }
   146         ~TLeftmostSymbolMaintainer()
   147         {
   148             if (needsPlaceholderSymbol)
   149                 leftmostSymbols.pop();
   150         }
   152     protected:
   153         TSymbolStack& leftmostSymbols;
   154         bool needsPlaceholderSymbol;
   155     };
   157     TDependencyGraphBuilder(TDependencyGraph* graph)
   158         : TIntermTraverser(true, false, false)
   159         , mLeftSubtree(NULL)
   160         , mRightSubtree(NULL)
   161         , mGraph(graph) {}
   162     void build(TIntermNode* intermNode) { intermNode->traverse(this); }
   164     void connectMultipleNodesToSingleNode(TParentNodeSet* nodes, TGraphNode* node) const;
   166     void visitAssignment(TIntermBinary*);
   167     void visitLogicalOp(TIntermBinary*);
   168     void visitBinaryChildren(TIntermBinary*);
   169     void visitFunctionDefinition(TIntermAggregate*);
   170     void visitFunctionCall(TIntermAggregate* intermFunctionCall);
   171     void visitAggregateChildren(TIntermAggregate*);
   173     TGraphSymbol mLeftSubtree;
   174     TGraphSymbol mRightSubtree;
   176     TDependencyGraph* mGraph;
   177     TNodeSetStack mNodeSets;
   178     TSymbolStack mLeftmostSymbols;
   179 };
   181 #endif  // COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H

mercurial