Changes in src/Concurrency/Waitfor.cc [e3e16bc:310e5b7]
- File:
-
- 1 edited
-
src/Concurrency/Waitfor.cc (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Waitfor.cc
re3e16bc r310e5b7 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 … … 129 129 void init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ); 130 130 Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt ); 131 Expression * call( );132 void choose();131 Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt); 132 void choose( WaitForStmt * waitfor, Expression * result, CompoundStmt * stmt ); 133 133 134 134 static void implement( std::list< Declaration * > & translationUnit ) { … … 142 142 StructDecl * decl_acceptable = nullptr; 143 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;148 144 149 145 static std::unique_ptr< Type > generic_func; … … 152 148 UniqueName namer_acc = "__acceptables_"s; 153 149 UniqueName namer_tim = "__timeout_"s; 150 UniqueName namer_ret = "__return_"s; 154 151 }; 155 152 … … 167 164 namespace { 168 165 Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) { 169 return new ApplicationExpr(166 return new UntypedExpr( 170 167 new NameExpr( "?[?]" ), 171 168 { … … 177 174 178 175 Expression * makeOpAssign( Expression * lhs, Expression * rhs ) { 179 return new ApplicationExpr(176 return new UntypedExpr( 180 177 new NameExpr( "?=?" ), 181 178 { lhs, rhs } … … 183 180 } 184 181 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 182 Expression * makeOpMember( Expression * sue, const std::string & mem ) { 183 return new UntypedMemberExpr( new NameExpr( mem ), sue ); 184 } 185 186 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) { 187 std::unique_ptr< Expression > expr( makeOpAssign( 188 makeOpMember( 189 makeOpIndex( 190 object, 191 index 199 192 ), 200 value 201 ) 202 ); 193 member 194 ), 195 value 196 ) ); 197 198 return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) ); 203 199 } 204 200 … … 208 204 return new ConstantExpr( Constant::from_bool( ifnull ) ); 209 205 } 206 207 VariableExpr * extractVariable( Expression * func ) { 208 if( VariableExpr * var = dynamic_cast< VariableExpr * >( func ) ) { 209 return var; 210 } 211 212 CastExpr * cast = strict_dynamic_cast< CastExpr * >( func ); 213 return strict_dynamic_cast< VariableExpr * >( cast->arg ); 214 } 215 216 Expression * betterIsDtor( Expression * func ) { 217 VariableExpr * typed_func = extractVariable( func ); 218 bool is_dtor = InitTweak::isDestructor( typed_func->var ); 219 return new ConstantExpr( Constant::from_bool( is_dtor ) ); 220 } 210 221 }; 211 222 … … 216 227 217 228 void GenerateWaitForPass::premutate( FunctionDecl * decl) { 218 if( decl->name != "__ accept_internal" ) return;229 if( decl->name != "__waitfor_internal" ) return; 219 230 220 231 decl_waitfor = decl; … … 227 238 assert( !decl_acceptable ); 228 239 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 236 240 } 237 241 else if( decl->name == "monitor_desc" ) { … … 242 246 243 247 Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) { 244 return waitfor;245 246 248 if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor ); 247 249 … … 265 267 ); 266 268 267 // Expression * result = call( acceptables, timeout, orelse, stmt );268 269 // choose( waitfor, result );269 Expression * result = call( waitfor->clauses.size(), acceptables, timeout, stmt ); 270 271 choose( waitfor, result, stmt ); 270 272 271 273 return stmt; … … 274 276 ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt ) 275 277 { 276 ObjectDecl * acceptables = new ObjectDecl(278 ObjectDecl * acceptables = ObjectDecl::newObject( 277 279 namer_acc.newName(), 278 noStorage,279 LinkageSpec::Cforall,280 nullptr,281 280 new ArrayType( 282 281 noQualifiers, … … 299 298 ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) { 300 299 301 ObjectDecl * mon = new ObjectDecl(300 ObjectDecl * mon = ObjectDecl::newObject( 302 301 namer_mon.newName(), 303 noStorage,304 LinkageSpec::Cforall,305 nullptr,306 302 new ArrayType( 307 303 noQualifiers, … … 330 326 ObjectDecl * monitors = declMon( clause, stmt ); 331 327 328 Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) ); 329 330 Expression * is_dtor = betterIsDtor( clause.target.function ); 332 331 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 ) )) );332 compound->push_back( makeAccStatement( acceptables, index, "func" , new CastExpr( clause.target.function, fptr_t ) , indexer ) ); 333 compound->push_back( makeAccStatement( acceptables, index, "count" , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ) ); 334 compound->push_back( makeAccStatement( acceptables, index, "monitors", new VariableExpr( monitors ) , indexer ) ); 335 compound->push_back( makeAccStatement( acceptables, index, "is_dtor" , is_dtor , indexer ) ); 337 336 338 337 stmt->push_back( new IfStmt( … … 355 354 CompoundStmt * stmt 356 355 ) { 357 ObjectDecl * timeout = new ObjectDecl(356 ObjectDecl * timeout = ObjectDecl::newObject( 358 357 namer_tim.newName(), 359 noStorage,360 LinkageSpec::Cforall,361 nullptr,362 358 new BasicType( 363 359 noQualifiers, … … 374 370 stmt->push_back( new IfStmt( 375 371 noLabels, 376 safeCond( else_cond ),372 safeCond( time_cond ), 377 373 new ExprStmt( 378 374 noLabels, … … 407 403 return new VariableExpr( timeout ); 408 404 } 405 406 Expression * GenerateWaitForPass::call( 407 size_t count, 408 ObjectDecl * acceptables, 409 Expression * timeout, 410 CompoundStmt * stmt 411 ) { 412 ObjectDecl * decl = ObjectDecl::newObject( 413 namer_ret.newName(), 414 new BasicType( 415 noQualifiers, 416 BasicType::LongLongUnsignedInt 417 ), 418 new SingleInit( 419 new UntypedExpr( 420 VariableExpr::functionPointer( decl_waitfor ), 421 { 422 new ConstantExpr( Constant::from_ulong( count ) ), 423 new VariableExpr( acceptables ), 424 timeout 425 } 426 ) 427 ) 428 ); 429 430 stmt->push_back( new DeclStmt( noLabels, decl ) ); 431 432 return new VariableExpr( decl ); 433 } 434 435 void GenerateWaitForPass::choose( 436 WaitForStmt * waitfor, 437 Expression * result, 438 CompoundStmt * stmt 439 ) { 440 SwitchStmt * swtch = new SwitchStmt( 441 noLabels, 442 result, 443 std::list<Statement *>() 444 ); 445 446 unsigned long i = 0; 447 for( auto & clause : waitfor->clauses ) { 448 swtch->statements.push_back( 449 new CaseStmt( 450 noLabels, 451 new ConstantExpr( Constant::from_ulong( i++ ) ), 452 { 453 clause.statement, 454 new BranchStmt( 455 noLabels, 456 "", 457 BranchStmt::Break 458 ) 459 } 460 ) 461 ); 462 } 463 464 if(waitfor->timeout.statement) { 465 swtch->statements.push_back( 466 new CaseStmt( 467 noLabels, 468 new ConstantExpr( Constant::from_ulong( i++ ) ), 469 { 470 waitfor->timeout.statement, 471 new BranchStmt( 472 noLabels, 473 "", 474 BranchStmt::Break 475 ) 476 } 477 ) 478 ); 479 } 480 481 if(waitfor->orelse.statement) { 482 swtch->statements.push_back( 483 new CaseStmt( 484 noLabels, 485 new ConstantExpr( Constant::from_ulong( i++ ) ), 486 { 487 waitfor->orelse.statement, 488 new BranchStmt( 489 noLabels, 490 "", 491 BranchStmt::Break 492 ) 493 } 494 ) 495 ); 496 } 497 498 stmt->push_back( swtch ); 499 } 409 500 }; 410 501
Note:
See TracChangeset
for help on using the changeset viewer.