comparison gen/statements.cpp @ 302:bef811104734 trunk

[svn r323] Branching out of inline asm works. Renamed emit_finallyblocks to DtoFinallyBlocks and moved to llvmhelpers. Added enclosingtryfinally to AsmBlockStatement, so branches out of asm blocks respect finallys. Refactored some GotoStatement code into DtoGoto.
author ChristianK
date Wed, 25 Jun 2008 20:39:09 +0200
parents df8a7b8d5929
children 3ebc136702dd
comparison
equal deleted inserted replaced
301:f42a1090e895 302:bef811104734
42 s->toIR(p); 42 s->toIR(p);
43 } 43 }
44 } 44 }
45 } 45 }
46 46
47 //////////////////////////////////////////////////////////////////////////////
48
49 // generates IR for finally blocks between the 'start' and 'end' statements
50 // will begin with the finally block belonging to 'start' and does not include
51 // the finally block of 'end'
52 void emit_finallyblocks(IRState* p, TryFinallyStatement* start, TryFinallyStatement* end)
53 {
54 // verify that end encloses start
55 TryFinallyStatement* endfinally = start;
56 while(endfinally != NULL && endfinally != end) {
57 endfinally = endfinally->enclosingtryfinally;
58 }
59 assert(endfinally == end);
60
61 // emit code for finallys between start and end
62 TryFinallyStatement* tf = start;
63 while(tf != end) {
64 tf->finalbody->toIR(p);
65 tf = tf->enclosingtryfinally;
66 }
67 }
68 47
69 ////////////////////////////////////////////////////////////////////////////// 48 //////////////////////////////////////////////////////////////////////////////
70 49
71 void ReturnStatement::toIR(IRState* p) 50 void ReturnStatement::toIR(IRState* p)
72 { 51 {
89 p->exps.pop_back(); 68 p->exps.pop_back();
90 69
91 if (!e->inPlace()) 70 if (!e->inPlace())
92 DtoAssign(rvar, e); 71 DtoAssign(rvar, e);
93 72
94 emit_finallyblocks(p, enclosingtryfinally, NULL); 73 DtoFinallyBlocks(enclosingtryfinally, NULL);
95 74
96 if (f->inVolatile) { 75 if (f->inVolatile) {
97 // store-load barrier 76 // store-load barrier
98 DtoMemoryBarrier(false, false, true, false); 77 DtoMemoryBarrier(false, false, true, false);
99 } 78 }
114 { 93 {
115 v = gIR->ir->CreateBitCast(v, p->topfunc()->getReturnType(), "tmp"); 94 v = gIR->ir->CreateBitCast(v, p->topfunc()->getReturnType(), "tmp");
116 Logger::cout() << "return value after cast: " << *v << '\n'; 95 Logger::cout() << "return value after cast: " << *v << '\n';
117 } 96 }
118 97
119 emit_finallyblocks(p, enclosingtryfinally, NULL); 98 DtoFinallyBlocks(enclosingtryfinally, NULL);
120 99
121 if (gIR->func()->inVolatile) { 100 if (gIR->func()->inVolatile) {
122 // store-load barrier 101 // store-load barrier
123 DtoMemoryBarrier(false, false, true, false); 102 DtoMemoryBarrier(false, false, true, false);
124 } 103 }
128 } 107 }
129 } 108 }
130 else 109 else
131 { 110 {
132 assert(p->topfunc()->getReturnType() == LLType::VoidTy); 111 assert(p->topfunc()->getReturnType() == LLType::VoidTy);
133 emit_finallyblocks(p, enclosingtryfinally, NULL); 112 DtoFinallyBlocks(enclosingtryfinally, NULL);
134 113
135 if (gIR->func()->inVolatile) { 114 if (gIR->func()->inVolatile) {
136 // store-load barrier 115 // store-load barrier
137 DtoMemoryBarrier(false, false, true, false); 116 DtoMemoryBarrier(false, false, true, false);
138 } 117 }
429 DtoDwarfStopPoint(loc.linnum); 408 DtoDwarfStopPoint(loc.linnum);
430 409
431 if (ident != 0) { 410 if (ident != 0) {
432 Logger::println("ident = %s", ident->toChars()); 411 Logger::println("ident = %s", ident->toChars());
433 412
434 emit_finallyblocks(p, enclosingtryfinally, target->enclosingtryfinally); 413 DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally);
435 414
436 // get the loop statement the label refers to 415 // get the loop statement the label refers to
437 Statement* targetLoopStatement = target->statement; 416 Statement* targetLoopStatement = target->statement;
438 ScopeStatement* tmp; 417 ScopeStatement* tmp;
439 while(tmp = targetLoopStatement->isScopeStatement()) 418 while(tmp = targetLoopStatement->isScopeStatement())
450 } 429 }
451 } 430 }
452 assert(found); 431 assert(found);
453 } 432 }
454 else { 433 else {
455 emit_finallyblocks(p, enclosingtryfinally, p->loopbbs.back().enclosingtryfinally); 434 DtoFinallyBlocks(enclosingtryfinally, p->loopbbs.back().enclosingtryfinally);
456 llvm::BranchInst::Create(p->loopbbs.back().end, p->scopebb()); 435 llvm::BranchInst::Create(p->loopbbs.back().end, p->scopebb());
457 } 436 }
458 437
459 // the break terminated this basicblock, start a new one 438 // the break terminated this basicblock, start a new one
460 llvm::BasicBlock* oldend = gIR->scopeend(); 439 llvm::BasicBlock* oldend = gIR->scopeend();
473 DtoDwarfStopPoint(loc.linnum); 452 DtoDwarfStopPoint(loc.linnum);
474 453
475 if (ident != 0) { 454 if (ident != 0) {
476 Logger::println("ident = %s", ident->toChars()); 455 Logger::println("ident = %s", ident->toChars());
477 456
478 emit_finallyblocks(p, enclosingtryfinally, target->enclosingtryfinally); 457 DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally);
479 458
480 // get the loop statement the label refers to 459 // get the loop statement the label refers to
481 Statement* targetLoopStatement = target->statement; 460 Statement* targetLoopStatement = target->statement;
482 ScopeStatement* tmp; 461 ScopeStatement* tmp;
483 while(tmp = targetLoopStatement->isScopeStatement()) 462 while(tmp = targetLoopStatement->isScopeStatement())
492 } 471 }
493 } 472 }
494 assert(0); 473 assert(0);
495 } 474 }
496 else { 475 else {
497 emit_finallyblocks(p, enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally); 476 DtoFinallyBlocks(enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally);
498 llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb()); 477 llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb());
499 } 478 }
500 } 479 }
501 480
502 ////////////////////////////////////////////////////////////////////////////// 481 //////////////////////////////////////////////////////////////////////////////
1106 assert(tf == NULL); 1085 assert(tf == NULL);
1107 1086
1108 llvm::BasicBlock* oldend = gIR->scopeend(); 1087 llvm::BasicBlock* oldend = gIR->scopeend();
1109 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend); 1088 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend);
1110 1089
1111 if (label->statement->llvmBB == NULL) 1090 DtoGoto(&loc, label, enclosingtryfinally);
1112 label->statement->llvmBB = llvm::BasicBlock::Create("label", p->topfunc()); 1091
1113 assert(!p->scopereturned());
1114
1115 // find finallys between goto and label
1116 TryFinallyStatement* endfinally = enclosingtryfinally;
1117 while(endfinally != NULL && endfinally != label->statement->enclosingtryfinally) {
1118 endfinally = endfinally->enclosingtryfinally;
1119 }
1120
1121 // error if didn't find tf statement of label
1122 if(endfinally != label->statement->enclosingtryfinally)
1123 error("cannot goto into try block", loc.toChars());
1124
1125 // emit code for finallys between goto and label
1126 emit_finallyblocks(p, enclosingtryfinally, endfinally);
1127
1128 llvm::BranchInst::Create(label->statement->llvmBB, p->scopebb());
1129 p->scope() = IRScope(bb,oldend); 1092 p->scope() = IRScope(bb,oldend);
1130 } 1093 }
1131 1094
1132 ////////////////////////////////////////////////////////////////////////////// 1095 //////////////////////////////////////////////////////////////////////////////
1133 1096
1143 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotodefault", p->topfunc(), oldend); 1106 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotodefault", p->topfunc(), oldend);
1144 1107
1145 assert(!p->scopereturned()); 1108 assert(!p->scopereturned());
1146 assert(sw->sdefault->bodyBB); 1109 assert(sw->sdefault->bodyBB);
1147 1110
1148 emit_finallyblocks(p, enclosingtryfinally, sw->enclosingtryfinally); 1111 DtoFinallyBlocks(enclosingtryfinally, sw->enclosingtryfinally);
1149 1112
1150 llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb()); 1113 llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb());
1151 p->scope() = IRScope(bb,oldend); 1114 p->scope() = IRScope(bb,oldend);
1152 } 1115 }
1153 1116
1168 if (!cs->bodyBB) 1131 if (!cs->bodyBB)
1169 { 1132 {
1170 cs->bodyBB = llvm::BasicBlock::Create("goto_case", p->topfunc(), p->scopeend()); 1133 cs->bodyBB = llvm::BasicBlock::Create("goto_case", p->topfunc(), p->scopeend());
1171 } 1134 }
1172 1135
1173 emit_finallyblocks(p, enclosingtryfinally, sw->enclosingtryfinally); 1136 DtoFinallyBlocks(enclosingtryfinally, sw->enclosingtryfinally);
1174 1137
1175 llvm::BranchInst::Create(cs->bodyBB, p->scopebb()); 1138 llvm::BranchInst::Create(cs->bodyBB, p->scopebb());
1176 p->scope() = IRScope(bb,oldend); 1139 p->scope() = IRScope(bb,oldend);
1177 } 1140 }
1178 1141