source: src/CodeTools/DeclStats.cc @ 567903e

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 567903e was 567903e, checked in by Aaron Moss <a3moss@…>, 7 years ago

Added percentage polymorphic parameters to stats

  • Property mode set to 100644
File size: 7.3 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// DeclStats.cc --
8//
9// Author           : Aaron Moss
10// Created On       : Wed Jan 31 16:40:00 2016
11// Last Modified By : Aaron Moss
12// Last Modified On : Wed Jan 31 16:40:00 2016
13// Update Count     : 1
14//
15
16#include "DeclStats.h"
17
18#include <iostream>
19#include <map>
20#include <string>
21#include <unordered_map>
22#include <unordered_set>
23
24#include "Common/VectorMap.h"
25#include "GenPoly/GenPoly.h"
26#include "Parser/LinkageSpec.h"
27#include "SynTree/Declaration.h"
28#include "SynTree/Visitor.h"
29
30namespace CodeTools {
31       
32        class DeclStats : public Visitor {
33                struct Stats {
34                        unsigned n_decls;     ///< Total number of declarations
35                        unsigned mono_decls;  ///< Monomorphic declarations
36                        unsigned poly_decls;  ///< Polymorphic declarations
37                        /// Count of declarations with each name
38                        std::unordered_map<std::string, unsigned> by_name;
39                        /// Count of declarations with each number of parameters
40                        VectorMap<unsigned> by_params;
41                        /// Count of declarations with each number of return types
42                        VectorMap<unsigned> by_returns;
43                        /// Count of declarations with each number of polymorphic parameters
44                        VectorMap<unsigned> n_poly_params;
45                        /// Count of declarations with each number of polymorphic return types
46                        VectorMap<unsigned> n_poly_returns;
47                        /// Count of declarations with each percentage of polymorphic parameters
48                        std::map<unsigned, unsigned> p_poly_params;
49                        /// Count of declarations with each percentage of polymorphic returns
50                        std::map<unsigned, unsigned> p_poly_returns;
51
52                        Stats() : n_decls(0), mono_decls(0), poly_decls(0), by_name(), by_params(), by_returns(), n_poly_params(), n_poly_returns(), p_poly_params(), p_poly_returns() {}
53
54                        Stats& operator+= (const Stats& o) {
55                                n_decls += o.n_decls;
56                                mono_decls += o.mono_decls;
57                                poly_decls += o.poly_decls;
58                               
59                                for ( auto& entry : o.by_name ) {
60                                        by_name[ entry.first ] += entry.second;
61                                }
62                               
63                                by_params.reserve( o.by_params.size() );
64                                for ( unsigned i = 0; i < o.by_params.size(); ++i ) {
65                                        by_params[i] += o.by_params[i];
66                                }
67
68                                by_returns.reserve( o.by_returns.size() );
69                                for ( unsigned i = 0; i < o.by_returns.size(); ++i ) {
70                                        by_returns[i] += o.by_returns[i];
71                                }
72
73                                n_poly_params.reserve( o.n_poly_params.size() );
74                                for ( unsigned i = 0; i < o.n_poly_params.size(); ++i ) {
75                                        n_poly_params[i] += o.n_poly_params[i];
76                                }
77
78                                n_poly_returns.reserve( o.n_poly_returns.size() );
79                                for ( unsigned i = 0; i < o.n_poly_returns.size(); ++i ) {
80                                        n_poly_returns[i] += o.n_poly_returns[i];
81                                }
82
83                                for ( const auto& entry : o.p_poly_params ) {
84                                        p_poly_params[ entry.first ] += entry.second;
85                                }
86
87                                for ( const auto& entry : o.p_poly_returns ) {
88                                        p_poly_returns[ entry.first ] += entry.second;
89                                }
90
91                                return *this;
92                        }
93                };
94
95                Stats for_linkage[LinkageSpec::NoOfSpecs];   ///< Stores separate stats per linkage
96                std::unordered_set<std::string> seen_names;  ///< Stores manglenames already seen to avoid double-counting
97                Stats total;
98
99        public:
100                using Visitor::visit;
101
102                virtual void visit( FunctionDecl *decl ) {
103                        // skip if already seen declaration for this function
104                        const std::string& mangleName = decl->get_mangleName().empty() ? decl->get_name() : decl->get_mangleName();
105                        if ( ! seen_names.insert( mangleName ).second ) return;
106                       
107                        Stats& stats = for_linkage[ decl->get_linkage() ];
108
109                        ++stats.n_decls;
110                        FunctionType* fnTy = decl->get_functionType();
111                        if ( fnTy->get_forall().empty() ) ++stats.mono_decls; else ++stats.poly_decls;
112
113                        ++stats.by_name[ decl->get_name() ];
114
115                        unsigned n_params = 0;
116                        unsigned n_poly_params = 0;
117                        for ( auto pdecl : fnTy->get_parameters() ) {
118                                n_params += pdecl->get_type()->size();
119                                if ( GenPoly::hasPolyBase( pdecl->get_type() ) ) ++n_poly_params;
120                        }
121                        ++stats.by_params.at( n_params );
122                        ++stats.n_poly_params.at( n_poly_params );
123                        if ( n_params > 0 ) ++stats.p_poly_params[ n_poly_params*100/n_params ];
124
125                        unsigned n_returns = 0;
126                        unsigned n_poly_returns = 0;
127                        for ( auto rdecl : fnTy->get_returnVals() ) {
128                                n_returns += rdecl->get_type()->size();
129                                if ( GenPoly::hasPolyBase( rdecl->get_type() ) ) ++n_poly_returns;
130                        }
131                        ++stats.by_returns.at( n_returns );
132                        ++stats.n_poly_returns.at( n_poly_returns );
133                        if ( n_returns > 0 ) ++stats.p_poly_returns[ n_poly_returns*100/n_returns ];
134                }
135
136        private:
137                template<typename F>
138                void printAll( const char* name, F extract ) {
139                        std::cout << "\"" << name << "\",";
140                        for ( const auto& stats : for_linkage ) {
141                                std::cout << "," << extract(stats);
142                        }
143                        std::cout << "," << extract(total) << std::endl;
144                }
145
146                template<typename F>
147                void printAllMap( const char* name, F extract ) {
148                        for ( const auto& entry : extract(total) ) {
149                                const auto& key = entry.first;
150                                std::cout << "\"" << name << "\"," << key;
151                                for ( const auto& stats : for_linkage ) {
152                                        const auto& map = extract(stats);
153                                        auto it = map.find( key );
154                                        if ( it == map.end() ) std::cout << ",0";
155                                        else std::cout << "," << it->second;
156                                }
157                                std::cout  << "," << entry.second << std::endl;
158                        }
159                }
160
161                template<typename F>
162                void printAllHisto( const char* name, F extract ) {
163                        VectorMap<unsigned> histos[LinkageSpec::NoOfSpecs];
164                        VectorMap<unsigned> thisto;
165
166                        for ( const auto& entry : extract(total) ) { ++thisto.at( entry.second ); }
167
168                        for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) {
169                                // can't be a higher count in one of the sub-histograms than the total
170                                histos[i].reserve( thisto.size() );
171
172                                for ( const auto& entry : extract(for_linkage[i]) ) { ++histos[i][entry.second]; }
173                        }
174
175                        for ( unsigned i = 0; i < thisto.size(); ++i ) {
176                                std::cout << "\"" << name << "\"," << i;
177                                for ( const auto& histo : histos ) {
178                                        std::cout << "," << histo[i];
179                                }
180                                std::cout << "," << thisto[i] << std::endl;
181                        }
182                }
183               
184        public:
185                void print() {
186                        for ( auto& stats : for_linkage ) {
187                                total += stats;
188                        }
189
190                        std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\"builtin\",\"TOTAL\"" << std::endl;
191
192                        printAll("mono_decls", [](const Stats& stats) { return stats.mono_decls; });
193                        printAll("poly_decls", [](const Stats& stats) { return stats.poly_decls; });
194                        printAll("n_decls", [](const Stats& stats) { return stats.n_decls; });
195                        printAll("unique_names", [](const Stats& stats) { return stats.by_name.size(); });
196
197                        printAllHisto("overloads", [](const Stats& stats) { return stats.by_name; });
198                        printAllMap("n_poly_params", [](const Stats& stats) { return stats.n_poly_params; });
199                        printAllMap("n_params", [](const Stats& stats) { return stats.by_params; });
200                        printAllMap("%_poly_params", [](const Stats& stats) { return stats.p_poly_params; });
201                        printAllMap("n_poly_returns", [](const Stats& stats) { return stats.n_poly_returns; });
202                        printAllMap("n_returns", [](const Stats& stats) { return stats.by_returns; });
203                        printAllMap("%_poly_returns", [](const Stats& stats) { return stats.p_poly_returns; });
204                }
205        };
206
207        void printDeclStats( std::list< Declaration * > &translationUnit ) {
208                DeclStats stats;
209                acceptAll( translationUnit, stats );
210                stats.print();
211        }
212       
213} // namespace CodeTools
214
215// Local Variables: //
216// tab-width: 4 //
217// mode: c++ //
218// compile-command: "make install" //
219// End: //
Note: See TracBrowser for help on using the repository browser.