comparison gen/statements.cpp @ 309:d59c363fccad trunk

[svn r330] Implemented synchronized statements. Changed the tryfinally handlers to a more generalized EnclosingHandler. Changed ClassInfoS to be mutable so they can be used as locks. Added new BB after throw ala return/break etc.
author lindquist
date Sat, 28 Jun 2008 11:37:53 +0200
parents 6b62e8cdf970
children 9967a3270837
comparison
equal deleted inserted replaced
308:6b62e8cdf970 309:d59c363fccad
68 p->exps.pop_back(); 68 p->exps.pop_back();
69 69
70 if (!e->inPlace()) 70 if (!e->inPlace())
71 DtoAssign(rvar, e); 71 DtoAssign(rvar, e);
72 72
73 DtoFinallyBlocks(enclosingtryfinally, NULL); 73 DtoEnclosingHandlers(enclosinghandler, NULL);
74
75 if (f->inVolatile) {
76 // store-load barrier
77 DtoMemoryBarrier(false, false, true, false);
78 }
79 74
80 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); 75 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
81 llvm::ReturnInst::Create(p->scopebb()); 76 llvm::ReturnInst::Create(p->scopebb());
82 77
83 } 78 }
93 { 88 {
94 v = gIR->ir->CreateBitCast(v, p->topfunc()->getReturnType(), "tmp"); 89 v = gIR->ir->CreateBitCast(v, p->topfunc()->getReturnType(), "tmp");
95 Logger::cout() << "return value after cast: " << *v << '\n'; 90 Logger::cout() << "return value after cast: " << *v << '\n';
96 } 91 }
97 92
98 DtoFinallyBlocks(enclosingtryfinally, NULL); 93 DtoEnclosingHandlers(enclosinghandler, NULL);
99
100 if (gIR->func()->inVolatile) {
101 // store-load barrier
102 DtoMemoryBarrier(false, false, true, false);
103 }
104 94
105 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 95 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
106 llvm::ReturnInst::Create(v, p->scopebb()); 96 llvm::ReturnInst::Create(v, p->scopebb());
107 } 97 }
108 } 98 }
109 else 99 else
110 { 100 {
111 assert(p->topfunc()->getReturnType() == LLType::VoidTy); 101 assert(p->topfunc()->getReturnType() == LLType::VoidTy);
112 DtoFinallyBlocks(enclosingtryfinally, NULL); 102 DtoEnclosingHandlers(enclosinghandler, NULL);
113
114 if (gIR->func()->inVolatile) {
115 // store-load barrier
116 DtoMemoryBarrier(false, false, true, false);
117 }
118 103
119 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 104 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
120 llvm::ReturnInst::Create(p->scopebb()); 105 llvm::ReturnInst::Create(p->scopebb());
121 } 106 }
122 107
273 258
274 // rewrite scope 259 // rewrite scope
275 gIR->scope() = IRScope(whilebodybb,endbb); 260 gIR->scope() = IRScope(whilebodybb,endbb);
276 261
277 // while body code 262 // while body code
278 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,whilebb,endbb)); 263 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,whilebb,endbb));
279 body->toIR(p); 264 body->toIR(p);
280 p->loopbbs.pop_back(); 265 p->loopbbs.pop_back();
281 266
282 // loop 267 // loop
283 if (!gIR->scopereturned()) 268 if (!gIR->scopereturned())
308 293
309 // replace current scope 294 // replace current scope
310 gIR->scope() = IRScope(dowhilebb,endbb); 295 gIR->scope() = IRScope(dowhilebb,endbb);
311 296
312 // do-while body code 297 // do-while body code
313 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,dowhilebb,endbb)); 298 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,dowhilebb,endbb));
314 body->toIR(p); 299 body->toIR(p);
315 p->loopbbs.pop_back(); 300 p->loopbbs.pop_back();
316 301
317 // create the condition 302 // create the condition
318 DValue* cond_e = condition->toElem(p); 303 DValue* cond_e = condition->toElem(p);
349 334
350 // move into the for condition block, ie. start the loop 335 // move into the for condition block, ie. start the loop
351 assert(!gIR->scopereturned()); 336 assert(!gIR->scopereturned());
352 llvm::BranchInst::Create(forbb, gIR->scopebb()); 337 llvm::BranchInst::Create(forbb, gIR->scopebb());
353 338
354 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,forincbb,endbb)); 339 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,forincbb,endbb));
355 340
356 // replace current scope 341 // replace current scope
357 gIR->scope() = IRScope(forbb,forbodybb); 342 gIR->scope() = IRScope(forbb,forbodybb);
358 343
359 // create the condition 344 // create the condition
408 DtoDwarfStopPoint(loc.linnum); 393 DtoDwarfStopPoint(loc.linnum);
409 394
410 if (ident != 0) { 395 if (ident != 0) {
411 Logger::println("ident = %s", ident->toChars()); 396 Logger::println("ident = %s", ident->toChars());
412 397
413 DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally); 398 DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler);
414 399
415 // get the loop statement the label refers to 400 // get the loop statement the label refers to
416 Statement* targetLoopStatement = target->statement; 401 Statement* targetLoopStatement = target->statement;
417 ScopeStatement* tmp; 402 ScopeStatement* tmp;
418 while(tmp = targetLoopStatement->isScopeStatement()) 403 while(tmp = targetLoopStatement->isScopeStatement())
429 } 414 }
430 } 415 }
431 assert(found); 416 assert(found);
432 } 417 }
433 else { 418 else {
434 DtoFinallyBlocks(enclosingtryfinally, p->loopbbs.back().enclosingtryfinally); 419 DtoEnclosingHandlers(enclosinghandler, p->loopbbs.back().enclosinghandler);
435 llvm::BranchInst::Create(p->loopbbs.back().end, p->scopebb()); 420 llvm::BranchInst::Create(p->loopbbs.back().end, p->scopebb());
436 } 421 }
437 422
438 // the break terminated this basicblock, start a new one 423 // the break terminated this basicblock, start a new one
439 llvm::BasicBlock* oldend = gIR->scopeend(); 424 llvm::BasicBlock* oldend = gIR->scopeend();
452 DtoDwarfStopPoint(loc.linnum); 437 DtoDwarfStopPoint(loc.linnum);
453 438
454 if (ident != 0) { 439 if (ident != 0) {
455 Logger::println("ident = %s", ident->toChars()); 440 Logger::println("ident = %s", ident->toChars());
456 441
457 DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally); 442 DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler);
458 443
459 // get the loop statement the label refers to 444 // get the loop statement the label refers to
460 Statement* targetLoopStatement = target->statement; 445 Statement* targetLoopStatement = target->statement;
461 ScopeStatement* tmp; 446 ScopeStatement* tmp;
462 while(tmp = targetLoopStatement->isScopeStatement()) 447 while(tmp = targetLoopStatement->isScopeStatement())
471 } 456 }
472 } 457 }
473 assert(0); 458 assert(0);
474 } 459 }
475 else { 460 else {
476 DtoFinallyBlocks(enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally); 461 DtoEnclosingHandlers(enclosinghandler, gIR->loopbbs.back().enclosinghandler);
477 llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb()); 462 llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb());
478 } 463 }
479 } 464 }
480 465
481 ////////////////////////////////////////////////////////////////////////////// 466 //////////////////////////////////////////////////////////////////////////////
597 //Logger::cout() << "calling: " << *fn << '\n'; 582 //Logger::cout() << "calling: " << *fn << '\n';
598 LLValue* arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0)); 583 LLValue* arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0));
599 //Logger::cout() << "arg: " << *arg << '\n'; 584 //Logger::cout() << "arg: " << *arg << '\n';
600 gIR->ir->CreateCall(fn, arg, ""); 585 gIR->ir->CreateCall(fn, arg, "");
601 gIR->ir->CreateUnreachable(); 586 gIR->ir->CreateUnreachable();
587
588 // need a block after the throw for now
589 llvm::BasicBlock* oldend = gIR->scopeend();
590 llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterthrow", p->topfunc(), oldend);
591 p->scope() = IRScope(bb,oldend);
602 } 592 }
603 593
604 ////////////////////////////////////////////////////////////////////////////// 594 //////////////////////////////////////////////////////////////////////////////
605 595
606 // used to build the sorted list of cases 596 // used to build the sorted list of cases
765 755
766 // do switch body 756 // do switch body
767 assert(body); 757 assert(body);
768 758
769 p->scope() = IRScope(bodybb, endbb); 759 p->scope() = IRScope(bodybb, endbb);
770 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,p->scopebb(),endbb)); 760 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb));
771 body->toIR(p); 761 body->toIR(p);
772 p->loopbbs.pop_back(); 762 p->loopbbs.pop_back();
773 763
774 if (!p->scopereturned()) 764 if (!p->scopereturned())
775 llvm::BranchInst::Create(endbb, p->scopebb()); 765 llvm::BranchInst::Create(endbb, p->scopebb());
849 839
850 llvm::BasicBlock* oldend = gIR->scopeend(); 840 llvm::BasicBlock* oldend = gIR->scopeend();
851 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend); 841 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend);
852 842
853 p->scope() = IRScope(p->scopebb(),endbb); 843 p->scope() = IRScope(p->scopebb(),endbb);
854 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,p->scopebb(),endbb)); 844 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb));
855 845
856 for (int i=0; i<statements->dim; ++i) 846 for (int i=0; i<statements->dim; ++i)
857 { 847 {
858 Statement* s = (Statement*)statements->data[i]; 848 Statement* s = (Statement*)statements->data[i];
859 s->toIR(p); 849 s->toIR(p);
972 DtoAssign(dst, src); 962 DtoAssign(dst, src);
973 value->ir.irLocal->value = valvar; 963 value->ir.irLocal->value = valvar;
974 } 964 }
975 965
976 // emit body 966 // emit body
977 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,nextbb,endbb)); 967 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb));
978 body->toIR(p); 968 body->toIR(p);
979 p->loopbbs.pop_back(); 969 p->loopbbs.pop_back();
980 970
981 if (!p->scopereturned()) 971 if (!p->scopereturned())
982 llvm::BranchInst::Create(nextbb, p->scopebb()); 972 llvm::BranchInst::Create(nextbb, p->scopebb());
1045 assert(tf == NULL); 1035 assert(tf == NULL);
1046 1036
1047 llvm::BasicBlock* oldend = gIR->scopeend(); 1037 llvm::BasicBlock* oldend = gIR->scopeend();
1048 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend); 1038 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend);
1049 1039
1050 DtoGoto(&loc, label->ident, enclosingtryfinally); 1040 DtoGoto(&loc, label->ident, enclosinghandler);
1051 1041
1052 p->scope() = IRScope(bb,oldend); 1042 p->scope() = IRScope(bb,oldend);
1053 } 1043 }
1054 1044
1055 ////////////////////////////////////////////////////////////////////////////// 1045 //////////////////////////////////////////////////////////////////////////////
1066 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotodefault", p->topfunc(), oldend); 1056 llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotodefault", p->topfunc(), oldend);
1067 1057
1068 assert(!p->scopereturned()); 1058 assert(!p->scopereturned());
1069 assert(sw->sdefault->bodyBB); 1059 assert(sw->sdefault->bodyBB);
1070 1060
1071 DtoFinallyBlocks(enclosingtryfinally, sw->enclosingtryfinally); 1061 DtoEnclosingHandlers(enclosinghandler, sw->enclosinghandler);
1072 1062
1073 llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb()); 1063 llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb());
1074 p->scope() = IRScope(bb,oldend); 1064 p->scope() = IRScope(bb,oldend);
1075 } 1065 }
1076 1066
1091 if (!cs->bodyBB) 1081 if (!cs->bodyBB)
1092 { 1082 {
1093 cs->bodyBB = llvm::BasicBlock::Create("goto_case", p->topfunc(), p->scopeend()); 1083 cs->bodyBB = llvm::BasicBlock::Create("goto_case", p->topfunc(), p->scopeend());
1094 } 1084 }
1095 1085
1096 DtoFinallyBlocks(enclosingtryfinally, sw->enclosingtryfinally); 1086 DtoEnclosingHandlers(enclosinghandler, sw->enclosinghandler);
1097 1087
1098 llvm::BranchInst::Create(cs->bodyBB, p->scopebb()); 1088 llvm::BranchInst::Create(cs->bodyBB, p->scopebb());
1099 p->scope() = IRScope(bb,oldend); 1089 p->scope() = IRScope(bb,oldend);
1100 } 1090 }
1101 1091
1120 body->toIR(p); 1110 body->toIR(p);
1121 } 1111 }
1122 1112
1123 ////////////////////////////////////////////////////////////////////////////// 1113 //////////////////////////////////////////////////////////////////////////////
1124 1114
1115 static LLConstant* generate_unique_critical_section()
1116 {
1117 const LLType* Mty = DtoMutexType();
1118 return new llvm::GlobalVariable(Mty, false, llvm::GlobalValue::InternalLinkage, LLConstant::getNullValue(Mty), ".uniqueCS", gIR->module);
1119 }
1120
1125 void SynchronizedStatement::toIR(IRState* p) 1121 void SynchronizedStatement::toIR(IRState* p)
1126 { 1122 {
1127 Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars()); 1123 Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars());
1128 LOG_SCOPE; 1124 LOG_SCOPE;
1129 1125
1130 Logger::attention(loc, "synchronized is currently ignored. only the body will be emitted"); 1126 if (global.params.symdebug)
1131 1127 DtoDwarfStopPoint(loc.linnum);
1132 if (global.params.symdebug) 1128
1133 DtoDwarfStopPoint(loc.linnum); 1129 // enter lock
1134 1130 if (exp)
1131 {
1132 llsync = exp->toElem(p)->getRVal();
1133 DtoEnterMonitor(llsync);
1134 }
1135 else
1136 {
1137 llsync = generate_unique_critical_section();
1138 DtoEnterCritical(llsync);
1139 }
1140
1141 // emit body
1135 body->toIR(p); 1142 body->toIR(p);
1136 } 1143
1137 1144 // exit lock
1138 ////////////////////////////////////////////////////////////////////////////// 1145 // no point in a unreachable unlock, terminating statements must insert this themselves.
1139 1146 if (p->scopereturned())
1140 /* this has moved to asmstmt.cpp 1147 return;
1141 void AsmStatement::toIR(IRState* p) 1148 else if (exp)
1142 { 1149 DtoLeaveMonitor(llsync);
1143 Logger::println("AsmStatement::toIR(): %s", loc.toChars()); 1150 else
1144 LOG_SCOPE; 1151 DtoLeaveCritical(llsync);
1145 // error("%s: inline asm is not yet implemented", loc.toChars()); 1152 }
1146 // fatal(); 1153
1147
1148 assert(!asmcode && !asmalign && !refparam && !naked && !regs);
1149
1150 Token* t = tokens;
1151 assert(t);
1152
1153 std::string asmstr;
1154
1155 do {
1156 Logger::println("token: %s", t->toChars());
1157 asmstr.append(t->toChars());
1158 asmstr.append(" ");
1159 } while (t = t->next);
1160
1161 Logger::println("asm expr = '%s'", asmstr.c_str());
1162
1163 // create function type
1164 std::vector<const LLType*> args;
1165 const llvm::FunctionType* fty = llvm::FunctionType::get(DtoSize_t(), args, false);
1166
1167 // create inline asm callee
1168 llvm::InlineAsm* inasm = llvm::InlineAsm::get(fty, asmstr, "r,r", false);
1169
1170 assert(0);
1171 }
1172 */
1173 ////////////////////////////////////////////////////////////////////////////// 1154 //////////////////////////////////////////////////////////////////////////////
1174 1155
1175 void VolatileStatement::toIR(IRState* p) 1156 void VolatileStatement::toIR(IRState* p)
1176 { 1157 {
1177 Logger::println("VolatileStatement::toIR(): %s", loc.toChars()); 1158 Logger::println("VolatileStatement::toIR(): %s", loc.toChars());
1179 1160
1180 if (global.params.symdebug) 1161 if (global.params.symdebug)
1181 DtoDwarfStopPoint(loc.linnum); 1162 DtoDwarfStopPoint(loc.linnum);
1182 1163
1183 // mark in-volatile 1164 // mark in-volatile
1184 bool old = gIR->func()->inVolatile; 1165 // FIXME
1185 gIR->func()->inVolatile = true;
1186 1166
1187 // has statement 1167 // has statement
1188 if (statement != NULL) 1168 if (statement != NULL)
1189 { 1169 {
1190 // load-store 1170 // load-store
1191 DtoMemoryBarrier(false, true, false, false); 1171 DtoMemoryBarrier(false, true, false, false);
1192 1172
1193 // do statement 1173 // do statement
1194 statement->toIR(p); 1174 statement->toIR(p);
1195 1175
1196 // no point in a unreachable barrier, terminating statements should insert this themselves. 1176 // no point in a unreachable barrier, terminating statements must insert this themselves.
1197 if (statement->fallOffEnd()) 1177 if (statement->fallOffEnd())
1198 { 1178 {
1199 // store-load 1179 // store-load
1200 DtoMemoryBarrier(false, false, true, false); 1180 DtoMemoryBarrier(false, false, true, false);
1201 } 1181 }
1206 // load-store & store-load 1186 // load-store & store-load
1207 DtoMemoryBarrier(false, true, true, false); 1187 DtoMemoryBarrier(false, true, true, false);
1208 } 1188 }
1209 1189
1210 // restore volatile state 1190 // restore volatile state
1211 gIR->func()->inVolatile = old; 1191 // FIXME
1212 } 1192 }
1213 1193
1214 ////////////////////////////////////////////////////////////////////////////// 1194 //////////////////////////////////////////////////////////////////////////////
1215 1195
1216 ////////////////////////////////////////////////////////////////////////////// 1196 //////////////////////////////////////////////////////////////////////////////