Mercurial > projects > ldc
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 |