source: src/ResolvExpr/SpecCost.cpp@ d5efcb7

Last change on this file since d5efcb7 was 5f225f5, checked in by Andrew Beach <ajbeach@…>, 17 months ago

Perhaps only src/Makefile.am needed to change, but I did a text search to try and be absolutely sure I got everything.

  • Property mode set to 100644
File size: 3.9 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.cpp --
8//
9// Author : Aaron B. Moss
10// Created On : Tue Oct 02 15:50:00 2018
11// Last Modified By : Andrew Beach
12// Last Modified On : Wed Jul 3 11:07:00 2019
13// Update Count : 3
14//
15
16#include <cassert>
17#include <limits>
18#include <type_traits>
19
20#include "AST/Pass.hpp"
21#include "AST/Type.hpp"
22
23namespace ResolvExpr {
24
25namespace {
26
27const ast::Type * expr_result( const ast::ptr< ast::Expr > & expr ) {
28 return expr->result.get();
29}
30
31const ast::Type * type_deref( const ast::ptr< ast::Type > & type ) {
32 return type.get();
33}
34
35/// The specialization counter inner class.
36class SpecCounter : public ast::WithShortCircuiting, public ast::WithVisitorRef<SpecCounter> {
37 int count = -1; ///< specialization count (-1 for none)
38
39 // Converts the max value to -1 (none), otherwise increments the value.
40 static int toNoneOrInc( int value ) {
41 assert( 0 <= value );
42 return value < std::numeric_limits<int>::max() ? value + 1 : -1;
43 }
44
45 template<typename T> using MapperT =
46 typename std::add_pointer<ast::Type const *(typename T::value_type const &)>::type;
47
48 // Update the minimum to the new lowest non-none value.
49 template<typename T>
50 void updateMinimumPresent( int & minimum, const T & list, MapperT<T> mapper ) {
51 for ( const auto & node : list ) {
52 count = -1;
53
54 if ( ast::Type const * type = mapper( node ) ) {
55 ast::Type const * newType = type->accept( *visitor );
56 assert( newType == nullptr || newType == type );
57 }
58
59 if ( count != -1 && count < minimum ) minimum = count;
60 }
61 }
62
63 // Returns minimum non-negative count + 1 over type parameters (-1 if none such).
64 template<typename T>
65 int minimumPresent( const T & list, MapperT<T> mapper ) {
66 int minCount = std::numeric_limits<int>::max();
67 updateMinimumPresent( minCount, list, mapper );
68 return toNoneOrInc( minCount );
69 }
70
71public:
72 int result() const { return 0 <= count ? count : 0; }
73
74 // Mark specialization of base type.
75 void postvisit( const ast::PointerType * ) { if ( 0 <= count ) ++count; }
76 void postvisit( const ast::ArrayType * ) { if ( 0 <= count ) ++count; }
77 void postvisit( const ast::ReferenceType * ) { if ( 0 <= count ) ++count; }
78
79 void postvisit( const ast::StructInstType * ) { if ( 0 <= count ) ++count; }
80 void postvisit( const ast::UnionInstType * ) { if ( 0 <= count ) ++count; }
81
82 // Use the minimal specialization value over returns and params.
83 void previsit( const ast::FunctionType * fty ) {
84 int minCount = std::numeric_limits<int>::max();
85 updateMinimumPresent( minCount, fty->params, type_deref );
86 updateMinimumPresent( minCount, fty->returns, type_deref );
87 // Add another level to minCount if set.
88 count = toNoneOrInc( minCount );
89 // We have already visited children.
90 visit_children = false;
91 }
92
93 // Look for polymorphic parameters.
94 void previsit( const ast::StructInstType * sty ) {
95 count = minimumPresent( sty->params, expr_result );
96 }
97
98 // Look for polymorphic parameters.
99 void previsit( const ast::UnionInstType * uty ) {
100 count = minimumPresent( uty->params, expr_result );
101 }
102
103 // Note polymorphic type (which may be specialized).
104 // xxx - maybe account for open/closed type variables
105 void postvisit( const ast::TypeInstType * ) { count = 0; }
106
107 // Use the minimal specialization over elements.
108 // xxx - maybe don't increment, tuple flattening doesn't necessarily specialize
109 void previsit( const ast::TupleType * tty ) {
110 count = minimumPresent( tty->types, type_deref );
111 visit_children = false;
112 }
113};
114
115} // namespace
116
117int specCost( const ast::Type * type ) {
118 return ( nullptr == type ) ? 0 : ast::Pass<SpecCounter>::read( type );
119}
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.