Changeset 080d2d7


Ignore:
Timestamp:
Mar 21, 2022, 11:51:20 AM (2 years ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
0d4f954
Parents:
51239d1b
Message:

added changes to mutex stmt pass

Location:
src/Concurrency
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r51239d1b r080d2d7  
    12041204                                        //new TypeofType( noQualifiers, args.front()->clone() )
    12051205                                        new TypeofType( noQualifiers, new UntypedExpr(
    1206                                                         new NameExpr( "__get_type" ),
     1206                                                        new NameExpr( "__get_mutexstmt_lock_type" ),
    12071207                                                        { args.front()->clone() }
    12081208                                                )
     
    12161216                                map_range < std::list<Initializer*> > ( args, [](Expression * var ){
    12171217                                        return new SingleInit( new UntypedExpr(
    1218                                                         new NameExpr( "__get_ptr" ),
     1218                                                        new NameExpr( "__get_mutexstmt_lock_ptr" ),
    12191219                                                        { var }
    12201220                                        ) );
     
    12271227                TypeExpr * lock_type_expr = new TypeExpr(
    12281228                        new TypeofType( noQualifiers, new UntypedExpr(
    1229                                 new NameExpr( "__get_type" ),
     1229                                new NameExpr( "__get_mutexstmt_lock_type" ),
    12301230                                { args.front()->clone() }
    12311231                                )
  • src/Concurrency/KeywordsNew.cpp

    r51239d1b r080d2d7  
    1414//
    1515
     16#include <iostream>
     17
    1618#include "Concurrency/Keywords.h"
    1719
     
    2628#include "Common/Examine.h"
    2729#include "Common/utility.h"
     30#include "Common/UniqueName.h"
    2831#include "ControlStruct/LabelGeneratorNew.hpp"
    2932#include "InitTweak/InitTweak.h"
     
    167170        const ast::StructDecl * typeid_decl = nullptr;
    168171        const ast::StructDecl * vtable_decl = nullptr;
     172
    169173};
    170174
     
    874878
    875879// --------------------------------------------------------------------------
    876 struct MutexKeyword final {
     880struct MutexKeyword final : public ast::WithDeclsToAdd<> {
    877881        const ast::FunctionDecl * postvisit( const ast::FunctionDecl * decl );
    878882        void postvisit( const ast::StructDecl * decl );
     
    887891        ast::CompoundStmt * addStatements( const ast::CompoundStmt * body, const std::vector<ast::ptr<ast::Expr>> & args );
    888892        ast::CompoundStmt * addThreadDtorStatements( const ast::FunctionDecl* func, const ast::CompoundStmt * body, const std::vector<const ast::DeclWithType *> & args );
    889 
     893        ast::ExprStmt * genVirtLockUnlockExpr( const std::string & fnName, ast::ptr<ast::Expr> expr, const CodeLocation & location, ast::Expr * param);
     894        ast::IfStmt * genTypeDiscrimLockUnlock( const std::string & fnName, const std::vector<ast::ptr<ast::Expr>> & args, const CodeLocation & location, ast::UntypedExpr * thisParam );
    890895private:
    891896        const ast::StructDecl * monitor_decl = nullptr;
     
    896901
    897902        static ast::ptr<ast::Type> generic_func;
     903
     904        UniqueName mutex_func_namer = UniqueName("__lock_unlock_curr");
    898905};
    899906
     
    9991006        ast::CompoundStmt * body =
    10001007                        new ast::CompoundStmt( stmt->location, { stmt->stmt } );
    1001         addStatements( body, stmt->mutexObjs );
    1002         return body;
     1008       
     1009        return addStatements( body, stmt->mutexObjs );;
    10031010}
    10041011
     
    11951202}
    11961203
     1204// generates a cast to the void ptr to the appropriate lock type and dereferences it before calling lock or unlock on it
     1205// used to undo the type erasure done by storing all the lock pointers as void
     1206ast::ExprStmt * MutexKeyword::genVirtLockUnlockExpr( const std::string & fnName, ast::ptr<ast::Expr> expr, const CodeLocation & location, ast::Expr * param ) {
     1207        return new ast::ExprStmt( location,
     1208                new ast::UntypedExpr( location,
     1209                        new ast::NameExpr( location, fnName ), {
     1210                                ast::UntypedExpr::createDeref(
     1211                                        location,
     1212                                        new ast::CastExpr( location,
     1213                                                param,
     1214                                                new ast::PointerType( new ast::TypeofType( new ast::UntypedExpr(
     1215                                                        expr->location,
     1216                                                        new ast::NameExpr( expr->location, "__get_mutexstmt_lock_type" ),
     1217                                                        { expr }
     1218                                                ) ) ),
     1219                                                ast::GeneratedFlag::ExplicitCast
     1220                                        )
     1221                                )
     1222                        }
     1223                )
     1224        );
     1225}
     1226
     1227ast::IfStmt * MutexKeyword::genTypeDiscrimLockUnlock( const std::string & fnName, const std::vector<ast::ptr<ast::Expr>> & args, const CodeLocation & location, ast::UntypedExpr * thisParam ) {
     1228        ast::IfStmt * outerLockIf = nullptr;
     1229        ast::IfStmt * lastLockIf = nullptr;
     1230
     1231        //adds an if/elif clause for each lock to assign type from void ptr based on ptr address
     1232        for ( long unsigned int i = 0; i < args.size(); i++ ) {
     1233               
     1234                ast::UntypedExpr * ifCond = new ast::UntypedExpr( location,
     1235                        new ast::NameExpr( location, "?==?" ), {
     1236                                ast::deepCopy( thisParam ),
     1237                                new ast::CastExpr( location, new ast::AddressExpr( location, args.at(i) ), new ast::PointerType( new ast::VoidType() ))
     1238                        }
     1239                );
     1240
     1241                ast::IfStmt * currLockIf = new ast::IfStmt(
     1242                        location,
     1243                        ifCond,
     1244                        genVirtLockUnlockExpr( fnName, args.at(i), location, ast::deepCopy( thisParam ) )
     1245                );
     1246               
     1247                if ( i == 0 ) {
     1248                        outerLockIf = currLockIf;
     1249                } else {
     1250                        // add ifstmt to else of previous stmt
     1251                        lastLockIf->else_ = currLockIf;
     1252                }
     1253
     1254                lastLockIf = currLockIf;
     1255        }
     1256        return outerLockIf;
     1257}
     1258
    11971259ast::CompoundStmt * MutexKeyword::addStatements(
    11981260                const ast::CompoundStmt * body,
    11991261                const std::vector<ast::ptr<ast::Expr>> & args ) {
    1200         ast::CompoundStmt * mutBody = ast::mutate( body );
    12011262
    12021263        // Code is generated near the beginning of the compound statement.
    1203         const CodeLocation & location = mutBody->location;
     1264        const CodeLocation & location = body->location;
     1265
     1266                // final body to return
     1267        ast::CompoundStmt * newBody = new ast::CompoundStmt( location );
     1268
     1269        // std::string lockFnName = mutex_func_namer.newName();
     1270        // std::string unlockFnName = mutex_func_namer.newName();
    12041271
    12051272        // Make pointer to the monitors.
     
    12091276                new ast::ArrayType(
    12101277                        new ast::PointerType(
    1211                                 new ast::TypeofType(
    1212                                         new ast::UntypedExpr(
    1213                                                 location,
    1214                                                 new ast::NameExpr( location, "__get_type" ),
    1215                                                 { args.front() }
    1216                                         )
    1217                                 )
     1278                                new ast::VoidType()
    12181279                        ),
    12191280                        ast::ConstantExpr::from_ulong( location, args.size() ),
     
    12291290                                                new ast::UntypedExpr(
    12301291                                                        expr->location,
    1231                                                         new ast::NameExpr( expr->location, "__get_ptr" ),
     1292                                                        new ast::NameExpr( expr->location, "__get_mutexstmt_lock_ptr" ),
    12321293                                                        { expr }
    12331294                                                )
     
    12421303        ast::StructInstType * lock_guard_struct =
    12431304                        new ast::StructInstType( lock_guard_decl );
    1244         ast::TypeExpr * lock_type_expr = new ast::TypeExpr(
    1245                 location,
    1246                 new ast::TypeofType(
    1247                         new ast::UntypedExpr(
    1248                                 location,
    1249                                 new ast::NameExpr( location, "__get_type" ),
    1250                                 { args.front() }
    1251                         )
    1252                 )
    1253         );
    1254 
    1255         lock_guard_struct->params.push_back( lock_type_expr );
    1256 
    1257         // In reverse order:
     1305
     1306        // use try stmts to lock and finally to unlock
     1307        ast::TryStmt * outerTry = nullptr;
     1308        ast::TryStmt * currentTry;
     1309        ast::CompoundStmt * lastBody = nullptr;
     1310
     1311        // adds a nested try stmt for each lock we are locking
     1312        for ( long unsigned int i = 0; i < args.size(); i++ ) {
     1313                ast::UntypedExpr * innerAccess = new ast::UntypedExpr(
     1314                        location,
     1315                        new ast::NameExpr( location,"?[?]" ), {
     1316                                new ast::NameExpr( location, "__monitors" ),
     1317                                ast::ConstantExpr::from_int( location, i )
     1318                        }
     1319                );
     1320
     1321                // make the try body
     1322                ast::CompoundStmt * currTryBody = new ast::CompoundStmt( location );
     1323                ast::IfStmt * lockCall = genTypeDiscrimLockUnlock( "lock", args, location, innerAccess );
     1324                currTryBody->push_back( lockCall );
     1325
     1326                // make the finally stmt
     1327                ast::CompoundStmt * currFinallyBody = new ast::CompoundStmt( location );
     1328                ast::IfStmt * unlockCall = genTypeDiscrimLockUnlock( "unlock", args, location, innerAccess );
     1329                currFinallyBody->push_back( unlockCall );
     1330
     1331                // construct the current try
     1332                currentTry = new ast::TryStmt(
     1333                        location,
     1334                        currTryBody,
     1335                        {},
     1336                        new ast::FinallyStmt( location, currFinallyBody )
     1337                );
     1338                if ( i == 0 ) outerTry = currentTry;
     1339                else {
     1340                        // pushback try into the body of the outer try
     1341                        lastBody->push_back( currentTry );
     1342                }
     1343                lastBody = currTryBody;
     1344        }
     1345
     1346        // push body into innermost try body
     1347        if ( lastBody != nullptr ) {
     1348                lastBody->push_back( body );
     1349                newBody->push_front( outerTry );
     1350        }       
     1351
    12581352        // monitor_guard_t __guard = { __monitors, # };
    1259         mutBody->push_front(
     1353        newBody->push_front(
    12601354                new ast::DeclStmt(
    12611355                        location,
     
    12841378
    12851379        // monitor$ * __monitors[] = { get_monitor(a), get_monitor(b) };
    1286         mutBody->push_front( new ast::DeclStmt( location, monitors ) );
    1287 
    1288         return mutBody;
     1380        newBody->push_front( new ast::DeclStmt( location, monitors ) );
     1381
     1382        // // The parameter for both __lock_curr/__unlock_curr routines.
     1383        // ast::ObjectDecl * this_decl = new ast::ObjectDecl(
     1384        //      location,
     1385        //      "this",
     1386        //      new ast::PointerType( new ast::VoidType() ),
     1387        //      nullptr,
     1388        //      {},
     1389        //      ast::Linkage::Cforall
     1390        // );
     1391
     1392        // ast::FunctionDecl * lock_decl = new ast::FunctionDecl(
     1393        //      location,
     1394        //      lockFnName,
     1395        //      { /* forall */ },
     1396        //      {
     1397        //              // Copy the declaration of this.
     1398        //              this_decl,
     1399        //      },
     1400        //      { /* returns */ },
     1401        //      nullptr,
     1402        //      0,
     1403        //      ast::Linkage::Cforall,
     1404        //      { /* attributes */ },
     1405        //      ast::Function::Inline
     1406        // );
     1407
     1408        // ast::FunctionDecl * unlock_decl = new ast::FunctionDecl(
     1409        //      location,
     1410        //      unlockFnName,
     1411        //      { /* forall */ },
     1412        //      {
     1413        //              // Copy the declaration of this.
     1414        //              ast::deepCopy( this_decl ),
     1415        //      },
     1416        //      { /* returns */ },
     1417        //      nullptr,
     1418        //      0,
     1419        //      ast::Linkage::Cforall,
     1420        //      { /* attributes */ },
     1421        //      ast::Function::Inline
     1422        // );
     1423
     1424        // ast::IfStmt * outerLockIf = nullptr;
     1425        // ast::IfStmt * outerUnlockIf = nullptr;
     1426        // ast::IfStmt * lastLockIf = nullptr;
     1427        // ast::IfStmt * lastUnlockIf = nullptr;
     1428
     1429        // //adds an if/elif clause for each lock to assign type from void ptr based on ptr address
     1430        // for ( long unsigned int i = 0; i < args.size(); i++ ) {
     1431        //      ast::VariableExpr * thisParam = new ast::VariableExpr( location, InitTweak::getParamThis( lock_decl ) );
     1432        //      ast::UntypedExpr * ifCond = new ast::UntypedExpr( location,
     1433        //              new ast::NameExpr( location, "?==?" ), {
     1434        //                      thisParam,
     1435        //                      new ast::CastExpr( location, new ast::AddressExpr( location, args.at(i) ), new ast::PointerType( new ast::VoidType() ))
     1436        //              }
     1437        //      );
     1438
     1439        //      ast::IfStmt * currLockIf = new ast::IfStmt(
     1440        //              location,
     1441        //              ast::deepCopy( ifCond ),
     1442        //              genVirtLockUnlockExpr( "lock", args.at(i), location, ast::deepCopy( thisParam ) )
     1443        //      );
     1444
     1445        //      ast::IfStmt * currUnlockIf = new ast::IfStmt(
     1446        //              location,
     1447        //              ifCond,
     1448        //              genVirtLockUnlockExpr( "unlock", args.at(i), location, ast::deepCopy( thisParam ) )
     1449        //      );
     1450               
     1451        //      if ( i == 0 ) {
     1452        //              outerLockIf = currLockIf;
     1453        //              outerUnlockIf = currUnlockIf;
     1454        //      } else {
     1455        //              // add ifstmt to else of previous stmt
     1456        //              lastLockIf->else_ = currLockIf;
     1457        //              lastUnlockIf->else_ = currUnlockIf;
     1458        //      }
     1459
     1460        //      lastLockIf = currLockIf;
     1461        //      lastUnlockIf = currUnlockIf;
     1462        // }
     1463       
     1464        // // add pointer typing if/elifs to body of routines
     1465        // lock_decl->stmts = new ast::CompoundStmt( location, { outerLockIf } );
     1466        // unlock_decl->stmts = new ast::CompoundStmt( location, { outerUnlockIf } );
     1467
     1468        // // add routines to scope
     1469        // declsToAddBefore.push_back( lock_decl );
     1470        // declsToAddBefore.push_back( unlock_decl );
     1471
     1472        // newBody->push_front(new ast::DeclStmt( location, lock_decl ));
     1473        // newBody->push_front(new ast::DeclStmt( location, unlock_decl ));
     1474
     1475        return newBody;
    12891476}
    12901477
Note: See TracChangeset for help on using the changeset viewer.