Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/SpecializeNew.cpp

    r9e23b446 rc36814a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // SpecializeNew.cpp --
     7// SpecializeNew.cpp -- Generate thunks to specialize polymorphic functions.
    88//
    99// Author           : Andrew Beach
     
    201201                        *formal, *actual, getInferredParams( expr ) );
    202202        }
    203         //for ( auto pair : group_iterate( formal->params, mut->args ) ) {
    204         //      const ast::ptr<ast::Type> & formal = std::get<0>( pair );
    205         //      ast::ptr<ast::Expr> & actual = std::get<1>( pair );
    206         //      *actual = doSpecialization( (*actual)->location, *formal, *actual, getInferredParams( expr ) );
    207         //}
    208203        return mut;
    209204}
     
    227222}
    228223
    229 // Restructures the arguments to match the structure of the formal parameters
    230 // of the actual function. [begin, end) are the exploded arguments.
    231 template<typename Iterator, typename OutIterator>
    232 void structureArg( const CodeLocation & location, const ast::Type * type,
    233                 Iterator & begin, Iterator end, OutIterator out ) {
    234         if ( auto tuple = dynamic_cast<const ast::TupleType *>( type ) ) {
    235                 std::vector<ast::ptr<ast::Expr>> exprs;
    236                 for ( const ast::Type * t : *tuple ) {
    237                         structureArg( location, t, begin, end, std::back_inserter( exprs ) );
    238                 }
    239                 *out++ = new ast::TupleExpr( location, std::move( exprs ) );
    240         } else {
    241                 assertf( begin != end, "reached the end of the arguments while structuring" );
    242                 *out++ = *begin++;
    243         }
    244 }
    245 
    246 #if 0
     224// Restructures arguments to match the structure of the formal parameters
     225// of the actual function. Returns the next structured argument.
    247226template<typename Iterator>
    248227const ast::Expr * structureArg(
    249228                const CodeLocation& location, const ast::ptr<ast::Type> & type,
    250229                Iterator & begin, const Iterator & end ) {
    251         if ( auto tuple = type->as<ast::TupleType>() ) {
     230        if ( auto tuple = type.as<ast::TupleType>() ) {
    252231                std::vector<ast::ptr<ast::Expr>> exprs;
    253                 for ( const ast::Type * t : *tuple ) {
     232                for ( const ast::ptr<ast::Type> & t : *tuple ) {
    254233                        exprs.push_back( structureArg( location, t, begin, end ) );
    255234                }
     
    260239        }
    261240}
    262 #endif
    263 
    264 namespace {
    265         struct TypeInstFixer : public ast::WithShortCircuiting {
    266                 std::map<const ast::TypeDecl *, std::pair<int, int>> typeMap;
    267 
    268                 void previsit(const ast::TypeDecl *) { visit_children = false; }
    269                 const ast::TypeInstType * postvisit(const ast::TypeInstType * typeInst) {
    270                         if (typeMap.count(typeInst->base)) {
    271                                 ast::TypeInstType * newInst = mutate(typeInst);
    272                                 newInst->expr_id = typeMap[typeInst->base].first;
    273                                 newInst->formal_usage = typeMap[typeInst->base].second;
    274                                 return newInst;
    275                         }
    276                         return typeInst;
    277                 }
    278         };
    279 }
     241
     242struct TypeInstFixer final : public ast::WithShortCircuiting {
     243        std::map<const ast::TypeDecl *, std::pair<int, int>> typeMap;
     244
     245        void previsit(const ast::TypeDecl *) { visit_children = false; }
     246        const ast::TypeInstType * postvisit(const ast::TypeInstType * typeInst) {
     247                if (typeMap.count(typeInst->base)) {
     248                        ast::TypeInstType * newInst = mutate(typeInst);
     249                        auto const & pair = typeMap[typeInst->base];
     250                        newInst->expr_id = pair.first;
     251                        newInst->formal_usage = pair.second;
     252                        return newInst;
     253                }
     254                return typeInst;
     255        }
     256};
    280257
    281258const ast::Expr * SpecializeCore::createThunkFunction(
     
    291268                // Must replace only occurrences of type variables
    292269                // that occure free in the thunk's type.
    293                 //ast::TypeSubstitution::ApplyResult<ast::FunctionType>
    294                 //      typeSubs->applyFree( newType );
    295270                auto result = typeSubs->applyFree( newType );
    296271                newType = result.node.release();
     
    300275        using DeclVector = std::vector<ast::ptr<ast::TypeDecl>>;
    301276
    302         //const std::string & thunkName = thunkNamer.newName();
    303         //UniqueName paramNamer(thunkName + "Param");
    304277        UniqueName paramNamer( paramPrefix );
    305278
    306         //auto toParamDecl = [&location, &paramNamer]( const ast::Type * type ) {
    307         //      return new ast::ObjectDecl(
    308         //              location, paramNamer.newName(), ast::deepCopy( type ) );
    309         //};
    310 
    311279        // Create new thunk with same signature as formal type.
    312 
    313         // std::map<const ast::TypeDecl *, std::pair<int, int>> typeMap;
    314280        ast::Pass<TypeInstFixer> fixer;
    315281        for (const auto & kv : newType->forall) {
    316282                if (fixer.core.typeMap.count(kv->base)) {
    317                         std::cerr << location << ' ' << kv->base->name << ' ' << kv->expr_id << '_' << kv->formal_usage << ','
    318                         << fixer.core.typeMap[kv->base].first << '_' << fixer.core.typeMap[kv->base].second << std::endl;
     283                        std::cerr << location << ' ' << kv->base->name
     284                                << ' ' << kv->expr_id << '_' << kv->formal_usage
     285                                << ',' << fixer.core.typeMap[kv->base].first
     286                                << '_' << fixer.core.typeMap[kv->base].second << std::endl;
    319287                        assertf(false, "multiple formals in specialize");
    320288                }
     
    322290                        fixer.core.typeMap[kv->base] = std::make_pair(kv->expr_id, kv->formal_usage);
    323291                }
    324         } 
     292        }
    325293
    326294        ast::CompoundStmt * thunkBody = new ast::CompoundStmt( location );
     
    345313                );
    346314
    347         // thunkFunc->accept(fixer);
    348315        thunkFunc->fixUniqueId();
    349 
    350 
    351316
    352317        // Thunks may be generated and not used, avoid them.
     
    375340                // Name each thunk parameter and explode it.
    376341                // These are then threaded back into the actual function call.
    377                 //param->name = paramNamer.newName();
    378342                ast::DeclWithType * mutParam = ast::mutate( param.get() );
    379                 // - Should be renamed earlier. -
    380                 //mutParam->name = paramNamer.newName();
    381343                explodeSimple( location, new ast::VariableExpr( location, mutParam ),
    382344                        std::back_inserter( args ) );
     
    388350                argBegin = args.begin(), argEnd = args.end();
    389351        for ( const auto & actualArg : actualType->params ) {
    390                 structureArg( location, actualArg.get(), argBegin, argEnd,
    391                         std::back_inserter( app->args ) );
     352                app->args.push_back(
     353                        structureArg( location, actualArg.get(), argBegin, argEnd ) );
    392354        }
    393355        assertf( argBegin == argEnd, "Did not structure all arguments." );
     
    469431        // Create thunks for the inferred parameters.
    470432        // This is not needed for intrinsic calls, because they aren't
    471         // actually passed
    472         //
    473         // need to handle explicit params before inferred params so that
    474         // explicit params do not recieve a changed set of inferParams (and
    475         // change them again) alternatively, if order starts to matter then
    476         // copy appExpr's inferParams and pass them to handleExplicitParams.
     433        // actually passed to the function. It needs to handle explicit params
     434        // before inferred params so that explicit params do not recieve a
     435        // changed set of inferParams (and change them again).
     436        // Alternatively, if order starts to matter then copy expr's inferParams
     437        // and pass them to handleExplicitParams.
    477438        ast::ApplicationExpr * mut = handleExplicitParams( expr );
    478439        if ( !mut->inferred.hasParams() ) {
     
    500461        if ( specialized != expr->arg ) {
    501462                // Assume that the specialization incorporates the cast.
    502                 std::cerr << expr <<std::endl;
    503463                return specialized;
    504464        } else {
Note: See TracChangeset for help on using the changeset viewer.