Changeset 34ed17b


Ignore:
Timestamp:
Jan 30, 2023, 4:30:37 PM (22 months ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, master
Children:
1c75ef8
Parents:
77ca074
Message:

Fixed decl before use issue with actors sending messages to other actors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Actors.cpp

    r77ca074 r34ed17b  
    7373    const StructDecl ** actorDecl;
    7474    const StructDecl ** msgDecl;
     75    std::vector<FunctionDecl *> & forwardDecls;
    7576
    7677        void postvisit( const FunctionDecl * decl ) {
    77         // return if not of the form receive( param1, param2 )
    78         if ( decl->name != "receive" || decl->params.size() != 2 ) return;
     78        // return if not of the form receive( param1, param2 ) or if it is a forward decl
     79        if ( decl->name != "receive" || decl->params.size() != 2 || !decl->stmts ) return;
    7980
    8081        // the params should be references
     
    193194
    194195            // put it all together into the complete function decl from above
    195             declsToAddAfter.push_back( new FunctionDecl(
     196            FunctionDecl * sendOperatorFunction = new FunctionDecl(
    196197                decl->location,
    197198                "?|?",
     
    216217                    )
    217218                },
    218                 sendBody,               // body
     219                nullptr,               // body
    219220                { Storage::Static },    // storage
    220221                Linkage::Cforall,       // linkage
    221222                {},                     // attributes
    222223                { Function::Inline }
    223             ));
     224            );
     225           
     226            // forward decls to resolve use before decl problem for '|' routines
     227            forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) );
     228
     229            sendOperatorFunction->stmts = sendBody;
     230            declsToAddAfter.push_back( sendOperatorFunction );
    224231        }
    225232        }
     
    227234  public:
    228235    GenReceiveDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,
    229         const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl )
    230         : actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ),
    231         allocationDecl( allocationDecl ), actorDecl(actorDecl), msgDecl(msgDecl) {}
     236        const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl,
     237        std::vector<FunctionDecl *> & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),
     238        requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {}
     239};
     240
     241struct GenFwdDecls : public ast::WithDeclsToAdd<> {
     242    std::map<const StructDecl *, int> & actorStructDecls;
     243    std::map<const StructDecl *, int>  & messageStructDecls;
     244    std::vector<FunctionDecl *> & forwardDecls;
     245    bool done;
     246
     247    void postvisit( const FunctionDecl * decl ) {
     248        if ( done ) return;
     249        // return if not of the form receive( param1, param2 ) or if it is a forward decl
     250        if ( decl->name != "receive" || decl->params.size() != 2 || !decl->stmts ) return;
     251
     252        // the params should be references
     253        const ReferenceType * derivedActorRef = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
     254        const ReferenceType * derivedMsgRef = dynamic_cast<const ReferenceType *>(decl->params.at(1)->get_type());
     255        if ( !derivedActorRef || !derivedMsgRef ) return;
     256
     257        // the references should be to struct instances
     258        const StructInstType * arg1InstType = dynamic_cast<const StructInstType *>(derivedActorRef->base.get());
     259        const StructInstType * arg2InstType = dynamic_cast<const StructInstType *>(derivedMsgRef->base.get());
     260        if ( !arg1InstType || !arg2InstType ) return;
     261
     262        // If the struct instances are derived actor and message types then generate the message send routine
     263        if ( actorStructDecls.count( arg1InstType->aggr() ) && messageStructDecls.count( arg2InstType->aggr() ) ) {
     264            done = true;
     265            for ( const auto & func : forwardDecls ) {
     266                declsToAddBefore.push_back( func );
     267            }
     268        }
     269    }
     270
     271  public:
     272    GenFwdDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,
     273        std::vector<FunctionDecl *> & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),
     274        forwardDecls(forwardDecls), done(false) {}
    232275};
    233276
     
    236279    std::map<const StructDecl *, int> actorStructDecls;
    237280    std::map<const StructDecl *, int> messageStructDecls;
    238 
    239     // for setting through the passes
     281    std::vector<FunctionDecl *> forwardDecls;
     282
     283    // for storing through the passes
     284    // these are populated with various important struct decls
    240285    const StructDecl * requestDeclPtr = nullptr;
    241286    const EnumDecl * allocationDeclPtr = nullptr;
     
    257302    // it then generates the appropriate operator '|' send routines for the receive routines
    258303    Pass<GenReceiveDecls>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl,
    259         allocationDecl, actorDecl, msgDecl );
     304        allocationDecl, actorDecl, msgDecl, forwardDecls );
     305
     306    // The third pass forward declares operator '|' send routines
     307    Pass<GenFwdDecls>::run( translationUnit, actorStructDecls, messageStructDecls, forwardDecls );
    260308}
    261309
Note: See TracChangeset for help on using the changeset viewer.