Changeset 2908f08 for src/ResolvExpr/SpecCost.cc
- Timestamp:
- Nov 17, 2023, 3:03:51 PM (10 months ago)
- Branches:
- master
- Children:
- f7f997a
- Parents:
- 41606df1
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/SpecCost.cc
r41606df1 r2908f08 33 33 } 34 34 35 36 37 35 /// The specialization counter inner class. 36 class SpecCounter : public ast::WithShortCircuiting, public ast::WithVisitorRef<SpecCounter> { 37 int count = -1; ///< specialization count (-1 for none) 38 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; 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; 43 60 } 61 } 44 62 45 template<typename T> using MapperT = 46 typename std::add_pointer<ast::Type const *(typename T::value_type const &)>::type; 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 } 47 70 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; 71 public: 72 int result() const { return 0 <= count ? count : 0; } 53 73 54 if ( ast::Type const * type = mapper( node ) ) {55 ast::Type const * newType = type->accept( *visitor );56 assert( newType == nullptr || newType == type );57 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; } 58 78 59 if ( count != -1 && count < minimum ) minimum = count; 60 } 61 } 79 void postvisit( const ast::StructInstType * ) { if ( 0 <= count ) ++count; } 80 void postvisit( const ast::UnionInstType * ) { if ( 0 <= count ) ++count; } 62 81 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 } 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 } 70 92 71 public: 72 int result() const { return 0 <= count ? count : 0; } 93 // Look for polymorphic parameters. 94 void previsit( const ast::StructInstType * sty ) { 95 count = minimumPresent( sty->params, expr_result ); 96 } 73 97 74 // Mark specialization of base type.75 void postvisit( const ast::PointerType * ) { if ( count >= 0 ) ++count; }76 void postvisit( const ast::ArrayType * ) { if ( count >= 0 ) ++count; }77 void postvisit( const ast::ReferenceType * ) { if ( count >= 0 ) ++count;}98 // Look for polymorphic parameters. 99 void previsit( const ast::UnionInstType * uty ) { 100 count = minimumPresent( uty->params, expr_result ); 101 } 78 102 79 void postvisit( const ast::StructInstType * ) { if ( count >= 0 ) ++count; } 80 void postvisit( const ast::UnionInstType * ) { if ( count >= 0 ) ++count; } 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; } 81 106 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 }; 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 114 115 115 } // namespace
Note: See TracChangeset
for help on using the changeset viewer.