Changes in src/Concurrency/Waitfor.cc [e3e16bc:08da53d]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Waitfor.cc
re3e16bc r08da53d 27 27 #include "InitTweak/InitTweak.h" // for getPointerBase 28 28 #include "Parser/LinkageSpec.h" // for Cforall 29 #include " SymTab/AddVisit.h" // for acceptAndAdd29 #include "ResolvExpr/Resolver.h" // for findVoidExpression 30 30 #include "SynTree/Constant.h" // for Constant 31 31 #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl … … 112 112 //============================================================================================= 113 113 114 class GenerateWaitForPass final : public With StmtsToAdd{114 class GenerateWaitForPass final : public WithIndexer { 115 115 public: 116 116 … … 126 126 127 127 ObjectDecl * declare( unsigned long count, CompoundStmt * stmt ); 128 ObjectDecl * declareFlag( CompoundStmt * stmt ); 129 Statement * makeSetter( ObjectDecl * flag ); 128 130 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 ); 133 135 134 136 static void implement( std::list< Declaration * > & translationUnit ) { … … 140 142 private: 141 143 FunctionDecl * decl_waitfor = nullptr; 144 StructDecl * decl_mask = nullptr; 142 145 StructDecl * decl_acceptable = nullptr; 143 146 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;148 147 149 148 static std::unique_ptr< Type > generic_func; 150 149 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; 151 154 UniqueName namer_mon = "__monitors_"s; 152 UniqueName namer_acc = "__acceptables_"s;153 155 UniqueName namer_tim = "__timeout_"s; 154 156 }; … … 167 169 namespace { 168 170 Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) { 169 return new ApplicationExpr(171 return new UntypedExpr( 170 172 new NameExpr( "?[?]" ), 171 173 { … … 177 179 178 180 Expression * makeOpAssign( Expression * lhs, Expression * rhs ) { 179 return new ApplicationExpr(181 return new UntypedExpr( 180 182 new NameExpr( "?=?" ), 181 183 { lhs, rhs } … … 183 185 } 184 186 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 Expression * expr = makeOpAssign( 193 makeOpMember( 194 makeOpIndex( 195 object, 196 index 199 197 ), 200 value 201 ) 198 member 199 ), 200 value 202 201 ); 202 203 ResolvExpr::findVoidExpression( expr, indexer ); 204 205 return new ExprStmt( noLabels, expr ); 203 206 } 204 207 … … 208 211 return new ConstantExpr( Constant::from_bool( ifnull ) ); 209 212 } 213 214 VariableExpr * extractVariable( Expression * func ) { 215 if( VariableExpr * var = dynamic_cast< VariableExpr * >( func ) ) { 216 return var; 217 } 218 219 CastExpr * cast = strict_dynamic_cast< CastExpr * >( func ); 220 return strict_dynamic_cast< VariableExpr * >( cast->arg ); 221 } 222 223 Expression * detectIsDtor( Expression * func ) { 224 VariableExpr * typed_func = extractVariable( func ); 225 bool is_dtor = InitTweak::isDestructor( typed_func->var ); 226 return new ConstantExpr( Constant::from_bool( is_dtor ) ); 227 } 210 228 }; 211 229 … … 216 234 217 235 void GenerateWaitForPass::premutate( FunctionDecl * decl) { 218 if( decl->name != "__ accept_internal" ) return;236 if( decl->name != "__waitfor_internal" ) return; 219 237 220 238 decl_waitfor = decl; … … 227 245 assert( !decl_acceptable ); 228 246 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 247 } 248 else if( decl->name == "__waitfor_mask_t" ) { 249 assert( !decl_mask ); 250 decl_mask = decl; 236 251 } 237 252 else if( decl->name == "monitor_desc" ) { … … 242 257 243 258 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 ); 259 if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor ); 247 260 248 261 CompoundStmt * stmt = new CompoundStmt( noLabels ); 249 262 250 263 ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt ); 264 ObjectDecl * flag = declareFlag( stmt ); 265 Statement * setter = makeSetter( flag ); 251 266 252 267 int index = 0; 253 268 for( auto & clause : waitfor->clauses ) { 254 init( acceptables, index, clause, s tmt );269 init( acceptables, index, clause, setter, stmt ); 255 270 256 271 index++; … … 262 277 waitfor->orelse .statement, 263 278 waitfor->orelse .condition, 279 setter, 264 280 stmt 265 281 ); 266 282 267 // Expression * result = call( acceptables, timeout, orelse, stmt ); 268 269 // choose( waitfor, result ); 283 CompoundStmt * compound = new CompoundStmt( noLabels ); 284 stmt->push_back( new IfStmt( 285 noLabels, 286 safeCond( new VariableExpr( flag ) ), 287 compound, 288 nullptr 289 )); 290 291 Expression * result = call( waitfor->clauses.size(), acceptables, timeout, compound ); 292 293 choose( waitfor, result, compound ); 270 294 271 295 return stmt; … … 274 298 ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt ) 275 299 { 276 ObjectDecl * acceptables = new ObjectDecl(300 ObjectDecl * acceptables = ObjectDecl::newObject( 277 301 namer_acc.newName(), 278 noStorage,279 LinkageSpec::Cforall,280 nullptr,281 302 new ArrayType( 282 303 noQualifiers, … … 294 315 stmt->push_back( new DeclStmt( noLabels, acceptables) ); 295 316 317 Expression * set = new UntypedExpr( 318 new NameExpr( "__builtin_memset" ), 319 { 320 new VariableExpr( acceptables ), 321 new ConstantExpr( Constant::from_int( 0 ) ), 322 new SizeofExpr( new VariableExpr( acceptables ) ) 323 } 324 ); 325 326 ResolvExpr::findVoidExpression( set, indexer ); 327 328 stmt->push_back( new ExprStmt( noLabels, set ) ); 329 296 330 return acceptables; 297 331 } 298 332 333 ObjectDecl * GenerateWaitForPass::declareFlag( CompoundStmt * stmt ) { 334 ObjectDecl * flag = ObjectDecl::newObject( 335 namer_flg.newName(), 336 new BasicType( 337 noQualifiers, 338 BasicType::Bool 339 ), 340 new SingleInit( new ConstantExpr( Constant::from_ulong( 0 ) ) ) 341 ); 342 343 stmt->push_back( new DeclStmt( noLabels, flag) ); 344 345 return flag; 346 } 347 348 Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) { 349 Expression * expr = new UntypedExpr( 350 new NameExpr( "?=?" ), 351 { 352 new VariableExpr( flag ), 353 new ConstantExpr( Constant::from_ulong( 1 ) ) 354 } 355 ); 356 357 ResolvExpr::findVoidExpression( expr, indexer ); 358 359 return new ExprStmt( noLabels, expr ); 360 } 361 299 362 ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) { 300 363 301 ObjectDecl * mon = new ObjectDecl(364 ObjectDecl * mon = ObjectDecl::newObject( 302 365 namer_mon.newName(), 303 noStorage,304 LinkageSpec::Cforall,305 nullptr,306 366 new ArrayType( 307 367 noQualifiers, 308 new StructInstType(368 new PointerType( 309 369 noQualifiers, 310 decl_monitor 370 new StructInstType( 371 noQualifiers, 372 decl_monitor 373 ) 311 374 ), 312 375 new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), … … 316 379 new ListInit( 317 380 map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){ 318 return new SingleInit( expr ); 381 Expression * init = 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 ResolvExpr::findSingleExpression( init, indexer ); 396 return new SingleInit( init ); 319 397 }) 320 398 ) … … 326 404 } 327 405 328 void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ) {406 void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * setter, CompoundStmt * stmt ) { 329 407 330 408 ObjectDecl * monitors = declMon( clause, stmt ); 331 409 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 ) ) ) ); 410 Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) ); 337 411 338 412 stmt->push_back( new IfStmt( 339 413 noLabels, 340 414 safeCond( clause.condition ), 341 compound, 415 new CompoundStmt({ 416 makeAccStatement( acceptables, index, "is_dtor", detectIsDtor( clause.target.function ) , indexer ), 417 makeAccStatement( acceptables, index, "func" , new CastExpr( clause.target.function, fptr_t ) , indexer ), 418 makeAccStatement( acceptables, index, "list" , new VariableExpr( monitors ) , indexer ), 419 makeAccStatement( acceptables, index, "size" , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ), 420 setter->clone() 421 }), 342 422 nullptr 343 423 )); … … 353 433 bool has_else, 354 434 Expression *& else_cond, 435 Statement * setter, 355 436 CompoundStmt * stmt 356 437 ) { 357 ObjectDecl * timeout = new ObjectDecl(438 ObjectDecl * timeout = ObjectDecl::newObject( 358 439 namer_tim.newName(), 359 noStorage,360 LinkageSpec::Cforall,361 nullptr,362 440 new BasicType( 363 441 noQualifiers, … … 374 452 stmt->push_back( new IfStmt( 375 453 noLabels, 376 safeCond( else_cond ), 377 new ExprStmt( 378 noLabels, 379 makeOpAssign( 380 new VariableExpr( timeout ), 381 time 382 ) 383 ), 454 safeCond( time_cond ), 455 new CompoundStmt({ 456 new ExprStmt( 457 noLabels, 458 makeOpAssign( 459 new VariableExpr( timeout ), 460 time 461 ) 462 ), 463 setter->clone() 464 }), 384 465 nullptr 385 466 )); … … 392 473 noLabels, 393 474 safeCond( else_cond ), 394 new ExprStmt( 395 noLabels, 396 makeOpAssign( 397 new VariableExpr( timeout ), 398 new ConstantExpr( Constant::from_ulong( 0 ) ) 399 ) 400 ), 475 new CompoundStmt({ 476 new ExprStmt( 477 noLabels, 478 makeOpAssign( 479 new VariableExpr( timeout ), 480 new ConstantExpr( Constant::from_ulong( 0 ) ) 481 ) 482 ), 483 setter->clone() 484 }), 401 485 nullptr 402 486 )); … … 405 489 } 406 490 491 delete setter; 492 407 493 return new VariableExpr( timeout ); 494 } 495 496 Expression * GenerateWaitForPass::call( 497 size_t count, 498 ObjectDecl * acceptables, 499 Expression * timeout, 500 CompoundStmt * stmt 501 ) { 502 ObjectDecl * index = ObjectDecl::newObject( 503 namer_idx.newName(), 504 new BasicType( 505 noQualifiers, 506 BasicType::ShortSignedInt 507 ), 508 new SingleInit( 509 new ConstantExpr( Constant::from_int( -1 ) ) 510 ) 511 ); 512 513 stmt->push_back( new DeclStmt( noLabels, index ) ); 514 515 ObjectDecl * mask = ObjectDecl::newObject( 516 namer_msk.newName(), 517 new StructInstType( 518 noQualifiers, 519 decl_mask 520 ), 521 new ListInit({ 522 new SingleInit( new AddressExpr( new VariableExpr( index ) ) ), 523 new SingleInit( new VariableExpr( acceptables ) ), 524 new SingleInit( new ConstantExpr( Constant::from_ulong( count ) ) ) 525 }) 526 ); 527 528 stmt->push_back( new DeclStmt( noLabels, mask ) ); 529 530 stmt->push_back( new ExprStmt( 531 noLabels, 532 new ApplicationExpr( 533 VariableExpr::functionPointer( decl_waitfor ), 534 { 535 new CastExpr( 536 new VariableExpr( mask ), 537 new ReferenceType( 538 noQualifiers, 539 new StructInstType( 540 noQualifiers, 541 decl_mask 542 ) 543 ) 544 ), 545 timeout 546 } 547 ) 548 )); 549 550 return new VariableExpr( index ); 551 } 552 553 void GenerateWaitForPass::choose( 554 WaitForStmt * waitfor, 555 Expression * result, 556 CompoundStmt * stmt 557 ) { 558 SwitchStmt * swtch = new SwitchStmt( 559 noLabels, 560 result, 561 std::list<Statement *>() 562 ); 563 564 unsigned long i = 0; 565 for( auto & clause : waitfor->clauses ) { 566 swtch->statements.push_back( 567 new CaseStmt( 568 noLabels, 569 new ConstantExpr( Constant::from_ulong( i++ ) ), 570 { 571 clause.statement, 572 new BranchStmt( 573 noLabels, 574 "", 575 BranchStmt::Break 576 ) 577 } 578 ) 579 ); 580 } 581 582 if(waitfor->timeout.statement) { 583 swtch->statements.push_back( 584 new CaseStmt( 585 noLabels, 586 new ConstantExpr( Constant::from_int( -2 ) ), 587 { 588 waitfor->timeout.statement, 589 new BranchStmt( 590 noLabels, 591 "", 592 BranchStmt::Break 593 ) 594 } 595 ) 596 ); 597 } 598 599 if(waitfor->orelse.statement) { 600 swtch->statements.push_back( 601 new CaseStmt( 602 noLabels, 603 new ConstantExpr( Constant::from_int( -1 ) ), 604 { 605 waitfor->orelse.statement, 606 new BranchStmt( 607 noLabels, 608 "", 609 BranchStmt::Break 610 ) 611 } 612 ) 613 ); 614 } 615 616 stmt->push_back( swtch ); 408 617 } 409 618 };
Note:
See TracChangeset
for help on using the changeset viewer.