source: src/ResolvExpr/SpecCost.cc @ 9d5089e

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 9d5089e was 9d5089e, checked in by Aaron Moss <a3moss@…>, 5 years ago

Port CandidateFinder::makeFunctionCandidates() and deps

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