Changeset 5aa4656


Ignore:
Timestamp:
Jun 19, 2019, 10:47:34 AM (2 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
arm-eh, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
3fc0f2a
Parents:
f52ce6e
Message:

Filled in SpecCost? and PolyCost? for the new ast.

Location:
src/ResolvExpr
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/PolyCost.cc

    rf52ce6e r5aa4656  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 09:50:12 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 09:52:02 2015
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jun 19 10:45:00 2019
     13// Update Count     : 4
    1414//
    1515
     
    5757        }
    5858
    59         int polyCost(
    60                 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
    61         ) {
    62                 #warning unimplemented
    63                 (void)type; (void)symtab; (void)env;
    64                 assert(false);
    65                 return 0;
     59// TODO: When the old PolyCost is torn out get rid of the _new suffix.
     60struct PolyCost_new {
     61        int result;
     62        const ast::SymbolTable &symtab;
     63        const ast::TypeEnvironment &env_;
     64
     65        PolyCost_new( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ) :
     66                result( 0 ), symtab( symtab ), env_( env ) {}
     67
     68        void previsit( const ast::TypeInstType * type ) {
     69                if ( const ast::EqvClass * eqv = env_.lookup( type->name ) ) /* && */ if ( eqv->bound ) {
     70                        if ( const ast::TypeInstType * otherType = eqv->bound.as< ast::TypeInstType >() ) {
     71                                if ( symtab.lookupType( otherType->name ) ) {
     72                                        // Bound to opaque type.
     73                                        result += 1;
     74                                }
     75                        } else {
     76                                // Bound to concrete type.
     77                                result += 1;
     78                        }
     79                }
    6680        }
     81};
     82
     83int polyCost(
     84        const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     85) {
     86        ast::Pass<PolyCost_new> costing( symtab, env );
     87        type->accept( costing );
     88        return costing.pass.result;
     89}
    6790
    6891} // namespace ResolvExpr
  • src/ResolvExpr/SpecCost.cc

    rf52ce6e r5aa4656  
    99// Author           : Aaron B. Moss
    1010// 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
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jun 19 10:43:00 2019
     13// Update Count     : 2
    1414//
    1515
    1616#include <limits>
    1717#include <list>
    18 
     18#include <type_traits>
     19
     20#include "AST/Pass.hpp"
    1921#include "AST/Type.hpp"
    2022#include "Common/PassVisitor.h"
     
    6264                        visit_children = false;
    6365                }
    64        
     66
    6567        private:
    6668                // returns minimum non-negative count + 1 over type parameters (-1 if none such)
     
    8183                        visit_children = false;
    8284                }
    83                
     85
    8486                // look for polymorphic parameters
    8587                void previsit(UnionInstType* uty) {
     
    113115        }
    114116
    115         int specCost( const ast::Type * ty ) {
    116                 #warning unimplmented
    117                 (void)ty;
    118                 assert(false);
     117namespace {
     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
     205int specCost( const ast::Type * type ) {
     206        if ( nullptr == type ) {
    119207                return 0;
    120208        }
     209        ast::Pass<SpecCounter> counter;
     210        type->accept( *counter.pass.visitor );
     211        return counter.pass.get_count();
     212}
     213
    121214} // namespace ResolvExpr
    122215
Note: See TracChangeset for help on using the changeset viewer.