Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/KeywordsNew.cpp

    r41d3c8d r4f6dda0  
    1414//
    1515
    16 #include <iostream>
    17 
    1816#include "Concurrency/Keywords.h"
    1917
     
    2826#include "Common/Examine.h"
    2927#include "Common/utility.h"
    30 #include "Common/UniqueName.h"
    3128#include "ControlStruct/LabelGeneratorNew.hpp"
    3229#include "InitTweak/InitTweak.h"
     
    170167        const ast::StructDecl * typeid_decl = nullptr;
    171168        const ast::StructDecl * vtable_decl = nullptr;
    172 
    173169};
    174170
     
    878874
    879875// --------------------------------------------------------------------------
    880 struct MutexKeyword final : public ast::WithDeclsToAdd<> {
     876struct MutexKeyword final {
    881877        const ast::FunctionDecl * postvisit( const ast::FunctionDecl * decl );
    882878        void postvisit( const ast::StructDecl * decl );
     
    891887        ast::CompoundStmt * addStatements( const ast::CompoundStmt * body, const std::vector<ast::ptr<ast::Expr>> & args );
    892888        ast::CompoundStmt * addThreadDtorStatements( const ast::FunctionDecl* func, const ast::CompoundStmt * body, const std::vector<const ast::DeclWithType *> & args );
    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 );
     889
    895890private:
    896891        const ast::StructDecl * monitor_decl = nullptr;
     
    901896
    902897        static ast::ptr<ast::Type> generic_func;
    903 
    904         UniqueName mutex_func_namer = UniqueName("__lock_unlock_curr");
    905898};
    906899
     
    1004997
    1005998const ast::Stmt * MutexKeyword::postvisit( const ast::MutexStmt * stmt ) {
    1006         if ( !lock_guard_decl ) {
    1007                 SemanticError( stmt->location, "mutex stmt requires a header, add #include <mutex_stmt.hfa>\n" );
    1008         }
    1009999        ast::CompoundStmt * body =
    10101000                        new ast::CompoundStmt( stmt->location, { stmt->stmt } );
    1011        
    1012         return addStatements( body, stmt->mutexObjs );;
     1001        addStatements( body, stmt->mutexObjs );
     1002        return body;
    10131003}
    10141004
     
    12051195}
    12061196
    1207 // generates a cast to the void ptr to the appropriate lock type and dereferences it before calling lock or unlock on it
    1208 // used to undo the type erasure done by storing all the lock pointers as void
    1209 ast::ExprStmt * MutexKeyword::genVirtLockUnlockExpr( const std::string & fnName, ast::ptr<ast::Expr> expr, const CodeLocation & location, ast::Expr * param ) {
    1210         return new ast::ExprStmt( location,
    1211                 new ast::UntypedExpr( location,
    1212                         new ast::NameExpr( location, fnName ), {
    1213                                 ast::UntypedExpr::createDeref(
    1214                                         location,
    1215                                         new ast::CastExpr( location,
    1216                                                 param,
    1217                                                 new ast::PointerType( new ast::TypeofType( new ast::UntypedExpr(
    1218                                                         expr->location,
    1219                                                         new ast::NameExpr( expr->location, "__get_mutexstmt_lock_type" ),
    1220                                                         { expr }
    1221                                                 ) ) ),
    1222                                                 ast::GeneratedFlag::ExplicitCast
    1223                                         )
    1224                                 )
    1225                         }
    1226                 )
    1227         );
    1228 }
    1229 
    1230 ast::IfStmt * MutexKeyword::genTypeDiscrimLockUnlock( const std::string & fnName, const std::vector<ast::ptr<ast::Expr>> & args, const CodeLocation & location, ast::UntypedExpr * thisParam ) {
    1231         ast::IfStmt * outerLockIf = nullptr;
    1232         ast::IfStmt * lastLockIf = nullptr;
    1233 
    1234         //adds an if/elif clause for each lock to assign type from void ptr based on ptr address
    1235         for ( long unsigned int i = 0; i < args.size(); i++ ) {
    1236                
    1237                 ast::UntypedExpr * ifCond = new ast::UntypedExpr( location,
    1238                         new ast::NameExpr( location, "?==?" ), {
    1239                                 ast::deepCopy( thisParam ),
    1240                                 new ast::CastExpr( location, new ast::AddressExpr( location, args.at(i) ), new ast::PointerType( new ast::VoidType() ))
    1241                         }
    1242                 );
    1243 
    1244                 ast::IfStmt * currLockIf = new ast::IfStmt(
    1245                         location,
    1246                         ifCond,
    1247                         genVirtLockUnlockExpr( fnName, args.at(i), location, ast::deepCopy( thisParam ) )
    1248                 );
    1249                
    1250                 if ( i == 0 ) {
    1251                         outerLockIf = currLockIf;
    1252                 } else {
    1253                         // add ifstmt to else of previous stmt
    1254                         lastLockIf->else_ = currLockIf;
    1255                 }
    1256 
    1257                 lastLockIf = currLockIf;
    1258         }
    1259         return outerLockIf;
    1260 }
    1261 
    12621197ast::CompoundStmt * MutexKeyword::addStatements(
    12631198                const ast::CompoundStmt * body,
    12641199                const std::vector<ast::ptr<ast::Expr>> & args ) {
     1200        ast::CompoundStmt * mutBody = ast::mutate( body );
    12651201
    12661202        // Code is generated near the beginning of the compound statement.
    1267         const CodeLocation & location = body->location;
    1268 
    1269                 // final body to return
    1270         ast::CompoundStmt * newBody = new ast::CompoundStmt( location );
    1271 
    1272         // std::string lockFnName = mutex_func_namer.newName();
    1273         // std::string unlockFnName = mutex_func_namer.newName();
     1203        const CodeLocation & location = mutBody->location;
    12741204
    12751205        // Make pointer to the monitors.
     
    12791209                new ast::ArrayType(
    12801210                        new ast::PointerType(
    1281                                 new ast::VoidType()
     1211                                new ast::TypeofType(
     1212                                        new ast::UntypedExpr(
     1213                                                location,
     1214                                                new ast::NameExpr( location, "__get_type" ),
     1215                                                { args.front() }
     1216                                        )
     1217                                )
    12821218                        ),
    12831219                        ast::ConstantExpr::from_ulong( location, args.size() ),
     
    12931229                                                new ast::UntypedExpr(
    12941230                                                        expr->location,
    1295                                                         new ast::NameExpr( expr->location, "__get_mutexstmt_lock_ptr" ),
     1231                                                        new ast::NameExpr( expr->location, "__get_ptr" ),
    12961232                                                        { expr }
    12971233                                                )
     
    13061242        ast::StructInstType * lock_guard_struct =
    13071243                        new ast::StructInstType( lock_guard_decl );
    1308 
    1309         // use try stmts to lock and finally to unlock
    1310         ast::TryStmt * outerTry = nullptr;
    1311         ast::TryStmt * currentTry;
    1312         ast::CompoundStmt * lastBody = nullptr;
    1313 
    1314         // adds a nested try stmt for each lock we are locking
    1315         for ( long unsigned int i = 0; i < args.size(); i++ ) {
    1316                 ast::UntypedExpr * innerAccess = new ast::UntypedExpr(
    1317                         location,
    1318                         new ast::NameExpr( location,"?[?]" ), {
    1319                                 new ast::NameExpr( location, "__monitors" ),
    1320                                 ast::ConstantExpr::from_int( location, i )
    1321                         }
    1322                 );
    1323 
    1324                 // make the try body
    1325                 ast::CompoundStmt * currTryBody = new ast::CompoundStmt( location );
    1326                 ast::IfStmt * lockCall = genTypeDiscrimLockUnlock( "lock", args, location, innerAccess );
    1327                 currTryBody->push_back( lockCall );
    1328 
    1329                 // make the finally stmt
    1330                 ast::CompoundStmt * currFinallyBody = new ast::CompoundStmt( location );
    1331                 ast::IfStmt * unlockCall = genTypeDiscrimLockUnlock( "unlock", args, location, innerAccess );
    1332                 currFinallyBody->push_back( unlockCall );
    1333 
    1334                 // construct the current try
    1335                 currentTry = new ast::TryStmt(
    1336                         location,
    1337                         currTryBody,
    1338                         {},
    1339                         new ast::FinallyStmt( location, currFinallyBody )
    1340                 );
    1341                 if ( i == 0 ) outerTry = currentTry;
    1342                 else {
    1343                         // pushback try into the body of the outer try
    1344                         lastBody->push_back( currentTry );
    1345                 }
    1346                 lastBody = currTryBody;
    1347         }
    1348 
    1349         // push body into innermost try body
    1350         if ( lastBody != nullptr ) {
    1351                 lastBody->push_back( body );
    1352                 newBody->push_front( outerTry );
    1353         }       
    1354 
     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:
    13551258        // monitor_guard_t __guard = { __monitors, # };
    1356         newBody->push_front(
     1259        mutBody->push_front(
    13571260                new ast::DeclStmt(
    13581261                        location,
     
    13811284
    13821285        // monitor$ * __monitors[] = { get_monitor(a), get_monitor(b) };
    1383         newBody->push_front( new ast::DeclStmt( location, monitors ) );
    1384 
    1385         // // The parameter for both __lock_curr/__unlock_curr routines.
    1386         // ast::ObjectDecl * this_decl = new ast::ObjectDecl(
    1387         //      location,
    1388         //      "this",
    1389         //      new ast::PointerType( new ast::VoidType() ),
    1390         //      nullptr,
    1391         //      {},
    1392         //      ast::Linkage::Cforall
    1393         // );
    1394 
    1395         // ast::FunctionDecl * lock_decl = new ast::FunctionDecl(
    1396         //      location,
    1397         //      lockFnName,
    1398         //      { /* forall */ },
    1399         //      {
    1400         //              // Copy the declaration of this.
    1401         //              this_decl,
    1402         //      },
    1403         //      { /* returns */ },
    1404         //      nullptr,
    1405         //      0,
    1406         //      ast::Linkage::Cforall,
    1407         //      { /* attributes */ },
    1408         //      ast::Function::Inline
    1409         // );
    1410 
    1411         // ast::FunctionDecl * unlock_decl = new ast::FunctionDecl(
    1412         //      location,
    1413         //      unlockFnName,
    1414         //      { /* forall */ },
    1415         //      {
    1416         //              // Copy the declaration of this.
    1417         //              ast::deepCopy( this_decl ),
    1418         //      },
    1419         //      { /* returns */ },
    1420         //      nullptr,
    1421         //      0,
    1422         //      ast::Linkage::Cforall,
    1423         //      { /* attributes */ },
    1424         //      ast::Function::Inline
    1425         // );
    1426 
    1427         // ast::IfStmt * outerLockIf = nullptr;
    1428         // ast::IfStmt * outerUnlockIf = nullptr;
    1429         // ast::IfStmt * lastLockIf = nullptr;
    1430         // ast::IfStmt * lastUnlockIf = nullptr;
    1431 
    1432         // //adds an if/elif clause for each lock to assign type from void ptr based on ptr address
    1433         // for ( long unsigned int i = 0; i < args.size(); i++ ) {
    1434         //      ast::VariableExpr * thisParam = new ast::VariableExpr( location, InitTweak::getParamThis( lock_decl ) );
    1435         //      ast::UntypedExpr * ifCond = new ast::UntypedExpr( location,
    1436         //              new ast::NameExpr( location, "?==?" ), {
    1437         //                      thisParam,
    1438         //                      new ast::CastExpr( location, new ast::AddressExpr( location, args.at(i) ), new ast::PointerType( new ast::VoidType() ))
    1439         //              }
    1440         //      );
    1441 
    1442         //      ast::IfStmt * currLockIf = new ast::IfStmt(
    1443         //              location,
    1444         //              ast::deepCopy( ifCond ),
    1445         //              genVirtLockUnlockExpr( "lock", args.at(i), location, ast::deepCopy( thisParam ) )
    1446         //      );
    1447 
    1448         //      ast::IfStmt * currUnlockIf = new ast::IfStmt(
    1449         //              location,
    1450         //              ifCond,
    1451         //              genVirtLockUnlockExpr( "unlock", args.at(i), location, ast::deepCopy( thisParam ) )
    1452         //      );
    1453                
    1454         //      if ( i == 0 ) {
    1455         //              outerLockIf = currLockIf;
    1456         //              outerUnlockIf = currUnlockIf;
    1457         //      } else {
    1458         //              // add ifstmt to else of previous stmt
    1459         //              lastLockIf->else_ = currLockIf;
    1460         //              lastUnlockIf->else_ = currUnlockIf;
    1461         //      }
    1462 
    1463         //      lastLockIf = currLockIf;
    1464         //      lastUnlockIf = currUnlockIf;
    1465         // }
    1466        
    1467         // // add pointer typing if/elifs to body of routines
    1468         // lock_decl->stmts = new ast::CompoundStmt( location, { outerLockIf } );
    1469         // unlock_decl->stmts = new ast::CompoundStmt( location, { outerUnlockIf } );
    1470 
    1471         // // add routines to scope
    1472         // declsToAddBefore.push_back( lock_decl );
    1473         // declsToAddBefore.push_back( unlock_decl );
    1474 
    1475         // newBody->push_front(new ast::DeclStmt( location, lock_decl ));
    1476         // newBody->push_front(new ast::DeclStmt( location, unlock_decl ));
    1477 
    1478         return newBody;
     1286        mutBody->push_front( new ast::DeclStmt( location, monitors ) );
     1287
     1288        return mutBody;
    14791289}
    14801290
Note: See TracChangeset for help on using the changeset viewer.