# source:src/CodeTools/DeclStats.cc@fa2de95

Last change on this file since fa2de95 was fa2de95, checked in by Aaron Moss <a3moss@…>, 7 years ago

Initial functional version of DeclStats?

• Property mode set to `100644`
File size: 5.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
13// Update Count     : 1
14//
15
16#include "DeclStats.h"
17
18#include <iostream>
19#include <string>
20#include <unordered_map>
21#include <unordered_set>
22
23#include "Common/VectorMap.h"
25#include "SynTree/Declaration.h"
26#include "SynTree/Visitor.h"
27
28namespace CodeTools {
29
30        class DeclStats : public Visitor {
31                struct Stats {
32                        unsigned n_decls;     ///< Total number of declarations
33                        unsigned mono_decls;  ///< Monomorphic declarations
34                        unsigned poly_decls;  ///< Polymorphic declarations
35                        /// Count of declarations with each name
36                        std::unordered_map<std::string, unsigned> by_name;
37                        /// Count of declarations with each number of parameters
38                        VectorMap<unsigned> by_params;
39                        /// Count of declarations with each number of return types
40                        VectorMap<unsigned> by_returns;
41
42                        Stats() : n_decls(0), mono_decls(0), poly_decls(0), by_name() {}
43
44                        Stats& operator+= (const Stats& o) {
45                                n_decls += o.n_decls;
46                                mono_decls += o.mono_decls;
47                                poly_decls += o.poly_decls;
48
49                                for ( auto& entry : o.by_name ) {
50                                        by_name[ entry.first ] += entry.second;
51                                }
52
53                                by_params.reserve( o.by_params.size() );
54                                for ( unsigned i = 0; i < o.by_params.size(); ++i ) {
55                                        by_params[i] += o.by_params[i];
56                                }
57
58                                by_returns.reserve( o.by_returns.size() );
59                                for ( unsigned i = 0; i < o.by_returns.size(); ++i ) {
60                                        by_returns[i] += o.by_returns[i];
61                                }
62
63                                return *this;
64                        }
65                };
66
68                std::unordered_set<std::string> seen_names;  ///< Stores manglenames already seen to avoid double-counting
69                Stats total;
70
71        public:
72                using Visitor::visit;
73
74                virtual void visit( FunctionDecl *decl ) {
75                        // skip if already seen declaration for this function
76                        const std::string& mangleName = decl->get_mangleName().empty() ? decl->get_name() : decl->get_mangleName();
77                        if ( ! seen_names.insert( mangleName ).second ) return;
78
80
81                        ++stats.n_decls;
82                        FunctionType* fnTy = decl->get_functionType();
83                        if ( fnTy->get_forall().empty() ) ++stats.mono_decls; else ++stats.poly_decls;
84
85                        ++stats.by_name[ decl->get_name() ];
86
87                        unsigned n_params = 0;
88                        for ( auto pdecl : fnTy->get_parameters() ) { n_params += pdecl->get_type()->size(); }
89                        ++stats.by_params.at( n_params );
90
91                        unsigned n_returns = 0;
92                        for ( auto rdecl : fnTy->get_returnVals() ) { n_returns += rdecl->get_type()->size(); }
93                        ++stats.by_returns.at( n_returns );
94                }
95
96        private:
97                template<typename F>
98                void printAll( const char* name, F extract ) {
99                        std::cout << "\"" << name << "\",";
100                        for ( const auto& stats : for_linkage ) {
101                                std::cout << "," << extract(stats);
102                        }
103                        std::cout << "," << extract(total) << std::endl;
104                }
105
106                template<typename F>
107                void printAllMap( const char* name, F extract ) {
108                        for ( const auto& entry : extract(total) ) {
109                                const auto& key = entry.first;
110                                std::cout << "\"" << name << "\"," << key;
111                                for ( const auto& stats : for_linkage ) {
112                                        const auto& map = extract(stats);
113                                        auto it = map.find( key );
114                                        if ( it == map.end() ) std::cout << ",0";
115                                        else std::cout << "," << it->second;
116                                }
117                                std::cout  << "," << entry.second << std::endl;
118                        }
119                }
120
121                template<typename F>
122                void printAllHisto( const char* name, F extract ) {
124                        VectorMap<unsigned> thisto;
125
126                        for ( const auto& entry : extract(total) ) { ++thisto.at( entry.second ); }
127
128                        for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) {
129                                // can't be a higher count in one of the sub-histograms than the total
130                                histos[i].reserve( thisto.size() );
131
132                                for ( const auto& entry : extract(for_linkage[i]) ) { ++histos[i][entry.second]; }
133                        }
134
135                        for ( unsigned i = 0; i < thisto.size(); ++i ) {
136                                std::cout << "\"" << name << "\"," << i;
137                                for ( const auto& histo : histos ) {
138                                        std::cout << "," << histo[i];
139                                }
140                                std::cout << "," << thisto[i] << std::endl;
141                        }
142                }
143
144        public:
145                void print() {
146                        for ( auto& stats : for_linkage ) {
147                                total += stats;
148                        }
149
150                        std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\"builtin\",\"TOTAL\"" << std::endl;
151
152                        printAll("mono_decls", [](const Stats& stats) { return stats.mono_decls; });
153                        printAll("poly_decls", [](const Stats& stats) { return stats.poly_decls; });
154                        printAll("n_decls", [](const Stats& stats) { return stats.n_decls; });
155                        printAll("unique_names", [](const Stats& stats) { return stats.by_name.size(); });
156
157                        printAllHisto("overloads", [](const Stats& stats) { return stats.by_name; });
158                        printAllMap("n_params", [](const Stats& stats) { return stats.by_params; });
159                        printAllMap("n_returns", [](const Stats& stats) { return stats.by_returns; });
160                }
161        };
162
163        void printDeclStats( std::list< Declaration * > &translationUnit ) {
164                DeclStats stats;
165                acceptAll( translationUnit, stats );
166                stats.print();
167        }
168
169} // namespace CodeTools
170
171// Local Variables: //
172// tab-width: 4 //
173// mode: c++ //
174// compile-command: "make install" //
175// End: //
Note: See TracBrowser for help on using the repository browser.