Mercurial > projects > ldc
diff 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 |
line wrap: on
line diff
--- a/gen/statements.cpp Sat Jun 28 05:57:16 2008 +0200 +++ b/gen/statements.cpp Sat Jun 28 11:37:53 2008 +0200 @@ -70,12 +70,7 @@ if (!e->inPlace()) DtoAssign(rvar, e); - DtoFinallyBlocks(enclosingtryfinally, NULL); - - if (f->inVolatile) { - // store-load barrier - DtoMemoryBarrier(false, false, true, false); - } + DtoEnclosingHandlers(enclosinghandler, NULL); if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); llvm::ReturnInst::Create(p->scopebb()); @@ -95,12 +90,7 @@ Logger::cout() << "return value after cast: " << *v << '\n'; } - DtoFinallyBlocks(enclosingtryfinally, NULL); - - if (gIR->func()->inVolatile) { - // store-load barrier - DtoMemoryBarrier(false, false, true, false); - } + DtoEnclosingHandlers(enclosinghandler, NULL); if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); llvm::ReturnInst::Create(v, p->scopebb()); @@ -109,12 +99,7 @@ else { assert(p->topfunc()->getReturnType() == LLType::VoidTy); - DtoFinallyBlocks(enclosingtryfinally, NULL); - - if (gIR->func()->inVolatile) { - // store-load barrier - DtoMemoryBarrier(false, false, true, false); - } + DtoEnclosingHandlers(enclosinghandler, NULL); if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); llvm::ReturnInst::Create(p->scopebb()); @@ -275,7 +260,7 @@ gIR->scope() = IRScope(whilebodybb,endbb); // while body code - p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,whilebb,endbb)); + p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,whilebb,endbb)); body->toIR(p); p->loopbbs.pop_back(); @@ -310,7 +295,7 @@ gIR->scope() = IRScope(dowhilebb,endbb); // do-while body code - p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,dowhilebb,endbb)); + p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,dowhilebb,endbb)); body->toIR(p); p->loopbbs.pop_back(); @@ -351,7 +336,7 @@ assert(!gIR->scopereturned()); llvm::BranchInst::Create(forbb, gIR->scopebb()); - p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,forincbb,endbb)); + p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,forincbb,endbb)); // replace current scope gIR->scope() = IRScope(forbb,forbodybb); @@ -410,7 +395,7 @@ if (ident != 0) { Logger::println("ident = %s", ident->toChars()); - DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally); + DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler); // get the loop statement the label refers to Statement* targetLoopStatement = target->statement; @@ -431,7 +416,7 @@ assert(found); } else { - DtoFinallyBlocks(enclosingtryfinally, p->loopbbs.back().enclosingtryfinally); + DtoEnclosingHandlers(enclosinghandler, p->loopbbs.back().enclosinghandler); llvm::BranchInst::Create(p->loopbbs.back().end, p->scopebb()); } @@ -454,7 +439,7 @@ if (ident != 0) { Logger::println("ident = %s", ident->toChars()); - DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally); + DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler); // get the loop statement the label refers to Statement* targetLoopStatement = target->statement; @@ -473,7 +458,7 @@ assert(0); } else { - DtoFinallyBlocks(enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally); + DtoEnclosingHandlers(enclosinghandler, gIR->loopbbs.back().enclosinghandler); llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb()); } } @@ -599,6 +584,11 @@ //Logger::cout() << "arg: " << *arg << '\n'; gIR->ir->CreateCall(fn, arg, ""); gIR->ir->CreateUnreachable(); + + // need a block after the throw for now + llvm::BasicBlock* oldend = gIR->scopeend(); + llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterthrow", p->topfunc(), oldend); + p->scope() = IRScope(bb,oldend); } ////////////////////////////////////////////////////////////////////////////// @@ -767,7 +757,7 @@ assert(body); p->scope() = IRScope(bodybb, endbb); - p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,p->scopebb(),endbb)); + p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb)); body->toIR(p); p->loopbbs.pop_back(); @@ -851,7 +841,7 @@ llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend); p->scope() = IRScope(p->scopebb(),endbb); - p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,p->scopebb(),endbb)); + p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb)); for (int i=0; i<statements->dim; ++i) { @@ -974,7 +964,7 @@ } // emit body - p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,nextbb,endbb)); + p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb)); body->toIR(p); p->loopbbs.pop_back(); @@ -1047,7 +1037,7 @@ llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend); - DtoGoto(&loc, label->ident, enclosingtryfinally); + DtoGoto(&loc, label->ident, enclosinghandler); p->scope() = IRScope(bb,oldend); } @@ -1068,7 +1058,7 @@ assert(!p->scopereturned()); assert(sw->sdefault->bodyBB); - DtoFinallyBlocks(enclosingtryfinally, sw->enclosingtryfinally); + DtoEnclosingHandlers(enclosinghandler, sw->enclosinghandler); llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb()); p->scope() = IRScope(bb,oldend); @@ -1093,7 +1083,7 @@ cs->bodyBB = llvm::BasicBlock::Create("goto_case", p->topfunc(), p->scopeend()); } - DtoFinallyBlocks(enclosingtryfinally, sw->enclosingtryfinally); + DtoEnclosingHandlers(enclosinghandler, sw->enclosinghandler); llvm::BranchInst::Create(cs->bodyBB, p->scopebb()); p->scope() = IRScope(bb,oldend); @@ -1122,56 +1112,47 @@ ////////////////////////////////////////////////////////////////////////////// +static LLConstant* generate_unique_critical_section() +{ + const LLType* Mty = DtoMutexType(); + return new llvm::GlobalVariable(Mty, false, llvm::GlobalValue::InternalLinkage, LLConstant::getNullValue(Mty), ".uniqueCS", gIR->module); +} + void SynchronizedStatement::toIR(IRState* p) { Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars()); LOG_SCOPE; - Logger::attention(loc, "synchronized is currently ignored. only the body will be emitted"); - if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); + // enter lock + if (exp) + { + llsync = exp->toElem(p)->getRVal(); + DtoEnterMonitor(llsync); + } + else + { + llsync = generate_unique_critical_section(); + DtoEnterCritical(llsync); + } + + // emit body body->toIR(p); + + // exit lock + // no point in a unreachable unlock, terminating statements must insert this themselves. + if (p->scopereturned()) + return; + else if (exp) + DtoLeaveMonitor(llsync); + else + DtoLeaveCritical(llsync); } ////////////////////////////////////////////////////////////////////////////// -/* this has moved to asmstmt.cpp -void AsmStatement::toIR(IRState* p) -{ - Logger::println("AsmStatement::toIR(): %s", loc.toChars()); - LOG_SCOPE; -// error("%s: inline asm is not yet implemented", loc.toChars()); -// fatal(); - - assert(!asmcode && !asmalign && !refparam && !naked && !regs); - - Token* t = tokens; - assert(t); - - std::string asmstr; - - do { - Logger::println("token: %s", t->toChars()); - asmstr.append(t->toChars()); - asmstr.append(" "); - } while (t = t->next); - - Logger::println("asm expr = '%s'", asmstr.c_str()); - - // create function type - std::vector<const LLType*> args; - const llvm::FunctionType* fty = llvm::FunctionType::get(DtoSize_t(), args, false); - - // create inline asm callee - llvm::InlineAsm* inasm = llvm::InlineAsm::get(fty, asmstr, "r,r", false); - - assert(0); -} -*/ -////////////////////////////////////////////////////////////////////////////// - void VolatileStatement::toIR(IRState* p) { Logger::println("VolatileStatement::toIR(): %s", loc.toChars()); @@ -1181,8 +1162,7 @@ DtoDwarfStopPoint(loc.linnum); // mark in-volatile - bool old = gIR->func()->inVolatile; - gIR->func()->inVolatile = true; + // FIXME // has statement if (statement != NULL) @@ -1193,7 +1173,7 @@ // do statement statement->toIR(p); - // no point in a unreachable barrier, terminating statements should insert this themselves. + // no point in a unreachable barrier, terminating statements must insert this themselves. if (statement->fallOffEnd()) { // store-load @@ -1208,7 +1188,7 @@ } // restore volatile state - gIR->func()->inVolatile = old; + // FIXME } //////////////////////////////////////////////////////////////////////////////