Changeset 1145:40caa8207b3e
- Timestamp:
- 03/26/09 13:46:21
(3 years ago)
- Author:
- Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
- branch:
- default
- Message:
Moved IRTargetScopeS from IRState into IrFunction?, fixes #240 .
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r1141 |
r1145 |
|
| 37 | 37 | struct BaseClass; |
|---|
| 38 | 38 | struct AnonDeclaration; |
|---|
| 39 | | struct EnclosingHandler; |
|---|
| 40 | 39 | |
|---|
| 41 | 40 | struct IrModule; |
|---|
| … | … | |
| 50 | 49 | IRScope(); |
|---|
| 51 | 50 | IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e); |
|---|
| 52 | | }; |
|---|
| 53 | | |
|---|
| 54 | | // scope statements that can be target of jumps |
|---|
| 55 | | // includes loops, switch, case, labels |
|---|
| 56 | | struct IRTargetScope |
|---|
| 57 | | { |
|---|
| 58 | | // generating statement |
|---|
| 59 | | Statement* s; |
|---|
| 60 | | |
|---|
| 61 | | // the try of a TryFinally that encloses the loop |
|---|
| 62 | | EnclosingHandler* enclosinghandler; |
|---|
| 63 | | |
|---|
| 64 | | llvm::BasicBlock* breakTarget; |
|---|
| 65 | | llvm::BasicBlock* continueTarget; |
|---|
| 66 | | |
|---|
| 67 | | IRTargetScope(); |
|---|
| 68 | | IRTargetScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* continueTarget, llvm::BasicBlock* breakTarget); |
|---|
| 69 | 51 | }; |
|---|
| 70 | 52 | |
|---|
| … | … | |
| 160 | 142 | llvm::CallSite CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name=""); |
|---|
| 161 | 143 | |
|---|
| 162 | | // loop blocks |
|---|
| 163 | | typedef std::vector<IRTargetScope> TargetScopeVec; |
|---|
| 164 | | TargetScopeVec targetScopes; |
|---|
| 165 | | |
|---|
| 166 | 144 | // this holds the array being indexed or sliced so $ will work |
|---|
| 167 | 145 | // might be a better way but it works. problem is I only get a |
|---|
| r1141 |
r1145 |
|
| 249 | 249 | |
|---|
| 250 | 250 | // figure out up until what handler we need to emit |
|---|
| 251 | | IRState::TargetScopeVec::reverse_iterator targetit; |
|---|
| 252 | | for (targetit = gIR->targetScopes.rbegin(); targetit != gIR->targetScopes.rend(); ++targetit) { |
|---|
| | 251 | IrFunction::TargetScopeVec::reverse_iterator targetit = gIR->func()->targetScopes.rbegin(); |
|---|
| | 252 | IrFunction::TargetScopeVec::reverse_iterator it_end = gIR->func()->targetScopes.rend(); |
|---|
| | 253 | while(targetit != it_end) { |
|---|
| 253 | 254 | if (targetit->s == target) { |
|---|
| 254 | 255 | break; |
|---|
| 255 | 256 | } |
|---|
| 256 | | } |
|---|
| 257 | | |
|---|
| 258 | | if (target && targetit == gIR->targetScopes.rend()) { |
|---|
| | 257 | ++targetit; |
|---|
| | 258 | } |
|---|
| | 259 | |
|---|
| | 260 | if (target && targetit == it_end) { |
|---|
| 259 | 261 | if (lblstmt) |
|---|
| 260 | 262 | error(loc, "cannot goto into try, volatile or synchronized statement at %s", target->loc.toChars()); |
|---|
| … | … | |
| 271 | 273 | // and might already exist push a label scope |
|---|
| 272 | 274 | gIR->func()->pushUniqueLabelScope("enclosing"); |
|---|
| 273 | | IRState::TargetScopeVec::reverse_iterator it; |
|---|
| 274 | | for (it = gIR->targetScopes.rbegin(); it != targetit; ++it) { |
|---|
| | 275 | IrFunction::TargetScopeVec::reverse_iterator it = gIR->func()->targetScopes.rbegin(); |
|---|
| | 276 | while (it != targetit) { |
|---|
| 275 | 277 | if (it->enclosinghandler) |
|---|
| 276 | 278 | it->enclosinghandler->emitCode(gIR); |
|---|
| | 279 | ++it; |
|---|
| 277 | 280 | } |
|---|
| 278 | 281 | gIR->func()->popLabelScope(); |
|---|
| r1141 |
r1145 |
|
| 297 | 297 | |
|---|
| 298 | 298 | // while body code |
|---|
| 299 | | p->targetScopes.push_back(IRTargetScope(this,NULL,whilebb,endbb)); |
|---|
| | 299 | p->func()->targetScopes.push_back(IRTargetScope(this,NULL,whilebb,endbb)); |
|---|
| 300 | 300 | body->toIR(p); |
|---|
| 301 | | p->targetScopes.pop_back(); |
|---|
| | 301 | p->func()->targetScopes.pop_back(); |
|---|
| 302 | 302 | |
|---|
| 303 | 303 | // loop |
|---|
| … | … | |
| 333 | 333 | |
|---|
| 334 | 334 | // do-while body code |
|---|
| 335 | | p->targetScopes.push_back(IRTargetScope(this,NULL,condbb,endbb)); |
|---|
| | 335 | p->func()->targetScopes.push_back(IRTargetScope(this,NULL,condbb,endbb)); |
|---|
| 336 | 336 | body->toIR(p); |
|---|
| 337 | | p->targetScopes.pop_back(); |
|---|
| | 337 | p->func()->targetScopes.pop_back(); |
|---|
| 338 | 338 | |
|---|
| 339 | 339 | // branch to condition block |
|---|
| … | … | |
| 378 | 378 | llvm::BranchInst::Create(forbb, gIR->scopebb()); |
|---|
| 379 | 379 | |
|---|
| 380 | | p->targetScopes.push_back(IRTargetScope(this,NULL,forincbb,endbb)); |
|---|
| | 380 | p->func()->targetScopes.push_back(IRTargetScope(this,NULL,forincbb,endbb)); |
|---|
| 381 | 381 | |
|---|
| 382 | 382 | // replace current scope |
|---|
| … | … | |
| 421 | 421 | llvm::BranchInst::Create(forbb, gIR->scopebb()); |
|---|
| 422 | 422 | |
|---|
| 423 | | p->targetScopes.pop_back(); |
|---|
| | 423 | p->func()->targetScopes.pop_back(); |
|---|
| 424 | 424 | |
|---|
| 425 | 425 | // rewrite the scope |
|---|
| … | … | |
| 455 | 455 | // find the right break block and jump there |
|---|
| 456 | 456 | bool found = false; |
|---|
| 457 | | IRState::TargetScopeVec::reverse_iterator it; |
|---|
| 458 | | for(it = p->targetScopes.rbegin(); it != p->targetScopes.rend(); ++it) { |
|---|
| | 457 | IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); |
|---|
| | 458 | IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); |
|---|
| | 459 | while(it != it_end) { |
|---|
| 459 | 460 | if(it->s == targetLoopStatement) { |
|---|
| 460 | 461 | llvm::BranchInst::Create(it->breakTarget, p->scopebb()); |
|---|
| … | … | |
| 462 | 463 | break; |
|---|
| 463 | 464 | } |
|---|
| | 465 | ++it; |
|---|
| 464 | 466 | } |
|---|
| 465 | 467 | assert(found); |
|---|
| … | … | |
| 467 | 469 | else { |
|---|
| 468 | 470 | // find closest scope with a break target |
|---|
| 469 | | IRState::TargetScopeVec::reverse_iterator it; |
|---|
| 470 | | for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) { |
|---|
| | 471 | IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); |
|---|
| | 472 | IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); |
|---|
| | 473 | while(it != it_end) { |
|---|
| 471 | 474 | if(it->breakTarget) { |
|---|
| 472 | 475 | break; |
|---|
| 473 | 476 | } |
|---|
| | 477 | ++it; |
|---|
| 474 | 478 | } |
|---|
| 475 | 479 | DtoEnclosingHandlers(loc, it->s); |
|---|
| … | … | |
| 506 | 510 | // find the right continue block and jump there |
|---|
| 507 | 511 | bool found = false; |
|---|
| 508 | | IRState::TargetScopeVec::reverse_iterator it; |
|---|
| 509 | | for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) { |
|---|
| | 512 | IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); |
|---|
| | 513 | IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); |
|---|
| | 514 | while(it != it_end) { |
|---|
| 510 | 515 | if(it->s == targetLoopStatement) { |
|---|
| 511 | 516 | llvm::BranchInst::Create(it->continueTarget, gIR->scopebb()); |
|---|
| … | … | |
| 513 | 518 | break; |
|---|
| 514 | 519 | } |
|---|
| | 520 | ++it; |
|---|
| 515 | 521 | } |
|---|
| 516 | 522 | assert(found); |
|---|
| … | … | |
| 518 | 524 | else { |
|---|
| 519 | 525 | // find closest scope with a continue target |
|---|
| 520 | | IRState::TargetScopeVec::reverse_iterator it; |
|---|
| 521 | | for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) { |
|---|
| | 526 | IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); |
|---|
| | 527 | IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); |
|---|
| | 528 | while(it != it_end) { |
|---|
| 522 | 529 | if(it->continueTarget) { |
|---|
| 523 | 530 | break; |
|---|
| 524 | 531 | } |
|---|
| | 532 | ++it; |
|---|
| 525 | 533 | } |
|---|
| 526 | 534 | DtoEnclosingHandlers(loc, it->s); |
|---|
| … | … | |
| 594 | 602 | |
|---|
| 595 | 603 | assert(body); |
|---|
| 596 | | p->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this),NULL,NULL)); |
|---|
| | 604 | p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this),NULL,NULL)); |
|---|
| 597 | 605 | body->toIR(p); |
|---|
| 598 | | p->targetScopes.pop_back(); |
|---|
| | 606 | p->func()->targetScopes.pop_back(); |
|---|
| 599 | 607 | |
|---|
| 600 | 608 | // terminate try BB |
|---|
| … | … | |
| 852 | 860 | |
|---|
| 853 | 861 | p->scope() = IRScope(bodybb, endbb); |
|---|
| 854 | | p->targetScopes.push_back(IRTargetScope(this,NULL,NULL,endbb)); |
|---|
| | 862 | p->func()->targetScopes.push_back(IRTargetScope(this,NULL,NULL,endbb)); |
|---|
| 855 | 863 | body->toIR(p); |
|---|
| 856 | | p->targetScopes.pop_back(); |
|---|
| | 864 | p->func()->targetScopes.pop_back(); |
|---|
| 857 | 865 | |
|---|
| 858 | 866 | if (!p->scopereturned()) |
|---|
| … | … | |
| 973 | 981 | // push loop scope |
|---|
| 974 | 982 | // continue goes to next statement, break goes to end |
|---|
| 975 | | p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); |
|---|
| | 983 | p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); |
|---|
| 976 | 984 | |
|---|
| 977 | 985 | // do statement |
|---|
| … | … | |
| 979 | 987 | |
|---|
| 980 | 988 | // pop loop scope |
|---|
| 981 | | p->targetScopes.pop_back(); |
|---|
| | 989 | p->func()->targetScopes.pop_back(); |
|---|
| 982 | 990 | |
|---|
| 983 | 991 | // next stmt |
|---|
| … | … | |
| 1096 | 1104 | |
|---|
| 1097 | 1105 | // emit body |
|---|
| 1098 | | p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); |
|---|
| | 1106 | p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); |
|---|
| 1099 | 1107 | if(body) |
|---|
| 1100 | 1108 | body->toIR(p); |
|---|
| 1101 | | p->targetScopes.pop_back(); |
|---|
| | 1109 | p->func()->targetScopes.pop_back(); |
|---|
| 1102 | 1110 | |
|---|
| 1103 | 1111 | if (!p->scopereturned()) |
|---|
| … | … | |
| 1192 | 1200 | |
|---|
| 1193 | 1201 | // emit body |
|---|
| 1194 | | p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); |
|---|
| | 1202 | p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); |
|---|
| 1195 | 1203 | if (body) |
|---|
| 1196 | 1204 | body->toIR(p); |
|---|
| 1197 | | p->targetScopes.pop_back(); |
|---|
| | 1205 | p->func()->targetScopes.pop_back(); |
|---|
| 1198 | 1206 | |
|---|
| 1199 | 1207 | // jump to next iteration |
|---|
| … | … | |
| 1262 | 1270 | |
|---|
| 1263 | 1271 | if (statement) { |
|---|
| 1264 | | p->targetScopes.push_back(IRTargetScope(this,NULL,NULL,NULL)); |
|---|
| | 1272 | p->func()->targetScopes.push_back(IRTargetScope(this,NULL,NULL,NULL)); |
|---|
| 1265 | 1273 | statement->toIR(p); |
|---|
| 1266 | | p->targetScopes.pop_back(); |
|---|
| | 1274 | p->func()->targetScopes.pop_back(); |
|---|
| 1267 | 1275 | } |
|---|
| 1268 | 1276 | } |
|---|
| … | … | |
| 1386 | 1394 | |
|---|
| 1387 | 1395 | // emit body |
|---|
| 1388 | | p->targetScopes.push_back(IRTargetScope(this,new EnclosingSynchro(this),NULL,NULL)); |
|---|
| | 1396 | p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingSynchro(this),NULL,NULL)); |
|---|
| 1389 | 1397 | body->toIR(p); |
|---|
| 1390 | | p->targetScopes.pop_back(); |
|---|
| | 1398 | p->func()->targetScopes.pop_back(); |
|---|
| 1391 | 1399 | |
|---|
| 1392 | 1400 | // exit lock |
|---|
| … | … | |
| 1420 | 1428 | |
|---|
| 1421 | 1429 | // do statement |
|---|
| 1422 | | p->targetScopes.push_back(IRTargetScope(this,new EnclosingVolatile(this),NULL,NULL)); |
|---|
| | 1430 | p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingVolatile(this),NULL,NULL)); |
|---|
| 1423 | 1431 | statement->toIR(p); |
|---|
| 1424 | | p->targetScopes.pop_back(); |
|---|
| | 1432 | p->func()->targetScopes.pop_back(); |
|---|
| 1425 | 1433 | |
|---|
| 1426 | 1434 | // no point in a unreachable barrier, terminating statements must insert this themselves. |
|---|
| r1051 |
r1145 |
|
| 9 | 9 | #include <stack> |
|---|
| 10 | 10 | #include <map> |
|---|
| | 11 | |
|---|
| | 12 | struct Statement; |
|---|
| | 13 | struct EnclosingHandler; |
|---|
| | 14 | |
|---|
| | 15 | // scope statements that can be target of jumps |
|---|
| | 16 | // includes loops, switch, case, labels |
|---|
| | 17 | struct IRTargetScope |
|---|
| | 18 | { |
|---|
| | 19 | // generating statement |
|---|
| | 20 | Statement* s; |
|---|
| | 21 | |
|---|
| | 22 | // the try of a TryFinally that encloses the loop |
|---|
| | 23 | EnclosingHandler* enclosinghandler; |
|---|
| | 24 | |
|---|
| | 25 | llvm::BasicBlock* breakTarget; |
|---|
| | 26 | llvm::BasicBlock* continueTarget; |
|---|
| | 27 | |
|---|
| | 28 | IRTargetScope(); |
|---|
| | 29 | IRTargetScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* continueTarget, llvm::BasicBlock* breakTarget); |
|---|
| | 30 | }; |
|---|
| 11 | 31 | |
|---|
| 12 | 32 | // represents a function |
|---|
| … | … | |
| 49 | 69 | IRLandingPad landingPad; |
|---|
| 50 | 70 | |
|---|
| | 71 | // loop blocks |
|---|
| | 72 | typedef std::vector<IRTargetScope> TargetScopeVec; |
|---|
| | 73 | TargetScopeVec targetScopes; |
|---|
| | 74 | |
|---|
| | 75 | // constructor |
|---|
| 51 | 76 | IrFunction(FuncDeclaration* fd); |
|---|
| 52 | 77 | |
|---|