comparison gen/statements.cpp @ 1141:f99a3b393c03

Reorganize EnclosingHandlers to require less changes to the frontend and allow us to implement the synchronized storage class for functions.
author Christian Kamm <kamm incasoftware de>
date Tue, 24 Mar 2009 21:18:18 +0100
parents b30fe7e1dbb9
children 40caa8207b3e
comparison
equal deleted inserted replaced
1137:45d73f0a9b43 1141:f99a3b393c03
74 DValue* e = exp->toElem(p); 74 DValue* e = exp->toElem(p);
75 // store return value 75 // store return value
76 DtoAssign(loc, rvar, e); 76 DtoAssign(loc, rvar, e);
77 77
78 // emit scopes 78 // emit scopes
79 DtoEnclosingHandlers(enclosinghandler, NULL); 79 DtoEnclosingHandlers(loc, NULL);
80 80
81 // emit dbg end function 81 // emit dbg end function
82 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); 82 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
83 83
84 // emit ret 84 // emit ret
120 120
121 if (Logger::enabled()) 121 if (Logger::enabled())
122 Logger::cout() << "return value after cast: " << *v << '\n'; 122 Logger::cout() << "return value after cast: " << *v << '\n';
123 } 123 }
124 124
125 DtoEnclosingHandlers(enclosinghandler, NULL); 125 DtoEnclosingHandlers(loc, NULL);
126 126
127 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 127 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
128 llvm::ReturnInst::Create(v, p->scopebb()); 128 llvm::ReturnInst::Create(v, p->scopebb());
129 } 129 }
130 } 130 }
131 // no return value expression means it's a void function 131 // no return value expression means it's a void function
132 else 132 else
133 { 133 {
134 assert(p->topfunc()->getReturnType() == LLType::VoidTy); 134 assert(p->topfunc()->getReturnType() == LLType::VoidTy);
135 DtoEnclosingHandlers(enclosinghandler, NULL); 135 DtoEnclosingHandlers(loc, NULL);
136 136
137 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 137 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
138 llvm::ReturnInst::Create(p->scopebb()); 138 llvm::ReturnInst::Create(p->scopebb());
139 } 139 }
140 140
294 294
295 // rewrite scope 295 // rewrite scope
296 gIR->scope() = IRScope(whilebodybb,endbb); 296 gIR->scope() = IRScope(whilebodybb,endbb);
297 297
298 // while body code 298 // while body code
299 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,whilebb,endbb)); 299 p->targetScopes.push_back(IRTargetScope(this,NULL,whilebb,endbb));
300 body->toIR(p); 300 body->toIR(p);
301 p->loopbbs.pop_back(); 301 p->targetScopes.pop_back();
302 302
303 // loop 303 // loop
304 if (!gIR->scopereturned()) 304 if (!gIR->scopereturned())
305 llvm::BranchInst::Create(whilebb, gIR->scopebb()); 305 llvm::BranchInst::Create(whilebb, gIR->scopebb());
306 306
330 330
331 // replace current scope 331 // replace current scope
332 gIR->scope() = IRScope(dowhilebb,condbb); 332 gIR->scope() = IRScope(dowhilebb,condbb);
333 333
334 // do-while body code 334 // do-while body code
335 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,condbb,endbb)); 335 p->targetScopes.push_back(IRTargetScope(this,NULL,condbb,endbb));
336 body->toIR(p); 336 body->toIR(p);
337 p->loopbbs.pop_back(); 337 p->targetScopes.pop_back();
338 338
339 // branch to condition block 339 // branch to condition block
340 llvm::BranchInst::Create(condbb, gIR->scopebb()); 340 llvm::BranchInst::Create(condbb, gIR->scopebb());
341 gIR->scope() = IRScope(condbb,endbb); 341 gIR->scope() = IRScope(condbb,endbb);
342 342
375 375
376 // move into the for condition block, ie. start the loop 376 // move into the for condition block, ie. start the loop
377 assert(!gIR->scopereturned()); 377 assert(!gIR->scopereturned());
378 llvm::BranchInst::Create(forbb, gIR->scopebb()); 378 llvm::BranchInst::Create(forbb, gIR->scopebb());
379 379
380 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,forincbb,endbb)); 380 p->targetScopes.push_back(IRTargetScope(this,NULL,forincbb,endbb));
381 381
382 // replace current scope 382 // replace current scope
383 gIR->scope() = IRScope(forbb,forbodybb); 383 gIR->scope() = IRScope(forbb,forbodybb);
384 384
385 // create the condition 385 // create the condition
418 418
419 // loop 419 // loop
420 if (!gIR->scopereturned()) 420 if (!gIR->scopereturned())
421 llvm::BranchInst::Create(forbb, gIR->scopebb()); 421 llvm::BranchInst::Create(forbb, gIR->scopebb());
422 422
423 p->loopbbs.pop_back(); 423 p->targetScopes.pop_back();
424 424
425 // rewrite the scope 425 // rewrite the scope
426 gIR->scope() = IRScope(endbb,oldend); 426 gIR->scope() = IRScope(endbb,oldend);
427 } 427 }
428 428
442 DtoDwarfStopPoint(loc.linnum); 442 DtoDwarfStopPoint(loc.linnum);
443 443
444 if (ident != 0) { 444 if (ident != 0) {
445 Logger::println("ident = %s", ident->toChars()); 445 Logger::println("ident = %s", ident->toChars());
446 446
447 DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler); 447 DtoEnclosingHandlers(loc, target);
448 448
449 // get the loop statement the label refers to 449 // get the loop statement the label refers to
450 Statement* targetLoopStatement = target->statement; 450 Statement* targetLoopStatement = target->statement;
451 ScopeStatement* tmp; 451 ScopeStatement* tmp;
452 while(tmp = targetLoopStatement->isScopeStatement()) 452 while(tmp = targetLoopStatement->isScopeStatement())
453 targetLoopStatement = tmp->statement; 453 targetLoopStatement = tmp->statement;
454 454
455 // find the right break block and jump there 455 // find the right break block and jump there
456 bool found = false; 456 bool found = false;
457 IRState::LoopScopeVec::reverse_iterator it; 457 IRState::TargetScopeVec::reverse_iterator it;
458 for(it = p->loopbbs.rbegin(); it != p->loopbbs.rend(); ++it) { 458 for(it = p->targetScopes.rbegin(); it != p->targetScopes.rend(); ++it) {
459 if(it->s == targetLoopStatement) { 459 if(it->s == targetLoopStatement) {
460 llvm::BranchInst::Create(it->end, p->scopebb()); 460 llvm::BranchInst::Create(it->breakTarget, p->scopebb());
461 found = true; 461 found = true;
462 break; 462 break;
463 } 463 }
464 } 464 }
465 assert(found); 465 assert(found);
466 } 466 }
467 else { 467 else {
468 DtoEnclosingHandlers(enclosinghandler, p->loopbbs.back().enclosinghandler); 468 // find closest scope with a break target
469 llvm::BranchInst::Create(p->loopbbs.back().end, p->scopebb()); 469 IRState::TargetScopeVec::reverse_iterator it;
470 for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) {
471 if(it->breakTarget) {
472 break;
473 }
474 }
475 DtoEnclosingHandlers(loc, it->s);
476 llvm::BranchInst::Create(it->breakTarget, gIR->scopebb());
470 } 477 }
471 478
472 // the break terminated this basicblock, start a new one 479 // the break terminated this basicblock, start a new one
473 llvm::BasicBlock* oldend = gIR->scopeend(); 480 llvm::BasicBlock* oldend = gIR->scopeend();
474 llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterbreak", p->topfunc(), oldend); 481 llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterbreak", p->topfunc(), oldend);
486 DtoDwarfStopPoint(loc.linnum); 493 DtoDwarfStopPoint(loc.linnum);
487 494
488 if (ident != 0) { 495 if (ident != 0) {
489 Logger::println("ident = %s", ident->toChars()); 496 Logger::println("ident = %s", ident->toChars());
490 497
491 DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler); 498 DtoEnclosingHandlers(loc, target);
492 499
493 // get the loop statement the label refers to 500 // get the loop statement the label refers to
494 Statement* targetLoopStatement = target->statement; 501 Statement* targetLoopStatement = target->statement;
495 ScopeStatement* tmp; 502 ScopeStatement* tmp;
496 while(tmp = targetLoopStatement->isScopeStatement()) 503 while(tmp = targetLoopStatement->isScopeStatement())
497 targetLoopStatement = tmp->statement; 504 targetLoopStatement = tmp->statement;
498 505
499 // find the right continue block and jump there 506 // find the right continue block and jump there
500 bool found = false; 507 bool found = false;
501 IRState::LoopScopeVec::reverse_iterator it; 508 IRState::TargetScopeVec::reverse_iterator it;
502 for(it = gIR->loopbbs.rbegin(); it != gIR->loopbbs.rend(); ++it) { 509 for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) {
503 if(it->s == targetLoopStatement) { 510 if(it->s == targetLoopStatement) {
504 llvm::BranchInst::Create(it->begin, gIR->scopebb()); 511 llvm::BranchInst::Create(it->continueTarget, gIR->scopebb());
505 found = true; 512 found = true;
506 break; 513 break;
507 } 514 }
508 } 515 }
509 assert(found); 516 assert(found);
510 } 517 }
511 else { 518 else {
512 // can't 'continue' within switch, so omit them 519 // find closest scope with a continue target
513 IRState::LoopScopeVec::reverse_iterator it; 520 IRState::TargetScopeVec::reverse_iterator it;
514 for(it = gIR->loopbbs.rbegin(); it != gIR->loopbbs.rend(); ++it) { 521 for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) {
515 if(!it->isSwitch) { 522 if(it->continueTarget) {
516 break; 523 break;
517 } 524 }
518 } 525 }
519 DtoEnclosingHandlers(enclosinghandler, it->enclosinghandler); 526 DtoEnclosingHandlers(loc, it->s);
520 llvm::BranchInst::Create(it->begin, gIR->scopebb()); 527 llvm::BranchInst::Create(it->continueTarget, gIR->scopebb());
521 } 528 }
522 529
523 // the continue terminated this basicblock, start a new one 530 // the continue terminated this basicblock, start a new one
524 llvm::BasicBlock* oldend = gIR->scopeend(); 531 llvm::BasicBlock* oldend = gIR->scopeend();
525 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftercontinue", p->topfunc(), oldend); 532 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftercontinue", p->topfunc(), oldend);
584 // do the try block 591 // do the try block
585 // 592 //
586 p->scope() = IRScope(trybb,finallybb); 593 p->scope() = IRScope(trybb,finallybb);
587 594
588 assert(body); 595 assert(body);
596 p->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this),NULL,NULL));
589 body->toIR(p); 597 body->toIR(p);
598 p->targetScopes.pop_back();
590 599
591 // terminate try BB 600 // terminate try BB
592 if (!p->scopereturned()) 601 if (!p->scopereturned())
593 llvm::BranchInst::Create(finallybb, p->scopebb()); 602 llvm::BranchInst::Create(finallybb, p->scopebb());
594 603
840 849
841 // do switch body 850 // do switch body
842 assert(body); 851 assert(body);
843 852
844 p->scope() = IRScope(bodybb, endbb); 853 p->scope() = IRScope(bodybb, endbb);
845 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb,true)); 854 p->targetScopes.push_back(IRTargetScope(this,NULL,NULL,endbb));
846 body->toIR(p); 855 body->toIR(p);
847 p->loopbbs.pop_back(); 856 p->targetScopes.pop_back();
848 857
849 if (!p->scopereturned()) 858 if (!p->scopereturned())
850 llvm::BranchInst::Create(endbb, p->scopebb()); 859 llvm::BranchInst::Create(endbb, p->scopebb());
851 860
852 // add the cases 861 // add the cases
961 // update scope 970 // update scope
962 p->scope() = IRScope(thisbb,nextbb); 971 p->scope() = IRScope(thisbb,nextbb);
963 972
964 // push loop scope 973 // push loop scope
965 // continue goes to next statement, break goes to end 974 // continue goes to next statement, break goes to end
966 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb)); 975 p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb));
967 976
968 // do statement 977 // do statement
969 s->toIR(p); 978 s->toIR(p);
970 979
971 // pop loop scope 980 // pop loop scope
972 p->loopbbs.pop_back(); 981 p->targetScopes.pop_back();
973 982
974 // next stmt 983 // next stmt
975 if (!p->scopereturned()) 984 if (!p->scopereturned())
976 p->ir->CreateBr(nextbb); 985 p->ir->CreateBr(nextbb);
977 } 986 }
1084 DtoAssign(loc, &dst, &src); 1093 DtoAssign(loc, &dst, &src);
1085 value->ir.irLocal->value = valvar; 1094 value->ir.irLocal->value = valvar;
1086 } 1095 }
1087 1096
1088 // emit body 1097 // emit body
1089 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb)); 1098 p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb));
1090 if(body) 1099 if(body)
1091 body->toIR(p); 1100 body->toIR(p);
1092 p->loopbbs.pop_back(); 1101 p->targetScopes.pop_back();
1093 1102
1094 if (!p->scopereturned()) 1103 if (!p->scopereturned())
1095 llvm::BranchInst::Create(nextbb, p->scopebb()); 1104 llvm::BranchInst::Create(nextbb, p->scopebb());
1096 1105
1097 // next 1106 // next
1180 v = p->ir->CreateSub(v, one); 1189 v = p->ir->CreateSub(v, one);
1181 DtoStore(v, keyval); 1190 DtoStore(v, keyval);
1182 } 1191 }
1183 1192
1184 // emit body 1193 // emit body
1185 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb)); 1194 p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb));
1186 if (body) 1195 if (body)
1187 body->toIR(p); 1196 body->toIR(p);
1188 p->loopbbs.pop_back(); 1197 p->targetScopes.pop_back();
1189 1198
1190 // jump to next iteration 1199 // jump to next iteration
1191 if (!p->scopereturned()) 1200 if (!p->scopereturned())
1192 llvm::BranchInst::Create(nextbb, p->scopebb()); 1201 llvm::BranchInst::Create(nextbb, p->scopebb());
1193 1202
1249 llvm::BranchInst::Create(labelBB, p->scopebb()); 1258 llvm::BranchInst::Create(labelBB, p->scopebb());
1250 1259
1251 p->scope() = IRScope(labelBB,oldend); 1260 p->scope() = IRScope(labelBB,oldend);
1252 } 1261 }
1253 1262
1254 if (statement) 1263 if (statement) {
1264 p->targetScopes.push_back(IRTargetScope(this,NULL,NULL,NULL));
1255 statement->toIR(p); 1265 statement->toIR(p);
1266 p->targetScopes.pop_back();
1267 }
1256 } 1268 }
1257 1269
1258 ////////////////////////////////////////////////////////////////////////////// 1270 //////////////////////////////////////////////////////////////////////////////
1259 1271
1260 void GotoStatement::toIR(IRState* p) 1272 void GotoStatement::toIR(IRState* p)
1266 DtoDwarfStopPoint(loc.linnum); 1278 DtoDwarfStopPoint(loc.linnum);
1267 1279
1268 llvm::BasicBlock* oldend = gIR->scopeend(); 1280 llvm::BasicBlock* oldend = gIR->scopeend();
1269 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend); 1281 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend);
1270 1282
1271 DtoGoto(&loc, label->ident, enclosinghandler, tf); 1283 DtoGoto(loc, label->ident);
1272 1284
1273 p->scope() = IRScope(bb,oldend); 1285 p->scope() = IRScope(bb,oldend);
1274 } 1286 }
1275 1287
1276 ////////////////////////////////////////////////////////////////////////////// 1288 //////////////////////////////////////////////////////////////////////////////
1287 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotodefault", p->topfunc(), oldend); 1299 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotodefault", p->topfunc(), oldend);
1288 1300
1289 assert(!p->scopereturned()); 1301 assert(!p->scopereturned());
1290 assert(sw->sdefault->bodyBB); 1302 assert(sw->sdefault->bodyBB);
1291 1303
1292 DtoEnclosingHandlers(enclosinghandler, sw->enclosinghandler); 1304 DtoEnclosingHandlers(loc, sw);
1293 1305
1294 llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb()); 1306 llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb());
1295 p->scope() = IRScope(bb,oldend); 1307 p->scope() = IRScope(bb,oldend);
1296 } 1308 }
1297 1309
1312 if (!cs->bodyBB) 1324 if (!cs->bodyBB)
1313 { 1325 {
1314 cs->bodyBB = llvm::BasicBlock::Create("goto_case", p->topfunc(), p->scopeend()); 1326 cs->bodyBB = llvm::BasicBlock::Create("goto_case", p->topfunc(), p->scopeend());
1315 } 1327 }
1316 1328
1317 DtoEnclosingHandlers(enclosinghandler, sw->enclosinghandler); 1329 DtoEnclosingHandlers(loc, sw);
1318 1330
1319 llvm::BranchInst::Create(cs->bodyBB, p->scopebb()); 1331 llvm::BranchInst::Create(cs->bodyBB, p->scopebb());
1320 p->scope() = IRScope(bb,oldend); 1332 p->scope() = IRScope(bb,oldend);
1321 } 1333 }
1322 1334
1371 llsync = generate_unique_critical_section(); 1383 llsync = generate_unique_critical_section();
1372 DtoEnterCritical(llsync); 1384 DtoEnterCritical(llsync);
1373 } 1385 }
1374 1386
1375 // emit body 1387 // emit body
1388 p->targetScopes.push_back(IRTargetScope(this,new EnclosingSynchro(this),NULL,NULL));
1376 body->toIR(p); 1389 body->toIR(p);
1390 p->targetScopes.pop_back();
1377 1391
1378 // exit lock 1392 // exit lock
1379 // no point in a unreachable unlock, terminating statements must insert this themselves. 1393 // no point in a unreachable unlock, terminating statements must insert this themselves.
1380 if (p->scopereturned()) 1394 if (p->scopereturned())
1381 return; 1395 return;
1403 { 1417 {
1404 // load-store 1418 // load-store
1405 DtoMemoryBarrier(false, true, false, false); 1419 DtoMemoryBarrier(false, true, false, false);
1406 1420
1407 // do statement 1421 // do statement
1422 p->targetScopes.push_back(IRTargetScope(this,new EnclosingVolatile(this),NULL,NULL));
1408 statement->toIR(p); 1423 statement->toIR(p);
1424 p->targetScopes.pop_back();
1409 1425
1410 // no point in a unreachable barrier, terminating statements must insert this themselves. 1426 // no point in a unreachable barrier, terminating statements must insert this themselves.
1411 if (statement->blockExit() & BEfallthru) 1427 if (statement->blockExit() & BEfallthru)
1412 { 1428 {
1413 // store-load 1429 // store-load