Changeset c8837e5 for src


Ignore:
Timestamp:
Oct 7, 2022, 4:09:36 PM (19 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, master
Children:
d8c96a9
Parents:
8c91088
Message:

Rewrite in GenPoly? to avoid mixing new AST and TyVarMap? (which internally has old AST code). Some nearby functions got writen out even though they are not used, and hence not tested.

Location:
src/GenPoly
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/GenPoly.cc

    r8c91088 rc8837e5  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Sep 14  9:24:00 2022
    13 // Update Count     : 15
     12// Last Modified On : Fri Oct  7 15:25:00 2022
     13// Update Count     : 16
    1414//
    1515
     
    6464                }
    6565
    66                 __attribute__((unused))
    67                 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
    68                         for (auto &param : params) {
    69                                 auto paramType = param.strict_as<ast::TypeExpr>();
    70                                 if (isPolyType(paramType->type, tyVars, env)) return true;
    71                         }
    72                         return false;
    73                 }
    74 
    7566                /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present
    7667                bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     
    8374                }
    8475
    85                 bool hasDynParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
    86                         for ( ast::ptr<ast::Expr> const & param : params ) {
    87                                 auto paramType = param.as<ast::TypeExpr>();
    88                                 assertf( paramType, "Aggregate parameters should be type expressions." );
    89                                 if ( isDynType( paramType->type, tyVars, typeSubs ) ) {
     76                bool hasDynParams(
     77                                const std::vector<ast::ptr<ast::Expr>> & params,
     78                                const TypeVarMap & typeVars,
     79                                const ast::TypeSubstitution * subst ) {
     80                        for ( ast::ptr<ast::Expr> const & paramExpr : params ) {
     81                                auto param = paramExpr.as<ast::TypeExpr>();
     82                                assertf( param, "Aggregate parameters should be type expressions." );
     83                                if ( isDynType( param->type.get(), typeVars, subst ) ) {
    9084                                        return true;
    9185                                }
     
    195189        }
    196190
     191const ast::Type * isPolyType( const ast::Type * type,
     192                const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
     193        type = replaceTypeInst( type, subst );
     194
     195        if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
     196                if ( typeVars.find( inst->typeString() ) != typeVars.end() ) return type;
     197        } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) {
     198                return isPolyType( array->base, subst );
     199        } else if ( auto sue = dynamic_cast< const ast::StructInstType * >( type ) ) {
     200                if ( hasPolyParams( sue->params, subst ) ) return type;
     201        } else if ( auto sue = dynamic_cast< const ast::UnionInstType * >( type ) ) {
     202                if ( hasPolyParams( sue->params, subst ) ) return type;
     203        }
     204        return nullptr;
     205}
     206
    197207        ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    198208                type = replaceTypeInst( type, env );
     
    211221        }
    212222
    213         const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
    214                 type = replaceTypeInst( type, typeSubs );
    215 
    216                 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) {
    217                         auto var = tyVars.find( inst->name );
    218                         if ( var != tyVars.end() && var->second.isComplete ) {
    219                                 return inst;
    220                         }
    221                 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
    222                         if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
    223                                 return inst;
    224                         }
    225                 } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) {
    226                         if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
    227                                 return inst;
    228                         }
    229                 }
    230                 return nullptr;
    231         }
     223const ast::BaseInstType * isDynType(
     224                const ast::Type * type, const TypeVarMap & typeVars,
     225                const ast::TypeSubstitution * subst ) {
     226        type = replaceTypeInst( type, subst );
     227
     228        if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) {
     229                auto var = typeVars.find( inst->name );
     230                if ( var != typeVars.end() && var->second.isComplete ) {
     231
     232                }
     233        } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
     234                if ( hasDynParams( inst->params, typeVars, subst ) ) {
     235                        return inst;
     236                }
     237        } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) {
     238                if ( hasDynParams( inst->params, typeVars, subst ) ) {
     239                        return inst;
     240                }
     241        }
     242        return nullptr;
     243}
    232244
    233245        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) {
     
    236248                return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
    237249        }
     250
     251const ast::BaseInstType *isDynRet(
     252                const ast::FunctionType * type, const TypeVarMap & typeVars ) {
     253        if ( type->returns.empty() ) return nullptr;
     254
     255        return isDynType( type->returns.front(), typeVars );
     256}
    238257
    239258        ReferenceToType *isDynRet( FunctionType *function ) {
     
    260279        }
    261280
     281bool needsAdapter(
     282                ast::FunctionType const * adaptee, const TypeVarMap & typeVars ) {
     283        if ( isDynRet( adaptee, typeVars ) ) return true;
     284
     285        for ( auto param : adaptee->params ) {
     286                if ( isDynType( param, typeVars ) ) {
     287                        return true;
     288                }
     289        }
     290        return false;
     291}
     292
    262293        Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
    263294                type = replaceTypeInst( type, env );
     
    311342                return isPolyType( type, tyVars, env );
    312343        }
     344
     345ast::Type const * hasPolyBase(
     346                ast::Type const * type, const TypeVarMap & typeVars,
     347                int * levels, const ast::TypeSubstitution * subst ) {
     348        int level_count = 0;
     349
     350        while ( true ) {
     351                type = replaceTypeInst( type, subst );
     352
     353                if ( auto ptr = dynamic_cast<ast::PointerType const *>( type ) ) {
     354                        type = ptr->base;
     355                        ++level_count;
     356                } else {
     357                        break;
     358                }
     359        }
     360
     361        if ( nullptr != levels ) { *levels = level_count; }
     362        return isPolyType( type, typeVars, subst );
     363}
    313364
    314365        bool includesPolyType( Type *type, const TypeSubstitution *env ) {
     
    685736}
    686737
    687         namespace {
    688                 // temporary hack to avoid re-implementing anything related to TyVarMap
    689                 // does this work? these two structs have identical definitions.
    690                 inline TypeDecl::Data convData(const ast::TypeDecl::Data & data) {
    691                         return *reinterpret_cast<const TypeDecl::Data *>(&data);
    692                 }
    693         }
    694 
    695738        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) {
    696739                // is parameter is not polymorphic, don't need to box
     
    703746        }
    704747
    705         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env) {
    706                 // is parameter is not polymorphic, don't need to box
    707                 if ( ! isPolyType( param, exprTyVars ) ) return false;
    708                 ast::ptr<ast::Type> newType = arg;
    709                 if ( env ) env->apply( newType );
    710                 // if the argument's type is polymorphic, we don't need to box again!
    711                 return ! isPolyType( newType );
    712         }
     748bool needsBoxing( const ast::Type * param, const ast::Type * arg,
     749                const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
     750        // Don't need to box if the parameter is not polymorphic.
     751        if ( !isPolyType( param, typeVars ) ) return false;
     752
     753        ast::ptr<ast::Type> newType = arg;
     754        if ( subst ) {
     755                int count = subst->apply( newType );
     756                (void)count;
     757        }
     758        // Only need to box if the argument is not also polymorphic.
     759        return !isPolyType( newType );
     760}
    713761
    714762        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) {
     
    720768        }
    721769
    722         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env) {
    723                 const ast::FunctionType * function = getFunctionType(appExpr->func->result);
    724                 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->func->result ).c_str() );
    725                 TyVarMap exprTyVars(TypeDecl::Data{});
    726                 makeTyVarMap(function, exprTyVars);
    727                 return needsBoxing(param, arg, exprTyVars, env);
    728 
    729         }
     770bool needsBoxing(
     771                const ast::Type * param, const ast::Type * arg,
     772                const ast::ApplicationExpr * expr,
     773                const ast::TypeSubstitution * subst ) {
     774        const ast::FunctionType * function = getFunctionType( expr->func->result );
     775        assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() );
     776        TypeVarMap exprTyVars = { ast::TypeDecl::Data() };
     777        makeTypeVarMap( function, exprTyVars );
     778        return needsBoxing( param, arg, exprTyVars, subst );
     779}
    730780
    731781        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
     
    733783        }
    734784
    735         void addToTyVarMap( const ast::TypeInstType * tyVar, TyVarMap & tyVarMap) {
    736                 tyVarMap.insert(tyVar->typeString(), convData(ast::TypeDecl::Data{tyVar->base}));
    737         }
     785void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) {
     786        typeVars.insert( type->typeString(), ast::TypeDecl::Data( type->base ) );
     787}
    738788
    739789        void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
     
    747797        }
    748798
    749         void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap) {
    750                 if (auto ptype = dynamic_cast<const ast::FunctionType *>(type)) {
    751                         for (auto & tyVar : ptype->forall) {
    752                                 assert (tyVar);
    753                                 addToTyVarMap(tyVar, tyVarMap);
    754                         }
    755                 }
    756                 if (auto pointer = dynamic_cast<const ast::PointerType *>(type)) {
    757                         makeTyVarMap(pointer->base, tyVarMap);
    758                 }
    759         }
     799void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars ) {
     800        if ( auto func = dynamic_cast<ast::FunctionType const *>( type ) ) {
     801                for ( auto & typeVar : func->forall ) {
     802                        assert( typeVar );
     803                        addToTypeVarMap( typeVar, typeVars );
     804                }
     805        }
     806        if ( auto pointer = dynamic_cast<ast::PointerType const *>( type ) ) {
     807                makeTypeVarMap( pointer->base, typeVars );
     808        }
     809}
    760810
    761811        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
     
    766816        }
    767817
     818void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars ) {
     819        for ( auto const & pair : typeVars ) {
     820                os << pair.first << " (" << pair.second << ") ";
     821        } // for
     822        os << std::endl;
     823}
     824
    768825} // namespace GenPoly
    769826
  • src/GenPoly/GenPoly.h

    r8c91088 rc8837e5  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 19 16:03:00 2022
    13 // Update Count     : 8
     12// Last Modified On : Fri Oct  7 15:06:00 2022
     13// Update Count     : 9
    1414//
    1515
     
    2020
    2121#include "ErasableScopedMap.h"    // for ErasableScopedMap
    22 #include "AST/Fwd.hpp"
     22#include "AST/Decl.hpp"           // for TypeDecl::Data
     23#include "AST/Fwd.hpp"            // for ApplicationExpr, BaseInstType, Func...
    2324#include "SymTab/Mangler.h"       // for Mangler
    2425#include "SynTree/Declaration.h"  // for TypeDecl::Data, AggregateDecl, Type...
     
    2930        // TODO Via some tricks this works for ast::TypeDecl::Data as well.
    3031        typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap;
     32        using TypeVarMap = ErasableScopedMap< std::string, ast::TypeDecl::Data >;
    3133
    3234        /// Replaces a TypeInstType by its referrent in the environment, if applicable
     
    3941        /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
    4042        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    41         const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env = nullptr);
     43        const ast::Type * isPolyType( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst = nullptr );
    4244
    4345        /// returns dynamic-layout type if is dynamic-layout type in tyVars, NULL otherwise; will look up substitution in env if provided
    4446        ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    45         const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs = 0 );
     47        const ast::BaseInstType *isDynType( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst = 0 );
    4648
    4749        /// true iff function has dynamic-layout return type under the given type variable map
    4850        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &tyVars );
     51        const ast::BaseInstType *isDynRet( const ast::FunctionType * type, const TypeVarMap & typeVars );
    4952
    5053        /// true iff function has dynamic-layout return type under the type variable map generated from its forall-parameters
     
    5356        /// A function needs an adapter if it returns a dynamic-layout value or if any of its parameters have dynamic-layout type
    5457        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr );
     58        bool needsAdapter( ast::FunctionType const * adaptee, const TypeVarMap & typeVars );
    5559
    5660        /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided
     
    5963        /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
    6064        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     65        const ast::Type * isPolyPtr( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * env = 0 );
    6166
    6267        /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type, returns the base type, NULL otherwise;
     
    6772        /// N will be stored in levels, if provided, will look up substitution in env if provided
    6873        Type *hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels = 0, const TypeSubstitution *env = 0 );
     74        const ast::Type * hasPolyBase( const ast::Type * type, const TypeVarMap & typeVars, int * levels = 0, const ast::TypeSubstitution * env = 0 );
    6975
    7076        /// true iff this type or some base of this type after dereferencing pointers is either polymorphic or a generic type with at least one
     
    9096        /// true if arg requires boxing given exprTyVars
    9197        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env );
    92         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env);
     98        bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst );
    9399
    94100        /// true if arg requires boxing in the call to appExpr
    95101        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env );
    96         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env);
     102        bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * expr, const ast::TypeSubstitution * subst );
    97103
    98104        /// Adds the type variable `tyVar` to `tyVarMap`
    99105        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap );
     106        void addToTypeVarMap( const ast::TypeDecl * type, TypeVarMap & typeVars );
    100107
    101108        /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
    102109        void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
    103         void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap);
     110        void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars );
    104111
    105112        /// Prints type variable map
    106113        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
     114        void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars );
    107115
    108116        /// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType().
  • src/GenPoly/ScrubTyVars.cc

    r8c91088 rc8837e5  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 19 16:10:00 2022
    13 // Update Count     : 4
     12// Last Modified On : Fri Oct  7 15:42:00 2022
     13// Update Count     : 5
    1414//
    1515
     
    128128        public ast::WithVisitorRef<ScrubTypeVars> {
    129129
    130         ScrubTypeVars( ScrubMode m, TyVarMap const * tv ) :
     130        ScrubTypeVars( ScrubMode m, TypeVarMap const * tv ) :
    131131                        mode ( m ), typeVars( tv ) {}
    132132
     
    148148        ScrubMode const mode;
    149149        /// Type varriables to scrub.
    150         TyVarMap const * const typeVars;
     150        TypeVarMap const * const typeVars;
    151151        /// Value cached by primeBaseScrub.
    152152        ast::Type const * dynType = nullptr;
     
    255255const ast::Node * scrubTypeVarsBase(
    256256                const ast::Node * target,
    257                 ScrubMode mode, const TyVarMap * typeVars ) {
     257                ScrubMode mode, const TypeVarMap * typeVars ) {
    258258        if ( ScrubMode::All == mode ) {
    259259                assert( nullptr == typeVars );
     
    266266
    267267} // namespace
     268
     269template<>
     270ast::Node const * scrubTypeVars<ast::Node>(
     271        const ast::Node * target, const TypeVarMap & typeVars ) {
     272        return scrubTypeVarsBase( target, ScrubMode::FromMap, &typeVars );
     273}
     274
     275template<>
     276ast::Node const * scrubTypeVarsDynamic<ast::Node>(
     277        ast::Node const * target, const TypeVarMap & typeVars ) {
     278        return scrubTypeVarsBase( target, ScrubMode::DynamicFromMap, &typeVars );
     279}
    268280
    269281template<>
  • src/GenPoly/ScrubTyVars.h

    r8c91088 rc8837e5  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 19 14:14:00 2022
    13 // Update Count     : 3
     12// Last Modified On : Fri Oct  7 15:51:00 2022
     13// Update Count     : 4
    1414//
    1515
     
    109109        }
    110110
     111/// For all polymorphic types with type variables in `typeVars`,
     112/// replaces generic types, dtypes, and ftypes with the appropriate void type,
     113/// and sizeof/alignof expressions with the proper variable.
     114template<typename node_t>
     115node_t const * scrubTypeVars(
     116                node_t const * target, const TypeVarMap & typeVars ) {
     117        return strict_dynamic_cast<node_t const *>(
     118                        scrubTypeVars<ast::Node>( target ) );
     119}
     120
     121/// For all dynamic-layout types with type variables in `typeVars`,
     122/// replaces generic types, dtypes, and ftypes with the appropriate void type,
     123/// and sizeof/alignof expressions with the proper variable.
     124template<typename node_t>
     125ast::Node const * scrubTypeVarsDynamic(
     126                node_t const * target, const TypeVarMap & typeVars ) {
     127        return strict_dynamic_cast<node_t const *>(
     128                        scrubTypeVarsDynamic<ast::Node>( target, typeVars ) );
     129}
     130
    111131/// For all polymorphic types, replaces generic types, with the appropriate
    112132/// void type, and sizeof/alignof expressions with the proper variable.
    113133template<typename node_t>
    114134node_t const * scrubAllTypeVars( node_t const * target ) {
    115         return strict_dynamic_cast<node_t const *>( scrubAllTypeVars<ast::Node>( target ) );
     135        return strict_dynamic_cast<node_t const *>(
     136                        scrubAllTypeVars<ast::Node>( target ) );
    116137}
     138
     139// We specialize for Node as a base case.
     140template<>
     141ast::Node const * scrubTypeVars<ast::Node>(
     142                const ast::Node * target, const TypeVarMap & typeVars );
     143
     144template<>
     145ast::Node const * scrubTypeVarsDynamic<ast::Node>(
     146                ast::Node const * target, const TypeVarMap & typeVars );
    117147
    118148template<>
Note: See TracChangeset for help on using the changeset viewer.