Changeset bb666f64


Ignore:
Timestamp:
Oct 25, 2017, 4:25:20 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
13a6154
Parents:
68195a6
Message:

Fix polymorphic-to-monomorphic function specialization for casts and initializers [fixes #27]

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Specialize.cc

    r68195a6 rbb666f64  
    4545        struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
    4646                Expression * postmutate( ApplicationExpr *applicationExpr );
    47                 Expression * postmutate( AddressExpr *castExpr );
    4847                Expression * postmutate( CastExpr *castExpr );
    4948
    5049                void handleExplicitParams( ApplicationExpr *appExpr );
    5150                Expression * createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams );
    52                 Expression * doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = nullptr );
     51                Expression * doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams );
    5352
    5453                std::string paramPrefix = "_p";
     
    131130                        if ( functionParameterSize( fftype ) != functionParameterSize( aftype ) ) return false;
    132131                        // tuple-parameter sizes are the same, but actual parameter sizes differ - must tuple specialize
    133                         if ( fftype->get_parameters().size() != aftype->get_parameters().size() ) return true;
     132                        if ( fftype->parameters.size() != aftype->parameters.size() ) return true;
    134133                        // total parameter size can be the same, while individual parameters can have different structure
    135                         for ( auto params : group_iterate( fftype->get_parameters(), aftype->get_parameters() ) ) {
     134                        for ( auto params : group_iterate( fftype->parameters, aftype->parameters ) ) {
    136135                                DeclarationWithType * formal = std::get<0>(params);
    137136                                DeclarationWithType * actual = std::get<1>(params);
     
    150149                if ( needsSpecialization( formalType, actual->get_result(), env ) ) {
    151150                        if ( FunctionType *funType = getFunctionType( formalType ) ) {
    152                                 ApplicationExpr *appExpr;
    153                                 VariableExpr *varExpr;
    154                                 if ( ( appExpr = dynamic_cast<ApplicationExpr*>( actual ) ) ) {
     151                                if ( ApplicationExpr * appExpr = dynamic_cast<ApplicationExpr*>( actual ) ) {
    155152                                        return createThunkFunction( funType, appExpr->get_function(), inferParams );
    156                                 } else if ( ( varExpr = dynamic_cast<VariableExpr*>( actual ) ) ) {
     153                                } else if ( VariableExpr * varExpr = dynamic_cast<VariableExpr*>( actual ) ) {
    157154                                        return createThunkFunction( funType, varExpr, inferParams );
    158155                                } else {
     
    323320        }
    324321
    325         Expression * Specialize::postmutate( AddressExpr *addrExpr ) {
    326                 assert( addrExpr->result );
    327                 addrExpr->set_arg( doSpecialization( addrExpr->result, addrExpr->arg ) );
    328                 return addrExpr;
    329         }
    330 
    331322        Expression * Specialize::postmutate( CastExpr *castExpr ) {
    332323                if ( castExpr->result->isVoid() ) {
     
    334325                        return castExpr;
    335326                }
    336                 Expression *specialized = doSpecialization( castExpr->result, castExpr->arg );
     327                Expression *specialized = doSpecialization( castExpr->result, castExpr->arg, &castExpr->inferParams );
    337328                if ( specialized != castExpr->arg ) {
    338329                        // assume here that the specialization incorporates the cast
  • src/ResolvExpr/AlternativeFinder.cc

    r68195a6 rbb666f64  
    319319        Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    320320                Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
    321                 // if ( convCost != Cost::zero ) {
    322 
    323                 // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize
    324                 // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the
    325                 // previous line.
     321
     322                // if there is a non-zero conversion cost, ignoring poly cost, then the expression requires conversion.
     323                // ignore poly cost for now, since this requires resolution of the cast to infer parameters and this
     324                // does not currently work for the reason stated below.
    326325                Cost tmpCost = convCost;
    327326                tmpCost.incPoly( -tmpCost.get_polyCost() );
    328327                if ( tmpCost != Cost::zero ) {
     328                // if ( convCost != Cost::zero ) {
    329329                        Type *newType = formalType->clone();
    330330                        env.apply( newType );
     
    914914                                thisCost.incSafe( discardedValues );
    915915                                Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost );
    916                                 // xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative.
    917                                 // Once this works, it should be possible to infer parameters on a cast expression and specialize any function.
    918 
    919916                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    920                                 // candidates.emplace_back( std::move( newAlt ) );
    921917                        } // if
    922918                } // for
     
    12971293                                        // count one safe conversion for each value that is thrown away
    12981294                                        thisCost.incSafe( discardedValues );
    1299                                         candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
     1295                                        Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost );
     1296                                        inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    13001297                                }
    13011298                        }
  • src/ResolvExpr/Resolver.cc

    r68195a6 rbb666f64  
    593593                initExpr->expr = nullptr;
    594594                std::swap( initExpr->env, newExpr->env );
     595                std::swap( initExpr->inferParams, newExpr->inferParams ) ;
    595596                delete initExpr;
    596597
Note: See TracChangeset for help on using the changeset viewer.