Ignore:
Timestamp:
Oct 8, 2022, 9:43:21 AM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master
Children:
b2ddaf3
Parents:
815943f (diff), d8c96a9 (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/GenPoly/GenPoly.cc

    r815943f r265e460  
    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
Note: See TracChangeset for help on using the changeset viewer.