Changeset 61e5d99


Ignore:
Timestamp:
Oct 16, 2023, 10:24:14 AM (7 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
c298079
Parents:
a97b9ed
Message:

Boxing no longer passes layout information about polymorphic types in the signature of the function. This simplifies the sub-passes in the box pass that added the arguments to the calls, the parameters to the declarations, and used the information internally. The effects in functions are less well quantified, because there are cases were the information has to be generated instead of passed in, but it is also never passed in (or generated) when not needed at all.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/BoxNew.cpp

    ra97b9ed r61e5d99  
    386386        // return value.
    387387
    388         /// Pass the extra type parameters from polymorphic generic arguments or
    389         /// return types into a function application.
    390         ast::vector<ast::Expr>::iterator passArgTypeVars(
    391                 ast::ApplicationExpr * expr, ast::Type const * parmType,
    392                 ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg,
    393                 const TypeVarMap & exprTyVars, std::set<std::string> & seenTypes );
    394         /// Passes extra type parameters into a polymorphic function application.
     388        /// Passes extra layout arguments for sized polymorphic type parameters.
    395389        ast::vector<ast::Expr>::iterator passTypeVars(
    396390                ast::ApplicationExpr * expr,
    397                 ast::Type const * polyRetType,
    398                 ast::FunctionType const * funcType,
    399                 const TypeVarMap & exprTyVars );
     391                ast::FunctionType const * funcType );
    400392        /// Wraps a function application with a new temporary for the
    401393        /// out-parameter return value.
     
    700692        // the concrete type's parameters, not the formal type's).
    701693        ast::vector<ast::Expr>::iterator argIt =
    702                 passTypeVars( mutExpr, concRetType, function, exprTypeVars );
     694                passTypeVars( mutExpr, function );
    703695        addInferredParams( mutExpr, argIt, function, exprTypeVars );
    704696
     
    812804}
    813805
    814 // arg is an in/out parameter that matches the return value.
    815 ast::vector<ast::Expr>::iterator CallAdapter::passArgTypeVars(
    816                 ast::ApplicationExpr * expr, ast::Type const * paramType,
    817                 ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg,
    818                 const TypeVarMap & exprTypeVars, std::set<std::string> & seenTypes ) {
    819         ast::Type const * polyType = isPolyType( paramType, exprTypeVars );
    820         if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    821                 return arg;
    822         }
    823 
    824         std::string typeName = Mangle::mangleType( polyType );
    825         if ( seenTypes.count( typeName ) ) return arg;
    826 
    827         arg = expr->args.insert( arg,
    828                 new ast::SizeofExpr( expr->location, ast::deepCopy( argBaseType ) )
    829         );
    830         arg++;
    831         arg = expr->args.insert( arg,
    832                 new ast::AlignofExpr( expr->location, ast::deepCopy( argBaseType ) )
    833         );
    834         arg++;
    835         if ( dynamic_cast<ast::StructInstType const *>( polyType ) ) {
    836                 auto argBaseStructType =
    837                                 dynamic_cast<ast::StructInstType const *>( argBaseType );
    838                 if ( nullptr == argBaseStructType ) {
    839                         SemanticError( expr,
    840                                 "Cannot pass non-structure type for generic struct: " );
    841                 }
    842 
    843                 // Zero-length arrays are forbidden by C, so don't pass
    844                 // offset for empty structure.
    845                 if ( !argBaseStructType->base->members.empty() ) {
    846                         arg = expr->args.insert( arg,
    847                                 new ast::OffsetPackExpr(
    848                                         expr->location,
    849                                         ast::deepCopy( argBaseStructType ) )
    850                         );
    851                         arg++;
    852                 }
    853         }
    854 
    855         seenTypes.insert( typeName );
    856         return arg;
    857 }
    858 
    859806ast::vector<ast::Expr>::iterator CallAdapter::passTypeVars(
    860807                ast::ApplicationExpr * expr,
    861                 ast::Type const * polyRetType,
    862                 ast::FunctionType const * function,
    863                 const TypeVarMap & exprTypeVars ) {
     808                ast::FunctionType const * function ) {
    864809        assert( typeSubs );
    865810        ast::vector<ast::Expr>::iterator arg = expr->args.begin();
     
    880825                        new ast::AlignofExpr( expr->location, ast::deepCopy( concrete ) ) );
    881826                arg++;
    882         }
    883 
    884         // Add size/align for generic types to parameter list.
    885         if ( !expr->func->result ) return arg;
    886         ast::FunctionType const * funcType = getFunctionType( expr->func->result );
    887         assert( funcType );
    888 
    889         // This iterator points at first original argument.
    890         ast::vector<ast::Expr>::const_iterator funcArg;
    891         // Names for generic types we've seen.
    892         std::set<std::string> seenTypes;
    893 
    894         // A polymorphic return type may need to be added to the argument list.
    895         if ( polyRetType ) {
    896                 assert( typeSubs );
    897                 auto concRetType = replaceWithConcrete( polyRetType, *typeSubs );
    898                 // TODO: This write-back may not be correct.
    899                 arg = passArgTypeVars( expr, polyRetType, concRetType,
    900                                 arg, exprTypeVars, seenTypes );
    901                 // Skip the return parameter in the argument list.
    902                 funcArg = arg + 1;
    903         } else {
    904                 funcArg = arg;
    905         }
    906 
    907         // TODO:
    908         // I believe this is (starts as) the number of original arguments to the
    909         // function with the args before funcArg all being inserted.
    910         ptrdiff_t argsToPass = std::distance( funcArg, expr->args.cend() );
    911 
    912         // Add type information args for presently unseen types in parameter list.
    913         ast::vector<ast::Type>::const_iterator funcParam = funcType->params.begin();
    914         // assert( funcType->params.size() == argsToPass );
    915         for ( ; funcParam != funcType->params.end() && 0 < argsToPass
    916                         ; ++funcParam, --argsToPass ) {
    917                 assert( 0 < argsToPass );
    918                 assert( argsToPass <= (ptrdiff_t)expr->args.size() );
    919                 ptrdiff_t index = expr->args.size() - argsToPass;
    920                 ast::Type const * argType = expr->args[index]->result;
    921                 if ( nullptr == argType ) continue;
    922                 arg = passArgTypeVars( expr, *funcParam, argType,
    923                                 arg, exprTypeVars, seenTypes );
    924827        }
    925828        return arg;
     
    15231426}
    15241427
    1525 ast::ObjectDecl * makePtr(
    1526                 CodeLocation const & location, std::string const & name ) {
    1527         return new ast::ObjectDecl( location, name,
    1528                 new ast::PointerType( makeSizeAlignType() ),
    1529                 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr );
    1530 }
    1531 
    15321428ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    15331429        TypeVarMap localTypeVars = { ast::TypeData() };
     
    15841480        mutDecl->assertions.clear();
    15851481
    1586         // Add size/align for generic parameter types to parameter list.
    1587         std::set<std::string> seenTypes;
    1588         ast::vector<ast::DeclWithType> otypeParams;
    1589         for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) {
    1590                 ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars );
    1591                 if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    1592                         continue;
    1593                 }
    1594                 std::string typeName = Mangle::mangleType( polyType );
    1595                 if ( seenTypes.count( typeName ) ) continue;
    1596                 seenTypes.insert( typeName );
    1597 
    1598                 auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) );
    1599                 otypeParams.emplace_back( sizeParam );
    1600 
    1601                 auto alignParam = makeObj( funcParam->location, alignofName( typeName ) );
    1602                 otypeParams.emplace_back( alignParam );
    1603 
    1604                 // Zero-length arrays are illegal in C, so empty structs have no
    1605                 // offset array.
    1606                 if ( auto * polyStruct =
    1607                                 dynamic_cast<ast::StructInstType const *>( polyType ) ;
    1608                                 polyStruct && !polyStruct->base->members.empty() ) {
    1609                         auto offsetParam = makePtr( funcParam->location, offsetofName( typeName ) );
    1610                         otypeParams.emplace_back( offsetParam );
    1611                 }
    1612         }
    1613 
    16141482        // Prepend each argument group. From last group to first. addAdapters
    16151483        // does do the same, it just does it itself and see all other parameters.
    16161484        spliceBegin( mutDecl->params, inferredParams );
    1617         spliceBegin( mutDecl->params, otypeParams );
    16181485        spliceBegin( mutDecl->params, layoutParams );
    16191486        addAdapters( mutDecl, localTypeVars );
     
    18151682        beginGenericScope();
    18161683        beginTypeScope( decl->type );
    1817 
    1818         // TODO: Going though dec->params does not work for some reason.
    1819         for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) {
    1820                 // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
    1821                 ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );
    1822                 if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    1823                         knownLayouts.insert( Mangle::mangleType( polyType ) );
    1824                 }
    1825         }
    18261684}
    18271685
     
    18981756        // don't mark them as known in this scope.
    18991757        expect_func_type = false;
    1900 
    1901         // Make sure that any type information passed into the function is
    1902         // accounted for.
    1903         for ( ast::ptr<ast::Type> const & funcParam : type->params ) {
    1904                 // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
    1905                 ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );
    1906                 if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    1907                         knownLayouts.insert( Mangle::mangleType( polyType ) );
    1908                 }
    1909         }
    19101758}
    19111759
Note: See TracChangeset for help on using the changeset viewer.