Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/SpecializeNew.cpp

    rc36814a r9e23b446  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // SpecializeNew.cpp -- Generate thunks to specialize polymorphic functions.
     7// SpecializeNew.cpp --
    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        //}
    203208        return mut;
    204209}
     
    222227}
    223228
    224 // Restructures arguments to match the structure of the formal parameters
    225 // of the actual function. Returns the next structured argument.
     229// Restructures the arguments to match the structure of the formal parameters
     230// of the actual function. [begin, end) are the exploded arguments.
     231template<typename Iterator, typename OutIterator>
     232void 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
    226247template<typename Iterator>
    227248const ast::Expr * structureArg(
    228249                const CodeLocation& location, const ast::ptr<ast::Type> & type,
    229250                Iterator & begin, const Iterator & end ) {
    230         if ( auto tuple = type.as<ast::TupleType>() ) {
     251        if ( auto tuple = type->as<ast::TupleType>() ) {
    231252                std::vector<ast::ptr<ast::Expr>> exprs;
    232                 for ( const ast::ptr<ast::Type> & t : *tuple ) {
     253                for ( const ast::Type * t : *tuple ) {
    233254                        exprs.push_back( structureArg( location, t, begin, end ) );
    234255                }
     
    239260        }
    240261}
    241 
    242 struct 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 };
     262#endif
     263
     264namespace {
     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}
    257280
    258281const ast::Expr * SpecializeCore::createThunkFunction(
     
    268291                // Must replace only occurrences of type variables
    269292                // that occure free in the thunk's type.
     293                //ast::TypeSubstitution::ApplyResult<ast::FunctionType>
     294                //      typeSubs->applyFree( newType );
    270295                auto result = typeSubs->applyFree( newType );
    271296                newType = result.node.release();
     
    275300        using DeclVector = std::vector<ast::ptr<ast::TypeDecl>>;
    276301
     302        //const std::string & thunkName = thunkNamer.newName();
     303        //UniqueName paramNamer(thunkName + "Param");
    277304        UniqueName paramNamer( paramPrefix );
    278305
     306        //auto toParamDecl = [&location, &paramNamer]( const ast::Type * type ) {
     307        //      return new ast::ObjectDecl(
     308        //              location, paramNamer.newName(), ast::deepCopy( type ) );
     309        //};
     310
    279311        // Create new thunk with same signature as formal type.
     312
     313        // std::map<const ast::TypeDecl *, std::pair<int, int>> typeMap;
    280314        ast::Pass<TypeInstFixer> fixer;
    281315        for (const auto & kv : newType->forall) {
    282316                if (fixer.core.typeMap.count(kv->base)) {
    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;
     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;
    287319                        assertf(false, "multiple formals in specialize");
    288320                }
     
    290322                        fixer.core.typeMap[kv->base] = std::make_pair(kv->expr_id, kv->formal_usage);
    291323                }
    292         }
     324        } 
    293325
    294326        ast::CompoundStmt * thunkBody = new ast::CompoundStmt( location );
     
    313345                );
    314346
     347        // thunkFunc->accept(fixer);
    315348        thunkFunc->fixUniqueId();
     349
     350
    316351
    317352        // Thunks may be generated and not used, avoid them.
     
    340375                // Name each thunk parameter and explode it.
    341376                // These are then threaded back into the actual function call.
     377                //param->name = paramNamer.newName();
    342378                ast::DeclWithType * mutParam = ast::mutate( param.get() );
     379                // - Should be renamed earlier. -
     380                //mutParam->name = paramNamer.newName();
    343381                explodeSimple( location, new ast::VariableExpr( location, mutParam ),
    344382                        std::back_inserter( args ) );
     
    350388                argBegin = args.begin(), argEnd = args.end();
    351389        for ( const auto & actualArg : actualType->params ) {
    352                 app->args.push_back(
    353                         structureArg( location, actualArg.get(), argBegin, argEnd ) );
     390                structureArg( location, actualArg.get(), argBegin, argEnd,
     391                        std::back_inserter( app->args ) );
    354392        }
    355393        assertf( argBegin == argEnd, "Did not structure all arguments." );
     
    431469        // Create thunks for the inferred parameters.
    432470        // This is not needed for intrinsic calls, because they aren't
    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.
     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.
    438477        ast::ApplicationExpr * mut = handleExplicitParams( expr );
    439478        if ( !mut->inferred.hasParams() ) {
     
    461500        if ( specialized != expr->arg ) {
    462501                // Assume that the specialization incorporates the cast.
     502                std::cerr << expr <<std::endl;
    463503                return specialized;
    464504        } else {
Note: See TracChangeset for help on using the changeset viewer.