- Timestamp:
- Oct 7, 2022, 4:09:36 PM (19 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- d8c96a9
- Parents:
- 8c91088
- Location:
- src/GenPoly
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/GenPoly.cc
r8c91088 rc8837e5 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Sep 14 9:24:00 202213 // Update Count : 1 512 // Last Modified On : Fri Oct 7 15:25:00 2022 13 // Update Count : 16 14 14 // 15 15 … … 64 64 } 65 65 66 __attribute__((unused))67 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {68 for (auto ¶m : params) {69 auto paramType = param.strict_as<ast::TypeExpr>();70 if (isPolyType(paramType->type, tyVars, env)) return true;71 }72 return false;73 }74 75 66 /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present 76 67 bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) { … … 83 74 } 84 75 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 ) ) { 90 84 return true; 91 85 } … … 195 189 } 196 190 191 const 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 197 207 ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 198 208 type = replaceTypeInst( type, env ); … … 211 221 } 212 222 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 } 223 const 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 } 232 244 233 245 ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) { … … 236 248 return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes ); 237 249 } 250 251 const 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 } 238 257 239 258 ReferenceToType *isDynRet( FunctionType *function ) { … … 260 279 } 261 280 281 bool 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 262 293 Type *isPolyPtr( Type *type, const TypeSubstitution *env ) { 263 294 type = replaceTypeInst( type, env ); … … 311 342 return isPolyType( type, tyVars, env ); 312 343 } 344 345 ast::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 } 313 364 314 365 bool includesPolyType( Type *type, const TypeSubstitution *env ) { … … 685 736 } 686 737 687 namespace {688 // temporary hack to avoid re-implementing anything related to TyVarMap689 // 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 695 738 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) { 696 739 // is parameter is not polymorphic, don't need to box … … 703 746 } 704 747 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 } 748 bool 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 } 713 761 714 762 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) { … … 720 768 } 721 769 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 } 770 bool 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 } 730 780 731 781 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { … … 733 783 } 734 784 735 void addToTyVarMap( const ast::TypeInstType * tyVar, TyVarMap & tyVarMap) {736 tyVarMap.insert(tyVar->typeString(), convData(ast::TypeDecl::Data{tyVar->base}));737 785 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) { 786 typeVars.insert( type->typeString(), ast::TypeDecl::Data( type->base ) ); 787 } 738 788 739 789 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) { … … 747 797 } 748 798 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 799 void 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 } 760 810 761 811 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) { … … 766 816 } 767 817 818 void 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 768 825 } // namespace GenPoly 769 826 -
src/GenPoly/GenPoly.h
r8c91088 rc8837e5 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 16:03:00 202213 // Update Count : 812 // Last Modified On : Fri Oct 7 15:06:00 2022 13 // Update Count : 9 14 14 // 15 15 … … 20 20 21 21 #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... 23 24 #include "SymTab/Mangler.h" // for Mangler 24 25 #include "SynTree/Declaration.h" // for TypeDecl::Data, AggregateDecl, Type... … … 29 30 // TODO Via some tricks this works for ast::TypeDecl::Data as well. 30 31 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap; 32 using TypeVarMap = ErasableScopedMap< std::string, ast::TypeDecl::Data >; 31 33 32 34 /// Replaces a TypeInstType by its referrent in the environment, if applicable … … 39 41 /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided 40 42 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 ); 42 44 43 45 /// returns dynamic-layout type if is dynamic-layout type in tyVars, NULL otherwise; will look up substitution in env if provided 44 46 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 ); 46 48 47 49 /// true iff function has dynamic-layout return type under the given type variable map 48 50 ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &tyVars ); 51 const ast::BaseInstType *isDynRet( const ast::FunctionType * type, const TypeVarMap & typeVars ); 49 52 50 53 /// true iff function has dynamic-layout return type under the type variable map generated from its forall-parameters … … 53 56 /// A function needs an adapter if it returns a dynamic-layout value or if any of its parameters have dynamic-layout type 54 57 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr ); 58 bool needsAdapter( ast::FunctionType const * adaptee, const TypeVarMap & typeVars ); 55 59 56 60 /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided … … 59 63 /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided 60 64 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 ); 61 66 62 67 /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type, returns the base type, NULL otherwise; … … 67 72 /// N will be stored in levels, if provided, will look up substitution in env if provided 68 73 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 ); 69 75 70 76 /// true iff this type or some base of this type after dereferencing pointers is either polymorphic or a generic type with at least one … … 90 96 /// true if arg requires boxing given exprTyVars 91 97 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ); 92 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const Ty VarMap &exprTyVars, const ast::TypeSubstitution * env);98 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ); 93 99 94 100 /// true if arg requires boxing in the call to appExpr 95 101 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 ); 97 103 98 104 /// Adds the type variable `tyVar` to `tyVarMap` 99 105 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ); 106 void addToTypeVarMap( const ast::TypeDecl * type, TypeVarMap & typeVars ); 100 107 101 108 /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap` 102 109 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ); 103 void makeTy VarMap(const ast::Type * type, TyVarMap & tyVarMap);110 void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars ); 104 111 105 112 /// Prints type variable map 106 113 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 114 void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars ); 107 115 108 116 /// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType(). -
src/GenPoly/ScrubTyVars.cc
r8c91088 rc8837e5 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 16:10:00 202213 // Update Count : 412 // Last Modified On : Fri Oct 7 15:42:00 2022 13 // Update Count : 5 14 14 // 15 15 … … 128 128 public ast::WithVisitorRef<ScrubTypeVars> { 129 129 130 ScrubTypeVars( ScrubMode m, Ty VarMap const * tv ) :130 ScrubTypeVars( ScrubMode m, TypeVarMap const * tv ) : 131 131 mode ( m ), typeVars( tv ) {} 132 132 … … 148 148 ScrubMode const mode; 149 149 /// Type varriables to scrub. 150 Ty VarMap const * const typeVars;150 TypeVarMap const * const typeVars; 151 151 /// Value cached by primeBaseScrub. 152 152 ast::Type const * dynType = nullptr; … … 255 255 const ast::Node * scrubTypeVarsBase( 256 256 const ast::Node * target, 257 ScrubMode mode, const Ty VarMap * typeVars ) {257 ScrubMode mode, const TypeVarMap * typeVars ) { 258 258 if ( ScrubMode::All == mode ) { 259 259 assert( nullptr == typeVars ); … … 266 266 267 267 } // namespace 268 269 template<> 270 ast::Node const * scrubTypeVars<ast::Node>( 271 const ast::Node * target, const TypeVarMap & typeVars ) { 272 return scrubTypeVarsBase( target, ScrubMode::FromMap, &typeVars ); 273 } 274 275 template<> 276 ast::Node const * scrubTypeVarsDynamic<ast::Node>( 277 ast::Node const * target, const TypeVarMap & typeVars ) { 278 return scrubTypeVarsBase( target, ScrubMode::DynamicFromMap, &typeVars ); 279 } 268 280 269 281 template<> -
src/GenPoly/ScrubTyVars.h
r8c91088 rc8837e5 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 14:14:00 202213 // Update Count : 312 // Last Modified On : Fri Oct 7 15:51:00 2022 13 // Update Count : 4 14 14 // 15 15 … … 109 109 } 110 110 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. 114 template<typename node_t> 115 node_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. 124 template<typename node_t> 125 ast::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 111 131 /// For all polymorphic types, replaces generic types, with the appropriate 112 132 /// void type, and sizeof/alignof expressions with the proper variable. 113 133 template<typename node_t> 114 134 node_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 ) ); 116 137 } 138 139 // We specialize for Node as a base case. 140 template<> 141 ast::Node const * scrubTypeVars<ast::Node>( 142 const ast::Node * target, const TypeVarMap & typeVars ); 143 144 template<> 145 ast::Node const * scrubTypeVarsDynamic<ast::Node>( 146 ast::Node const * target, const TypeVarMap & typeVars ); 117 147 118 148 template<>
Note: See TracChangeset
for help on using the changeset viewer.