Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Corun.cpp

    r3d9d017 rcf3da24  
    2727struct CorunKeyword : public WithDeclsToAdd<>, public WithStmtsToAdd<> {
    2828    UniqueName CorunFnNamer = "__CFA_corun_lambda_"s;
    29     UniqueName CoforFnNamer = "__CFA_cofor_lambda_"s;
    30     // UniqueName CoforFnVarNamer = "__CFA_cofor_lambda_var"s;
    3129    UniqueName RunnerBlockNamer = "__CFA_corun_block_"s;
    32    
    33     string coforArgName = "__CFA_cofor_lambda_arg";
    34     string numProcsName = "__CFA_cofor_num_procs";
    35     string currProcsName = "__CFA_cofor_curr_procs";
    36     string thdArrName = "__CFA_cofor_thread_array";
    37     string loopTempName = "__CFA_cofor_loop_temp";
    38    
    3930
    4031    const StructDecl * runnerBlockDecl = nullptr;
    41     const StructDecl * coforRunnerDecl = nullptr;
    4232
    43     // Finds runner_block (corun task) and cofor_runner (cofor task) decls
     33    // Finds select_node decl
    4434    void previsit( const StructDecl * decl ) {
    4535        if ( !decl->body ) {
     
    4838            assert( !runnerBlockDecl );
    4939            runnerBlockDecl = decl;
    50         } else if ( "cofor_runner" == decl->name ) {
    51             assert( !coforRunnerDecl );
    52             coforRunnerDecl = decl;
    5340        }
    5441    }
    5542
    56     // codegen for cofor statements
    57     Stmt * postvisit( const CoforStmt * stmt ) {
    58         if ( !runnerBlockDecl || !coforRunnerDecl )
    59             SemanticError( stmt->location, "To use cofor statements add #include <cofor.hfa>\n" );
    60 
    61         if ( stmt->inits.size() != 1 )
    62             SemanticError( stmt->location, "Cofor statements must have a single initializer in the loop control\n" );
    63 
    64         if ( !stmt->body )
    65             return nullptr;
    66 
    67         const CodeLocation & loc = stmt->location;
    68         const string fnName = CoforFnNamer.newName();
    69 
    70         CompoundStmt * body = new CompoundStmt( loc );
    71 
    72         // push back cofor initializer to generated body
    73         body->push_back( deepCopy( stmt->inits.at(0) ) );
    74 
    75         CompoundStmt * fnBody = new CompoundStmt( loc );
    76 
    77         const DeclStmt * declStmtPtr = dynamic_cast<const DeclStmt *>(stmt->inits.at(0).get());
    78         if ( ! declStmtPtr )
    79             SemanticError( stmt->location, "Cofor statement initializer is somehow not a decl statement?\n" );
    80 
    81         const Decl * declPtr = dynamic_cast<const Decl *>(declStmtPtr->decl.get());
    82         if ( ! declPtr )
    83             SemanticError( stmt->location, "Cofor statement initializer is somehow not a decl?\n" );
    84 
    85         Type * initType = new TypeofType( new NameExpr( loc, declPtr->name ) );
    86 
    87         // Generates:
    88         // typeof(init) __CFA_cofor_lambda_var = *((typeof(init) *)val);
    89         fnBody->push_back( new DeclStmt( loc,
    90             new ObjectDecl( loc,
    91                 declPtr->name,
    92                 initType,
    93                 new SingleInit( loc,
    94                     UntypedExpr::createDeref( loc,
    95                         new CastExpr( loc,
    96                             new NameExpr( loc, coforArgName ),
    97                             new PointerType( initType ), ExplicitCast
    98                         )
    99                     )
    100                 )
    101             )
    102         ));
    103 
    104         // push rest of cofor body into loop lambda
    105         fnBody->push_back( deepCopy( stmt->body ) );
    106 
    107         // Generates:
    108         // void __CFA_cofor_lambda_() {
    109         //    typeof(init) __CFA_cofor_lambda_var = *((typeof(init) *)val);
    110         //    stmt->body;
    111         // }
    112         Stmt * coforLambda = new DeclStmt( loc,
    113             new FunctionDecl( loc,
    114                 fnName,                                             // name
    115                 {},                                                 // forall
    116                 {
    117                     new ObjectDecl( loc,
    118                         coforArgName,
    119                         new ast::PointerType( new ast::VoidType() )
    120                     )
    121                 },                                                  // params
    122                 {},                                                 // return
    123                 fnBody   // body
    124             )
    125         );
    126         body->push_back( coforLambda );
    127 
    128         // Generates:
    129         // unsigned __CFA_cofor_num_procs = get_proc_count();
    130         body->push_back( new DeclStmt( loc,
    131                 new ObjectDecl( loc,
    132                     numProcsName,
    133                     new BasicType( BasicType::Kind::UnsignedInt ),
    134                     new SingleInit( loc,
    135                         new UntypedExpr( loc,
    136                             new NameExpr( loc, "get_proc_count" ),
    137                             {}
    138                         )
    139                     )
    140                 )
    141             )
    142         );
    143 
    144         // Generates:
    145         // unsigned __CFA_cofor_curr_procs = 0;
    146         body->push_back( new DeclStmt( loc,
    147                 new ObjectDecl( loc,
    148                     currProcsName,
    149                     new BasicType( BasicType::Kind::UnsignedInt ),
    150                     new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
    151                 )
    152             )
    153         );
    154 
    155         // Generates:
    156         // unsigned cofor_runner __CFA_cofor_thread_array[nprocs];
    157         body->push_back( new DeclStmt( loc,
    158                 new ObjectDecl( loc,
    159                     thdArrName,
    160                     new ast::ArrayType(
    161                         new StructInstType( coforRunnerDecl ),
    162                         new NameExpr( loc, numProcsName ),
    163                         ast::FixedLen,
    164                         ast::DynamicDim
    165                     )
    166                 )
    167             )
    168         );
    169 
    170         // Generates:
    171         // start_runners( __CFA_cofor_thread_array, __CFA_cofor_num_procs, __CFA_cofor_lambda_ );
    172         body->push_back( new ExprStmt( loc,
    173             new UntypedExpr( loc,
    174                 new NameExpr( loc, "start_runners" ),
    175                 {
    176                     new NameExpr( loc, thdArrName ),
    177                     new NameExpr( loc, numProcsName ),
    178                     new NameExpr( loc, fnName )
    179                 }
    180             )
    181         ));
    182 
    183         // Generates:
    184         // typeof(initializer) * __CFA_cofor_loop_temp = malloc();
    185         CompoundStmt * forLoopBody = new CompoundStmt( loc );
    186         forLoopBody->push_back( new DeclStmt( loc,
    187                 new ObjectDecl( loc,
    188                     loopTempName,
    189                     new PointerType( initType ),
    190                     new SingleInit( loc,
    191                         new UntypedExpr( loc,
    192                             new NameExpr( loc, "malloc" ),
    193                             {}
    194                         )
    195                     )
    196                 )
    197             )
    198         );
    199 
    200         // Generates:
    201         // *__CFA_cofor_loop_temp = initializer;
    202         forLoopBody->push_back( new ExprStmt( loc,
    203             UntypedExpr::createAssign( loc,
    204                 UntypedExpr::createDeref( loc, new NameExpr( loc, loopTempName ) ),
    205                 new NameExpr( loc, declPtr->name )
    206             )
    207         ));
    208 
    209         // Generates:
    210         // send_work( __CFA_cofor_thread_array, __CFA_cofor_num_procs,
    211         //     __CFA_cofor_curr_procs, __CFA_cofor_loop_temp );
    212         forLoopBody->push_back( new ExprStmt( loc,
    213             new UntypedExpr( loc,
    214                 new NameExpr( loc, "send_work" ),
    215                 {
    216                     new NameExpr( loc, thdArrName ),
    217                     new NameExpr( loc, numProcsName ),
    218                     new NameExpr( loc, currProcsName ),
    219                     new NameExpr( loc, loopTempName )
    220                 }
    221             )
    222         ));
    223 
    224         body->push_back( new ForStmt( loc,
    225             {},
    226             deepCopy( stmt->cond ),
    227             deepCopy( stmt->inc ),
    228             forLoopBody
    229         ));
    230 
    231         // Generates:
    232         // end_runners( __CFA_cofor_thread_array, __CFA_cofor_num_procs );
    233         body->push_back( new ExprStmt( loc,
    234             new UntypedExpr( loc,
    235                 new NameExpr( loc, "end_runners" ),
    236                 {
    237                     new NameExpr( loc, thdArrName ),
    238                     new NameExpr( loc, numProcsName )
    239                 }
    240             )
    241         ));
    242 
    243         return body;
    244     }
    245 
    246     // codegen for corun statements
    24743    Stmt * postvisit( const CorunStmt * stmt ) {
    248         if ( !runnerBlockDecl || !coforRunnerDecl )
     44        if ( !runnerBlockDecl )
    24945            SemanticError( stmt->location, "To use corun statements add #include <cofor.hfa>\n" );
    25046
Note: See TracChangeset for help on using the changeset viewer.