Ignore:
Timestamp:
Jun 19, 2019, 11:50:35 AM (5 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
17a0ede2
Parents:
c829320 (diff), 5aa4656 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/SpecCost.cc

    rc829320 r3fc0f2a  
    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.