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