1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker 7*8975f5c5SAndroid Build Coastguard Worker // CallDAG.h: Defines a call graph DAG of functions to be re-used accross 8*8975f5c5SAndroid Build Coastguard Worker // analyses, allows to efficiently traverse the functions in topological 9*8975f5c5SAndroid Build Coastguard Worker // order. 10*8975f5c5SAndroid Build Coastguard Worker 11*8975f5c5SAndroid Build Coastguard Worker #ifndef COMPILER_TRANSLATOR_CALLDAG_H_ 12*8975f5c5SAndroid Build Coastguard Worker #define COMPILER_TRANSLATOR_CALLDAG_H_ 13*8975f5c5SAndroid Build Coastguard Worker 14*8975f5c5SAndroid Build Coastguard Worker #include <map> 15*8975f5c5SAndroid Build Coastguard Worker 16*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/IntermNode.h" 17*8975f5c5SAndroid Build Coastguard Worker 18*8975f5c5SAndroid Build Coastguard Worker namespace sh 19*8975f5c5SAndroid Build Coastguard Worker { 20*8975f5c5SAndroid Build Coastguard Worker 21*8975f5c5SAndroid Build Coastguard Worker // The translator needs to analyze the the graph of the function calls 22*8975f5c5SAndroid Build Coastguard Worker // to run checks and analyses; since in GLSL recursion is not allowed 23*8975f5c5SAndroid Build Coastguard Worker // that graph is a DAG. 24*8975f5c5SAndroid Build Coastguard Worker // This class is used to precompute that function call DAG so that it 25*8975f5c5SAndroid Build Coastguard Worker // can be reused by multiple analyses. 26*8975f5c5SAndroid Build Coastguard Worker // 27*8975f5c5SAndroid Build Coastguard Worker // It stores a vector of function records, with one record per defined function. 28*8975f5c5SAndroid Build Coastguard Worker // Records are accessed by index but a function symbol id can be converted 29*8975f5c5SAndroid Build Coastguard Worker // to the index of the corresponding record. The records contain the AST node 30*8975f5c5SAndroid Build Coastguard Worker // of the function definition and the indices of the function's callees. 31*8975f5c5SAndroid Build Coastguard Worker // 32*8975f5c5SAndroid Build Coastguard Worker // In addition, records are in reverse topological order: a function F being 33*8975f5c5SAndroid Build Coastguard Worker // called by a function G will have index index(F) < index(G), that way 34*8975f5c5SAndroid Build Coastguard Worker // depth-first analysis becomes analysis in the order of indices. 35*8975f5c5SAndroid Build Coastguard Worker 36*8975f5c5SAndroid Build Coastguard Worker class CallDAG : angle::NonCopyable 37*8975f5c5SAndroid Build Coastguard Worker { 38*8975f5c5SAndroid Build Coastguard Worker public: 39*8975f5c5SAndroid Build Coastguard Worker CallDAG(); 40*8975f5c5SAndroid Build Coastguard Worker ~CallDAG(); 41*8975f5c5SAndroid Build Coastguard Worker 42*8975f5c5SAndroid Build Coastguard Worker struct Record 43*8975f5c5SAndroid Build Coastguard Worker { 44*8975f5c5SAndroid Build Coastguard Worker TIntermFunctionDefinition *node; // Guaranteed to be non-null. 45*8975f5c5SAndroid Build Coastguard Worker std::vector<int> callees; 46*8975f5c5SAndroid Build Coastguard Worker }; 47*8975f5c5SAndroid Build Coastguard Worker 48*8975f5c5SAndroid Build Coastguard Worker enum InitResult 49*8975f5c5SAndroid Build Coastguard Worker { 50*8975f5c5SAndroid Build Coastguard Worker INITDAG_SUCCESS, 51*8975f5c5SAndroid Build Coastguard Worker INITDAG_RECURSION, 52*8975f5c5SAndroid Build Coastguard Worker INITDAG_UNDEFINED, 53*8975f5c5SAndroid Build Coastguard Worker }; 54*8975f5c5SAndroid Build Coastguard Worker 55*8975f5c5SAndroid Build Coastguard Worker // Returns INITDAG_SUCCESS if it was able to create the DAG, otherwise prints 56*8975f5c5SAndroid Build Coastguard Worker // the initialization error in diagnostics, if present. 57*8975f5c5SAndroid Build Coastguard Worker InitResult init(TIntermNode *root, TDiagnostics *diagnostics); 58*8975f5c5SAndroid Build Coastguard Worker 59*8975f5c5SAndroid Build Coastguard Worker // Returns InvalidIndex if the function wasn't found 60*8975f5c5SAndroid Build Coastguard Worker size_t findIndex(const TSymbolUniqueId &id) const; 61*8975f5c5SAndroid Build Coastguard Worker 62*8975f5c5SAndroid Build Coastguard Worker const Record &getRecordFromIndex(size_t index) const; 63*8975f5c5SAndroid Build Coastguard Worker size_t size() const; 64*8975f5c5SAndroid Build Coastguard Worker void clear(); 65*8975f5c5SAndroid Build Coastguard Worker 66*8975f5c5SAndroid Build Coastguard Worker const static size_t InvalidIndex; 67*8975f5c5SAndroid Build Coastguard Worker 68*8975f5c5SAndroid Build Coastguard Worker private: 69*8975f5c5SAndroid Build Coastguard Worker std::vector<Record> mRecords; 70*8975f5c5SAndroid Build Coastguard Worker std::map<int, int> mFunctionIdToIndex; 71*8975f5c5SAndroid Build Coastguard Worker 72*8975f5c5SAndroid Build Coastguard Worker class CallDAGCreator; 73*8975f5c5SAndroid Build Coastguard Worker }; 74*8975f5c5SAndroid Build Coastguard Worker 75*8975f5c5SAndroid Build Coastguard Worker } // namespace sh 76*8975f5c5SAndroid Build Coastguard Worker 77*8975f5c5SAndroid Build Coastguard Worker #endif // COMPILER_TRANSLATOR_CALLDAG_H_ 78