Changeset 3d9d017


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

added cofor implementation

Location:
src
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r49ae2bc r3d9d017  
    656656        }
    657657
     658        const ast::Stmt * visit( const ast::CoforStmt * node ) override final {
     659                // There is no old-AST CoforStmt, so this should never be called.
     660                assert( !node );
     661                return nullptr;
     662        }
     663
    658664        TypeSubstitution * convertTypeSubstitution(const ast::TypeSubstitution * src) {
    659665
  • src/AST/Fwd.hpp

    r49ae2bc r3d9d017  
    6868class MutexStmt;
    6969class CorunStmt;
     70class CoforStmt;
    7071
    7172class Expr;
  • src/AST/Node.cpp

    r49ae2bc r3d9d017  
    194194template class ast::ptr_base< ast::CorunStmt, ast::Node::ref_type::weak >;
    195195template class ast::ptr_base< ast::CorunStmt, ast::Node::ref_type::strong >;
     196template class ast::ptr_base< ast::CoforStmt, ast::Node::ref_type::weak >;
     197template class ast::ptr_base< ast::CoforStmt, ast::Node::ref_type::strong >;
    196198template class ast::ptr_base< ast::Expr, ast::Node::ref_type::weak >;
    197199template class ast::ptr_base< ast::Expr, ast::Node::ref_type::strong >;
  • src/AST/Pass.hpp

    r49ae2bc r3d9d017  
    172172        const ast::Stmt *             visit( const ast::MutexStmt            * ) override final;
    173173        const ast::Stmt *             visit( const ast::CorunStmt            * ) override final;
     174        const ast::Stmt *             visit( const ast::CoforStmt            * ) override final;
    174175        const ast::Expr *             visit( const ast::ApplicationExpr      * ) override final;
    175176        const ast::Expr *             visit( const ast::UntypedExpr          * ) override final;
  • src/AST/Pass.impl.hpp

    r49ae2bc r3d9d017  
    11341134
    11351135//--------------------------------------------------------------------------
     1136// CoforStmt
     1137template< typename core_t >
     1138const ast::Stmt * ast::Pass< core_t >::visit( const ast::CoforStmt * node ) {
     1139        VISIT_START( node );
     1140
     1141        if ( __visit_children() ) {
     1142                // for statements introduce a level of scope (for the initialization)
     1143                guard_symtab guard { *this };
     1144                maybe_accept( node, &CoforStmt::inits );
     1145                maybe_accept_top( node, &CoforStmt::cond  );
     1146                maybe_accept_top( node, &CoforStmt::inc   );
     1147                maybe_accept_as_compound( node, &CoforStmt::body  );
     1148        }
     1149
     1150        VISIT_END( Stmt, node );
     1151}
     1152
     1153//--------------------------------------------------------------------------
    11361154// ApplicationExpr
    11371155template< typename core_t >
  • src/AST/Print.cpp

    r49ae2bc r3d9d017  
    934934        }
    935935
     936        virtual const ast::Stmt * visit( const ast::CoforStmt * node ) override final {
     937                os << "Cofor Statement" << endl;
     938
     939                if ( ! node->inits.empty() ) {
     940                        os << indent << "... initialization:" << endl;
     941                        ++indent;
     942                        for ( const ast::Stmt * stmt : node->inits ) {
     943                                os << indent+1;
     944                                safe_print( stmt );
     945                        }
     946                        --indent;
     947                }
     948
     949                if ( node->cond ) {
     950                        os << indent << "... condition:" << endl;
     951                        ++indent;
     952                        os << indent;
     953                        node->cond->accept( *this );
     954                        --indent;
     955                }
     956
     957                if ( node->inc ) {
     958                        os << indent << "... increment:" << endl;
     959                        ++indent;
     960                        os << indent;
     961                        node->inc->accept( *this );
     962                        --indent;
     963                }
     964
     965                if ( node->body ) {
     966                        os << indent << "... with body:" << endl;
     967                        ++indent;
     968                        os << indent;
     969                        node->body->accept( *this );
     970                        --indent;
     971                }
     972                os << endl;
     973                print( node->labels );
     974
     975                return node;
     976        }
     977
    936978        virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
    937979                ++indent;
  • src/AST/Stmt.hpp

    r49ae2bc r3d9d017  
    546546};
    547547
     548// Corun Statement
     549class CoforStmt final : public Stmt {
     550  public:
     551        std::vector<ptr<Stmt>> inits;
     552        ptr<Expr> cond;
     553        ptr<Expr> inc;
     554        ptr<Stmt> body;
     555
     556        CoforStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond,
     557                         const Expr * inc, const Stmt * body, const std::vector<Label> && label = {} )
     558                : Stmt(loc, std::move(label)), inits(std::move(inits)), cond(cond), inc(inc), body(body) {}
     559
     560        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
     561  private:
     562        CoforStmt * clone() const override { return new CoforStmt{ *this }; }
     563        MUTATE_FRIEND
     564};
     565
    548566} // namespace ast
    549567
  • src/AST/Visitor.hpp

    r49ae2bc r3d9d017  
    6060    virtual const ast::Stmt *             visit( const ast::MutexStmt            * ) = 0;
    6161    virtual const ast::Stmt *             visit( const ast::CorunStmt            * ) = 0;
     62    virtual const ast::Stmt *             visit( const ast::CoforStmt            * ) = 0;
    6263    virtual const ast::Expr *             visit( const ast::ApplicationExpr      * ) = 0;
    6364    virtual const ast::Expr *             visit( const ast::UntypedExpr          * ) = 0;
  • src/Common/CodeLocationTools.cpp

    r49ae2bc r3d9d017  
    138138    macro(MutexStmt, Stmt) \
    139139    macro(CorunStmt, Stmt) \
     140        macro(CoforStmt, Stmt) \
    140141    macro(ApplicationExpr, Expr) \
    141142    macro(UntypedExpr, Expr) \
  • 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
  • src/Parser/StatementNode.cc

    r49ae2bc r3d9d017  
    503503} // build_corun
    504504
     505ast::Stmt * build_cofor( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt ) {
     506        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
     507        buildMoveList( forctl->init, astinit );
     508
     509        ast::Expr * astcond = nullptr;                                          // maybe empty
     510        astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) );
     511
     512        ast::Expr * astincr = nullptr;                                          // maybe empty
     513        astincr = maybeMoveBuild( forctl->change );
     514        delete forctl;
     515
     516        return new ast::CoforStmt( location,
     517                std::move( astinit ),
     518                astcond,
     519                astincr,
     520                buildMoveSingle( stmt )
     521        );
     522} // build_cofor
     523
    505524// Local Variables: //
    506525// tab-width: 4 //
  • src/Parser/StatementNode.h

    r49ae2bc r3d9d017  
    106106ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
    107107ast::Stmt * build_corun( const CodeLocation &, StatementNode * stmt );
     108ast::Stmt * build_cofor( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt );
  • src/Parser/parser.yy

    r49ae2bc r3d9d017  
    17251725cofor_statement:
    17261726        COFOR '(' for_control_expression_list ')' statement
    1727                 { SemanticError( yylloc, "cofor statement is currently unimplemented." ); $$ = nullptr; }
     1727                { $$ = new StatementNode( build_cofor( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    17281728        ;
    17291729
Note: See TracChangeset for help on using the changeset viewer.