Changes in src/Concurrency/KeywordsNew.cpp [41d3c8d:4f6dda0]
- File:
-
- 1 edited
-
src/Concurrency/KeywordsNew.cpp (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/KeywordsNew.cpp
r41d3c8d r4f6dda0 14 14 // 15 15 16 #include <iostream>17 18 16 #include "Concurrency/Keywords.h" 19 17 … … 28 26 #include "Common/Examine.h" 29 27 #include "Common/utility.h" 30 #include "Common/UniqueName.h"31 28 #include "ControlStruct/LabelGeneratorNew.hpp" 32 29 #include "InitTweak/InitTweak.h" … … 170 167 const ast::StructDecl * typeid_decl = nullptr; 171 168 const ast::StructDecl * vtable_decl = nullptr; 172 173 169 }; 174 170 … … 878 874 879 875 // -------------------------------------------------------------------------- 880 struct MutexKeyword final : public ast::WithDeclsToAdd<>{876 struct MutexKeyword final { 881 877 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * decl ); 882 878 void postvisit( const ast::StructDecl * decl ); … … 891 887 ast::CompoundStmt * addStatements( const ast::CompoundStmt * body, const std::vector<ast::ptr<ast::Expr>> & args ); 892 888 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 895 890 private: 896 891 const ast::StructDecl * monitor_decl = nullptr; … … 901 896 902 897 static ast::ptr<ast::Type> generic_func; 903 904 UniqueName mutex_func_namer = UniqueName("__lock_unlock_curr");905 898 }; 906 899 … … 1004 997 1005 998 const 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 }1009 999 ast::CompoundStmt * body = 1010 1000 new ast::CompoundStmt( stmt->location, { stmt->stmt } ); 1011 1012 return addStatements( body, stmt->mutexObjs );;1001 addStatements( body, stmt->mutexObjs ); 1002 return body; 1013 1003 } 1014 1004 … … 1205 1195 } 1206 1196 1207 // generates a cast to the void ptr to the appropriate lock type and dereferences it before calling lock or unlock on it1208 // used to undo the type erasure done by storing all the lock pointers as void1209 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::ExplicitCast1223 )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 address1235 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 stmt1254 lastLockIf->else_ = currLockIf;1255 }1256 1257 lastLockIf = currLockIf;1258 }1259 return outerLockIf;1260 }1261 1262 1197 ast::CompoundStmt * MutexKeyword::addStatements( 1263 1198 const ast::CompoundStmt * body, 1264 1199 const std::vector<ast::ptr<ast::Expr>> & args ) { 1200 ast::CompoundStmt * mutBody = ast::mutate( body ); 1265 1201 1266 1202 // 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; 1274 1204 1275 1205 // Make pointer to the monitors. … … 1279 1209 new ast::ArrayType( 1280 1210 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 ) 1282 1218 ), 1283 1219 ast::ConstantExpr::from_ulong( location, args.size() ), … … 1293 1229 new ast::UntypedExpr( 1294 1230 expr->location, 1295 new ast::NameExpr( expr->location, "__get_ mutexstmt_lock_ptr" ),1231 new ast::NameExpr( expr->location, "__get_ptr" ), 1296 1232 { expr } 1297 1233 ) … … 1306 1242 ast::StructInstType * lock_guard_struct = 1307 1243 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: 1355 1258 // monitor_guard_t __guard = { __monitors, # }; 1356 newBody->push_front(1259 mutBody->push_front( 1357 1260 new ast::DeclStmt( 1358 1261 location, … … 1381 1284 1382 1285 // 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; 1479 1289 } 1480 1290
Note:
See TracChangeset
for help on using the changeset viewer.