Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/SpecCost.cc

    r5aa4656 r1dd1bd2  
    99// Author           : Aaron B. Moss
    1010// Created On       : Tue Oct 02 15:50:00 2018
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jun 19 10:43:00 2019
    13 // Update Count     : 2
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Tue Oct 02 15:50:00 2018
     13// Update Count     : 1
    1414//
    1515
    1616#include <limits>
    1717#include <list>
    18 #include <type_traits>
    1918
    20 #include "AST/Pass.hpp"
    21 #include "AST/Type.hpp"
    2219#include "Common/PassVisitor.h"
    2320#include "SynTree/Declaration.h"
     
    6461                        visit_children = false;
    6562                }
    66 
     63       
    6764        private:
    6865                // returns minimum non-negative count + 1 over type parameters (-1 if none such)
     
    8380                        visit_children = false;
    8481                }
    85 
     82               
    8683                // look for polymorphic parameters
    8784                void previsit(UnionInstType* uty) {
     
    114111                return counter.pass.get_count();
    115112        }
    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 variables
    193                 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 specialize
    197                 void previsit( const ast::TupleType * tty ) {
    198                         count = minimumPresent( tty->types, type_deref );
    199                         visit_children = false;
    200                 }
    201         };
    202 
    203 } // namespace
    204 
    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 
    214113} // namespace ResolvExpr
    215114
Note: See TracChangeset for help on using the changeset viewer.