Changes in src/ResolvExpr/SpecCost.cc [5aa4656:1dd1bd2]
- File:
-
- 1 edited
-
src/ResolvExpr/SpecCost.cc (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/SpecCost.cc
r5aa4656 r1dd1bd2 9 9 // Author : Aaron B. Moss 10 10 // Created On : Tue Oct 02 15:50:00 2018 11 // Last Modified By : A ndrew Beach12 // Last Modified On : Wed Jun 19 10:43:00 201913 // Update Count : 211 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Tue Oct 02 15:50:00 2018 13 // Update Count : 1 14 14 // 15 15 16 16 #include <limits> 17 17 #include <list> 18 #include <type_traits>19 18 20 #include "AST/Pass.hpp"21 #include "AST/Type.hpp"22 19 #include "Common/PassVisitor.h" 23 20 #include "SynTree/Declaration.h" … … 64 61 visit_children = false; 65 62 } 66 63 67 64 private: 68 65 // returns minimum non-negative count + 1 over type parameters (-1 if none such) … … 83 80 visit_children = false; 84 81 } 85 82 86 83 // look for polymorphic parameters 87 84 void previsit(UnionInstType* uty) { … … 114 111 return counter.pass.get_count(); 115 112 } 116 117 namespace {118 /// The specialization counter inner class.119 class SpecCounter : public ast::WithShortCircuiting, public ast::WithVisitorRef<SpecCounter> {120 int count = -1; ///< specialization count (-1 for none)121 122 // Converts the max value to -1 (none), otherwise increments the value.123 static int toNoneOrInc( int value ) {124 assert( 0 <= value );125 return value < std::numeric_limits<int>::max() ? value + 1 : -1;126 }127 128 template<typename T> using MapperT =129 typename std::add_pointer<ast::Type const *(typename T::value_type const &)>::type;130 131 // Update the minimum to the new lowest non-none value.132 template<typename T>133 void updateMinimumPresent( int & minimum, const T & list, MapperT<T> mapper ) {134 for ( const auto & node : list ) {135 count = -1;136 mapper( node )->accept( *visitor );137 if ( count != -1 && count < minimum ) minimum = count;138 }139 }140 141 // Returns minimum non-negative count + 1 over type parameters (-1 if none such).142 template<typename T>143 int minimumPresent( const T & list, MapperT<T> mapper ) {144 int minCount = std::numeric_limits<int>::max();145 updateMinimumPresent( minCount, list, mapper );146 return toNoneOrInc( minCount );147 }148 149 // The three mappers:150 static const ast::Type * decl_type( const ast::ptr< ast::DeclWithType > & decl ) {151 return decl->get_type();152 }153 static const ast::Type * expr_result( const ast::ptr< ast::Expr > & expr ) {154 return expr->result;155 }156 static const ast::Type * type_deref( const ast::ptr< ast::Type > & type ) {157 return type.get();158 }159 160 public:161 int get_count() const { return 0 <= count ? count : 0; }162 163 // Mark specialization of base type.164 void postvisit( const ast::PointerType * ) { if ( count >= 0 ) ++count; }165 void postvisit( const ast::ArrayType * ) { if ( count >= 0 ) ++count; }166 void postvisit( const ast::ReferenceType * ) { if ( count >= 0 ) ++count; }167 168 // Use the minimal specialization value over returns and params.169 void previsit( const ast::FunctionType * fty ) {170 int minCount = std::numeric_limits<int>::max();171 updateMinimumPresent( minCount, fty->params, decl_type );172 updateMinimumPresent( minCount, fty->returns, decl_type );173 // Add another level to minCount if set.174 count = toNoneOrInc( minCount );175 // We have already visited children.176 visit_children = false;177 }178 179 // Look for polymorphic parameters.180 void previsit( const ast::StructInstType * sty ) {181 count = minimumPresent( sty->params, expr_result );182 visit_children = false;183 }184 185 // Look for polymorphic parameters.186 void previsit( const ast::UnionInstType * uty ) {187 count = minimumPresent( uty->params, expr_result );188 visit_children = false;189 }190 191 // Note polymorphic type (which may be specialized).192 // xxx - maybe account for open/closed type variables193 void postvisit( const ast::TypeInstType * ) { count = 0; }194 195 // Use the minimal specialization over elements.196 // xxx - maybe don't increment, tuple flattening doesn't necessarily specialize197 void previsit( const ast::TupleType * tty ) {198 count = minimumPresent( tty->types, type_deref );199 visit_children = false;200 }201 };202 203 } // namespace204 205 int specCost( const ast::Type * type ) {206 if ( nullptr == type ) {207 return 0;208 }209 ast::Pass<SpecCounter> counter;210 type->accept( *counter.pass.visitor );211 return counter.pass.get_count();212 }213 214 113 } // namespace ResolvExpr 215 114
Note:
See TracChangeset
for help on using the changeset viewer.