Ignore:
Timestamp:
Sep 26, 2017, 11:27:38 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
5dc26f5
Parents:
201aeb9
Message:

merge

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Waitfor.cc

    r201aeb9 rd67cdb7  
    2727#include "InitTweak/InitTweak.h"   // for getPointerBase
    2828#include "Parser/LinkageSpec.h"    // for Cforall
    29 #include "SymTab/AddVisit.h"       // for acceptAndAdd
     29#include "ResolvExpr/Resolver.h"   // for findVoidExpression
    3030#include "SynTree/Constant.h"      // for Constant
    3131#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     
    112112        //=============================================================================================
    113113
    114         class GenerateWaitForPass final : public WithStmtsToAdd {
     114        class GenerateWaitForPass final : public WithIndexer {
    115115          public:
    116116
     
    126126
    127127                ObjectDecl * declare( unsigned long count, CompoundStmt * stmt );
     128                ObjectDecl * declareFlag( CompoundStmt * stmt );
     129                Statement  * makeSetter( ObjectDecl * flag );
    128130                ObjectDecl * declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt );
    129                 void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt );
    130                 Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt );
    131                 Expression * call();
    132                 void choose();
     131                void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * settter, CompoundStmt * stmt );
     132                Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, Statement * settter, CompoundStmt * stmt );
     133                Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt);
     134                void         choose( WaitForStmt * waitfor, Expression  * result, CompoundStmt * stmt );
    133135
    134136                static void implement( std::list< Declaration * > & translationUnit ) {
     
    140142          private:
    141143                FunctionDecl        * decl_waitfor    = nullptr;
     144                StructDecl          * decl_mask       = nullptr;
    142145                StructDecl          * decl_acceptable = nullptr;
    143146                StructDecl          * decl_monitor    = nullptr;
    144                 DeclarationWithType * decl_m_func     = nullptr;
    145                 DeclarationWithType * decl_m_count    = nullptr;
    146                 DeclarationWithType * decl_m_monitors = nullptr;
    147                 DeclarationWithType * decl_m_isdtor   = nullptr;
    148147
    149148                static std::unique_ptr< Type > generic_func;
    150149
     150                UniqueName namer_acc = "__acceptables_"s;
     151                UniqueName namer_idx = "__index_"s;
     152                UniqueName namer_flg = "__do_run_"s;
     153                UniqueName namer_msk = "__mask_"s;
    151154                UniqueName namer_mon = "__monitors_"s;
    152                 UniqueName namer_acc = "__acceptables_"s;
    153155                UniqueName namer_tim = "__timeout_"s;
    154156        };
     
    167169        namespace {
    168170                Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) {
    169                         return new ApplicationExpr(
     171                        return new UntypedExpr(
    170172                                new NameExpr( "?[?]" ),
    171173                                {
     
    177179
    178180                Expression * makeOpAssign( Expression * lhs, Expression * rhs ) {
    179                         return new ApplicationExpr(
     181                        return new UntypedExpr(
    180182                                        new NameExpr( "?=?" ),
    181183                                        { lhs, rhs }
     
    183185                }
    184186
    185                 Expression * makeOpMember( Expression * sue, DeclarationWithType * mem ) {
    186                         return new MemberExpr( mem, sue );
    187                 }
    188 
    189                 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, DeclarationWithType * member, Expression * value ) {
    190                         return new ExprStmt(
    191                                 noLabels,
    192                                 makeOpAssign(
    193                                         makeOpMember(
    194                                                 makeOpIndex(
    195                                                         object,
    196                                                         index
    197                                                 ),
    198                                                 member
     187                Expression * makeOpMember( Expression * sue, const std::string & mem ) {
     188                        return new UntypedMemberExpr( new NameExpr( mem ), sue );
     189                }
     190
     191                Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) {
     192                        std::unique_ptr< Expression > expr( makeOpAssign(
     193                                makeOpMember(
     194                                        makeOpIndex(
     195                                                object,
     196                                                index
    199197                                        ),
    200                                         value
    201                                 )
    202                         );
     198                                        member
     199                                ),
     200                                value
     201                        ) );
     202
     203                        return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) );
    203204                }
    204205
     
    208209                        return new ConstantExpr( Constant::from_bool( ifnull ) );
    209210                }
     211
     212                VariableExpr * extractVariable( Expression * func ) {
     213                        if( VariableExpr * var = dynamic_cast< VariableExpr * >( func ) ) {
     214                                return var;
     215                        }
     216
     217                        CastExpr * cast = strict_dynamic_cast< CastExpr * >( func );
     218                        return strict_dynamic_cast< VariableExpr * >( cast->arg );
     219                }
     220
     221                Expression * detectIsDtor( Expression * func ) {
     222                        VariableExpr * typed_func = extractVariable( func );
     223                        bool is_dtor = InitTweak::isDestructor( typed_func->var );
     224                        return new ConstantExpr( Constant::from_bool( is_dtor ) );
     225                }
    210226        };
    211227
     
    216232
    217233        void GenerateWaitForPass::premutate( FunctionDecl * decl) {
    218                 if( decl->name != "__accept_internal" ) return;
     234                if( decl->name != "__waitfor_internal" ) return;
    219235
    220236                decl_waitfor = decl;
     
    227243                        assert( !decl_acceptable );
    228244                        decl_acceptable = decl;
    229                         for( Declaration * field : decl_acceptable->members ) {
    230                                      if( field->name == "func"    ) decl_m_func     = strict_dynamic_cast< DeclarationWithType * >( field );
    231                                 else if( field->name == "count"   ) decl_m_count    = strict_dynamic_cast< DeclarationWithType * >( field );
    232                                 else if( field->name == "monitor" ) decl_m_monitors = strict_dynamic_cast< DeclarationWithType * >( field );
    233                                 else if( field->name == "is_dtor" ) decl_m_isdtor   = strict_dynamic_cast< DeclarationWithType * >( field );
    234                         }
    235 
     245                }
     246                else if( decl->name == "__waitfor_mask_t" ) {
     247                        assert( !decl_mask );
     248                        decl_mask = decl;
    236249                }
    237250                else if( decl->name == "monitor_desc" ) {
     
    242255
    243256        Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
    244                 return waitfor;
    245 
    246                 if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
     257                if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
    247258
    248259                CompoundStmt * stmt = new CompoundStmt( noLabels );
    249260
    250261                ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt );
     262                ObjectDecl * flag        = declareFlag( stmt );
     263                Statement  * setter      = makeSetter( flag );
    251264
    252265                int index = 0;
    253266                for( auto & clause : waitfor->clauses ) {
    254                         init( acceptables, index, clause, stmt );
     267                        init( acceptables, index, clause, setter, stmt );
    255268
    256269                        index++;
     
    262275                        waitfor->orelse .statement,
    263276                        waitfor->orelse .condition,
     277                        setter,
    264278                        stmt
    265279                );
    266280
    267                 // Expression * result  = call( acceptables, timeout, orelse, stmt );
    268 
    269                 // choose( waitfor, result );
     281                CompoundStmt * compound = new CompoundStmt( noLabels );
     282                stmt->push_back( new IfStmt(
     283                        noLabels,
     284                        safeCond( new VariableExpr( flag ) ),
     285                        compound,
     286                        nullptr
     287                ));
     288
     289                Expression * result = call( waitfor->clauses.size(), acceptables, timeout, compound );
     290
     291                choose( waitfor, result, compound );
    270292
    271293                return stmt;
     
    274296        ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt )
    275297        {
    276                 ObjectDecl * acceptables = new ObjectDecl(
     298                ObjectDecl * acceptables = ObjectDecl::newObject(
    277299                        namer_acc.newName(),
    278                         noStorage,
    279                         LinkageSpec::Cforall,
    280                         nullptr,
    281300                        new ArrayType(
    282301                                noQualifiers,
     
    294313                stmt->push_back( new DeclStmt( noLabels, acceptables) );
    295314
     315                UntypedExpr * set = new UntypedExpr(
     316                        new NameExpr( "__builtin_memset" ),
     317                        {
     318                                new VariableExpr( acceptables ),
     319                                new ConstantExpr( Constant::from_int( 0 ) ),
     320                                new SizeofExpr( new VariableExpr( acceptables ) )
     321                        }
     322                );
     323
     324                Expression * resolved_set = ResolvExpr::findVoidExpression( set, indexer );
     325                delete set;
     326
     327                stmt->push_back( new ExprStmt( noLabels, resolved_set ) );
     328
    296329                return acceptables;
    297330        }
    298331
     332        ObjectDecl * GenerateWaitForPass::declareFlag( CompoundStmt * stmt ) {
     333                ObjectDecl * flag = ObjectDecl::newObject(
     334                        namer_flg.newName(),
     335                        new BasicType(
     336                                noQualifiers,
     337                                BasicType::Bool
     338                        ),
     339                        new SingleInit( new ConstantExpr( Constant::from_ulong( 0 ) ) )
     340                );
     341
     342                stmt->push_back( new DeclStmt( noLabels, flag) );
     343
     344                return flag;
     345        }
     346
     347        Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) {
     348                Expression * untyped = new UntypedExpr(
     349                        new NameExpr( "?=?" ),
     350                        {
     351                                new VariableExpr( flag ),
     352                                new ConstantExpr( Constant::from_ulong( 1 ) )
     353                        }
     354                );
     355
     356                Expression * expr = ResolvExpr::findVoidExpression( untyped, indexer );
     357                delete untyped;
     358
     359                return new ExprStmt( noLabels, expr );
     360        }
     361
    299362        ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
    300363
    301                 ObjectDecl * mon = new ObjectDecl(
     364                ObjectDecl * mon = ObjectDecl::newObject(
    302365                        namer_mon.newName(),
    303                         noStorage,
    304                         LinkageSpec::Cforall,
    305                         nullptr,
    306366                        new ArrayType(
    307367                                noQualifiers,
    308                                 new StructInstType(
     368                                new PointerType(
    309369                                        noQualifiers,
    310                                         decl_monitor
     370                                        new StructInstType(
     371                                                noQualifiers,
     372                                                decl_monitor
     373                                        )
    311374                                ),
    312375                                new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ),
     
    316379                        new ListInit(
    317380                                map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){
    318                                         return new SingleInit( expr );
     381                                        Expression * untyped = new CastExpr(
     382                                                new UntypedExpr(
     383                                                        new NameExpr( "get_monitor" ),
     384                                                        { expr }
     385                                                ),
     386                                                new PointerType(
     387                                                        noQualifiers,
     388                                                        new StructInstType(
     389                                                                noQualifiers,
     390                                                                decl_monitor
     391                                                        )
     392                                                )
     393                                        );
     394
     395                                        Expression * init = ResolvExpr::findSingleExpression( untyped, indexer );
     396                                        delete untyped;
     397                                        return new SingleInit( init );
    319398                                })
    320399                        )
     
    326405        }
    327406
    328         void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
     407        void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * setter, CompoundStmt * stmt ) {
    329408
    330409                ObjectDecl * monitors = declMon( clause, stmt );
    331410
    332                 CompoundStmt * compound = new CompoundStmt( noLabels );
    333                 compound->push_back( makeAccStatement( acceptables, index, decl_m_func    , clause.target.function ) );
    334                 compound->push_back( makeAccStatement( acceptables, index, decl_m_count   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ) ) );
    335                 compound->push_back( makeAccStatement( acceptables, index, decl_m_monitors, new VariableExpr( monitors ) ) );
    336                 compound->push_back( makeAccStatement( acceptables, index, decl_m_isdtor  , new ConstantExpr( Constant::from_bool( true ) ) ) );
     411                Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) );
    337412
    338413                stmt->push_back( new IfStmt(
    339414                        noLabels,
    340415                        safeCond( clause.condition ),
    341                         compound,
     416                        new CompoundStmt({
     417                                makeAccStatement( acceptables, index, "is_dtor", detectIsDtor( clause.target.function )                                    , indexer ),
     418                                makeAccStatement( acceptables, index, "func"   , new CastExpr( clause.target.function, fptr_t )                            , indexer ),
     419                                makeAccStatement( acceptables, index, "list"   , new VariableExpr( monitors )                                              , indexer ),
     420                                makeAccStatement( acceptables, index, "size"   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ),
     421                                setter->clone()
     422                        }),
    342423                        nullptr
    343424                ));
     
    353434                bool has_else,
    354435                Expression *& else_cond,
     436                Statement * setter,
    355437                CompoundStmt * stmt
    356438        ) {
    357                 ObjectDecl * timeout = new ObjectDecl(
     439                ObjectDecl * timeout = ObjectDecl::newObject(
    358440                        namer_tim.newName(),
    359                         noStorage,
    360                         LinkageSpec::Cforall,
    361                         nullptr,
    362441                        new BasicType(
    363442                                noQualifiers,
     
    374453                        stmt->push_back( new IfStmt(
    375454                                noLabels,
    376                                 safeCond( else_cond ),
    377                                 new ExprStmt(
    378                                         noLabels,
    379                                         makeOpAssign(
    380                                                 new VariableExpr( timeout ),
    381                                                 time
    382                                         )
    383                                 ),
     455                                safeCond( time_cond ),
     456                                new CompoundStmt({
     457                                        new ExprStmt(
     458                                                noLabels,
     459                                                makeOpAssign(
     460                                                        new VariableExpr( timeout ),
     461                                                        time
     462                                                )
     463                                        ),
     464                                        setter->clone()
     465                                }),
    384466                                nullptr
    385467                        ));
     
    392474                                noLabels,
    393475                                safeCond( else_cond ),
    394                                 new ExprStmt(
    395                                         noLabels,
    396                                         makeOpAssign(
    397                                                 new VariableExpr( timeout ),
    398                                                 new ConstantExpr( Constant::from_ulong( 0 ) )
    399                                         )
    400                                 ),
     476                                new CompoundStmt({
     477                                        new ExprStmt(
     478                                                noLabels,
     479                                                makeOpAssign(
     480                                                        new VariableExpr( timeout ),
     481                                                        new ConstantExpr( Constant::from_ulong( 0 ) )
     482                                                )
     483                                        ),
     484                                        setter->clone()
     485                                }),
    401486                                nullptr
    402487                        ));
     
    405490                }
    406491
     492                delete setter;
     493
    407494                return new VariableExpr( timeout );
     495        }
     496
     497        Expression * GenerateWaitForPass::call(
     498                size_t count,
     499                ObjectDecl * acceptables,
     500                Expression * timeout,
     501                CompoundStmt * stmt
     502        ) {
     503                ObjectDecl * index = ObjectDecl::newObject(
     504                        namer_idx.newName(),
     505                        new BasicType(
     506                                noQualifiers,
     507                                BasicType::ShortSignedInt
     508                        ),
     509                        new SingleInit(
     510                                new ConstantExpr( Constant::from_int( -1 ) )
     511                        )
     512                );
     513
     514                stmt->push_back( new DeclStmt( noLabels, index ) );
     515
     516                ObjectDecl * mask = ObjectDecl::newObject(
     517                        namer_msk.newName(),
     518                        new StructInstType(
     519                                noQualifiers,
     520                                decl_mask
     521                        ),
     522                        new ListInit({
     523                                new SingleInit( new AddressExpr( new VariableExpr( index ) ) ),
     524                                new SingleInit( new VariableExpr( acceptables ) ),
     525                                new SingleInit( new ConstantExpr( Constant::from_ulong( count ) ) )
     526                        })
     527                );
     528
     529                stmt->push_back( new DeclStmt( noLabels, mask ) );
     530
     531                stmt->push_back( new ExprStmt(
     532                        noLabels,
     533                        new ApplicationExpr(
     534                                VariableExpr::functionPointer( decl_waitfor ),
     535                                {
     536                                        new CastExpr(
     537                                                new VariableExpr( mask ),
     538                                                new ReferenceType(
     539                                                        noQualifiers,
     540                                                        new StructInstType(
     541                                                                noQualifiers,
     542                                                                decl_mask
     543                                                        )
     544                                                )
     545                                        ),
     546                                        timeout
     547                                }
     548                        )
     549                ));
     550
     551                return new VariableExpr( index );
     552        }
     553
     554        void GenerateWaitForPass::choose(
     555                WaitForStmt * waitfor,
     556                Expression  * result,
     557                CompoundStmt * stmt
     558        ) {
     559                SwitchStmt * swtch = new SwitchStmt(
     560                        noLabels,
     561                        result,
     562                        std::list<Statement *>()
     563                );
     564
     565                unsigned long i = 0;
     566                for( auto & clause : waitfor->clauses ) {
     567                        swtch->statements.push_back(
     568                                new CaseStmt(
     569                                        noLabels,
     570                                        new ConstantExpr( Constant::from_ulong( i++ ) ),
     571                                        {
     572                                                clause.statement,
     573                                                new BranchStmt(
     574                                                        noLabels,
     575                                                        "",
     576                                                        BranchStmt::Break
     577                                                )
     578                                        }
     579                                )
     580                        );
     581                }
     582
     583                if(waitfor->timeout.statement) {
     584                        swtch->statements.push_back(
     585                                new CaseStmt(
     586                                        noLabels,
     587                                        new ConstantExpr( Constant::from_int( -2 ) ),
     588                                        {
     589                                                waitfor->timeout.statement,
     590                                                new BranchStmt(
     591                                                        noLabels,
     592                                                        "",
     593                                                        BranchStmt::Break
     594                                                )
     595                                        }
     596                                )
     597                        );
     598                }
     599
     600                if(waitfor->orelse.statement) {
     601                        swtch->statements.push_back(
     602                                new CaseStmt(
     603                                        noLabels,
     604                                        new ConstantExpr( Constant::from_int( -1 ) ),
     605                                        {
     606                                                waitfor->orelse.statement,
     607                                                new BranchStmt(
     608                                                        noLabels,
     609                                                        "",
     610                                                        BranchStmt::Break
     611                                                )
     612                                        }
     613                                )
     614                        );
     615                }
     616
     617                stmt->push_back( swtch );
    408618        }
    409619};
Note: See TracChangeset for help on using the changeset viewer.