Changeset 3d9d017 for src/Concurrency


Ignore:
Timestamp:
Nov 6, 2023, 2:19:37 PM (23 months ago)
Author:
caparson <caparson@…>
Branches:
master
Children:
ba0e1bc
Parents:
49ae2bc
Message:

added cofor implementation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Corun.cpp

    r49ae2bc r3d9d017  
    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;
    2931    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   
    3039
    3140    const StructDecl * runnerBlockDecl = nullptr;
    32 
    33     // Finds select_node decl
     41    const StructDecl * coforRunnerDecl = nullptr;
     42
     43    // Finds runner_block (corun task) and cofor_runner (cofor task) decls
    3444    void previsit( const StructDecl * decl ) {
    3545        if ( !decl->body ) {
     
    3848            assert( !runnerBlockDecl );
    3949            runnerBlockDecl = decl;
     50        } else if ( "cofor_runner" == decl->name ) {
     51            assert( !coforRunnerDecl );
     52            coforRunnerDecl = decl;
    4053        }
    4154    }
    4255
     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
    43247    Stmt * postvisit( const CorunStmt * stmt ) {
    44         if ( !runnerBlockDecl )
     248        if ( !runnerBlockDecl || !coforRunnerDecl )
    45249            SemanticError( stmt->location, "To use corun statements add #include <cofor.hfa>\n" );
    46250
Note: See TracChangeset for help on using the changeset viewer.