source: src/ResolvExpr/SpecCost.cc @ 2f42718

no_list
Last change on this file since 2f42718 was 2f42718, checked in by tdelisle <tdelisle@…>, 3 years ago

Parameters and return value of functions are now vectors (and some related clean-up)

  • Property mode set to 100644
File size: 3.6 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// SpecCost.cc --
8//
9// Author           : Aaron B. Moss
10// Created On       : Tue Oct 02 15:50:00 2018
11// Last Modified By : Aaron B. Moss
12// Last Modified On : Tue Oct 02 15:50:00 2018
13// Update Count     : 1
14//
15
16#include <limits>
17#include <list>
18
19#include "Common/PassVisitor.h"
20#include "SynTree/Declaration.h"
21#include "SynTree/Expression.h"
22#include "SynTree/Type.h"
23
24namespace ResolvExpr {
25
26        /// Counts specializations in a type
27        class CountSpecs : public WithShortCircuiting, public WithVisitorRef<CountSpecs> {
28                int count = -1;  ///< specialization count (-1 for none)
29
30        public:
31                int get_count() const { return count >= 0 ? count : 0; }
32
33                // mark specialization of base type
34                void postvisit(PointerType*) { if ( count >= 0 ) ++count; }
35
36                // mark specialization of base type
37                void postvisit(ArrayType*) { if ( count >= 0 ) ++count; }
38
39                // mark specialization of base type
40                void postvisit(ReferenceType*) { if ( count >= 0 ) ++count; }
41
42        private:
43                // takes minimum non-negative count over parameter/return list
44                void takeminover( int& mincount, std::vector<DeclarationWithType*> & dwts ) {
45                        for ( DeclarationWithType* dwt : dwts ) {
46                                count = -1;
47                                maybeAccept( dwt->get_type(), *visitor );
48                                if ( count != -1 && count < mincount ) mincount = count;
49                        }
50                }
51
52        public:
53                // take minimal specialization value over ->returnVals and ->parameters
54                void previsit(FunctionType* fty) {
55                        int mincount = std::numeric_limits<int>::max();
56                        takeminover( mincount, fty->parameters );
57                        takeminover( mincount, fty->returnVals );
58                        // add another level to mincount if set
59                        count = mincount < std::numeric_limits<int>::max() ? mincount + 1 : -1;
60                        // already visited children
61                        visit_children = false;
62                }
63
64        private:
65                // returns minimum non-negative count + 1 over type parameters (-1 if none such)
66                int minover( std::list<Expression*>& parms ) {
67                        int mincount = std::numeric_limits<int>::max();
68                        for ( Expression* parm : parms ) {
69                                count = -1;
70                                maybeAccept( parm->result, *visitor );
71                                if ( count != -1 && count < mincount ) mincount = count;
72                        }
73                        return mincount < std::numeric_limits<int>::max() ? mincount + 1 : -1;
74                }
75
76        public:
77                // look for polymorphic parameters
78                void previsit(StructInstType* sty) {
79                        count = minover( sty->parameters );
80                        visit_children = false;
81                }
82
83                // look for polymorphic parameters
84                void previsit(UnionInstType* uty) {
85                        count = minover( uty->parameters );
86                        visit_children = false;
87                }
88
89                // note polymorphic type (which may be specialized)
90                // xxx - maybe account for open/closed type variables
91                void postvisit(TypeInstType*) { count = 0; }
92
93                // take minimal specialization over elements
94                // xxx - maybe don't increment, tuple flattening doesn't necessarily specialize
95                void previsit(TupleType* tty) {
96                        int mincount = std::numeric_limits<int>::max();
97                        for ( Type* ty : tty->types ) {
98                                count = -1;
99                                maybeAccept( ty, *visitor );
100                                if ( count != -1 && count < mincount ) mincount = count;
101                        }
102                        count = mincount < std::numeric_limits<int>::max() ? mincount + 1 : -1;
103                        visit_children = false;
104                }
105        };
106
107        /// Returns the (negated) specialization cost for a given type
108        int specCost( Type* ty ) {
109                PassVisitor<CountSpecs> counter;
110                maybeAccept( ty, *counter.pass.visitor );
111                return counter.pass.get_count();
112        }
113} // namespace ResolvExpr
114
115// Local Variables: //
116// tab-width: 4 //
117// mode: c++ //
118// compile-command: "make install" //
119// End: //
Note: See TracBrowser for help on using the repository browser.