diff gen/statements.cpp @ 205:9d44ec83acd1 trunk

[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 . Fixed: Implemented volatile statements. Uses the LLVM memory barrier intrinsic, closes #21 .
author lindquist
date Tue, 13 May 2008 17:58:11 +0200
parents 8f9191180c7a
children cd2c9f4010e4
line wrap: on
line diff
--- a/gen/statements.cpp	Tue May 13 16:16:50 2008 +0200
+++ b/gen/statements.cpp	Tue May 13 17:58:11 2008 +0200
@@ -92,8 +92,13 @@
 
             emit_finallyblocks(p, enclosingtryfinally, NULL);
 
+            if (gIR->func()->inVolatile) {
+                // store-load barrier
+                DtoMemoryBarrier(false, false, true, false);
+            }
+
             if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
-            new llvm::ReturnInst(p->scopebb());
+            llvm::ReturnInst::Create(p->scopebb());
 
         }
         else {
@@ -112,8 +117,13 @@
 
             emit_finallyblocks(p, enclosingtryfinally, NULL);
 
+            if (gIR->func()->inVolatile) {
+                // store-load barrier
+                DtoMemoryBarrier(false, false, true, false);
+            }
+
             if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
-            new llvm::ReturnInst(v, p->scopebb());
+            llvm::ReturnInst::Create(v, p->scopebb());
         }
     }
     else
@@ -121,8 +131,13 @@
         if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
             emit_finallyblocks(p, enclosingtryfinally, NULL);
 
+            if (gIR->func()->inVolatile) {
+                // store-load barrier
+                DtoMemoryBarrier(false, false, true, false);
+            }
+
             if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
-            new llvm::ReturnInst(p->scopebb());
+            llvm::ReturnInst::Create(p->scopebb());
         }
         else {
             assert(0); // why should this ever happen?
@@ -173,15 +188,15 @@
 
     llvm::BasicBlock* oldend = gIR->scopeend();
 
-    llvm::BasicBlock* ifbb = new llvm::BasicBlock("if", gIR->topfunc(), oldend);
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("endif", gIR->topfunc(), oldend);
-    llvm::BasicBlock* elsebb = elsebody ? new llvm::BasicBlock("else", gIR->topfunc(), endbb) : endbb;
+    llvm::BasicBlock* ifbb = llvm::BasicBlock::Create("if", gIR->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endif", gIR->topfunc(), oldend);
+    llvm::BasicBlock* elsebb = elsebody ? llvm::BasicBlock::Create("else", gIR->topfunc(), endbb) : endbb;
 
     if (cond_val->getType() != llvm::Type::Int1Ty) {
         Logger::cout() << "if conditional: " << *cond_val << '\n';
         cond_val = DtoBoolean(cond_val);
     }
-    llvm::Value* ifgoback = new llvm::BranchInst(ifbb, elsebb, cond_val, gIR->scopebb());
+    llvm::Value* ifgoback = llvm::BranchInst::Create(ifbb, elsebb, cond_val, gIR->scopebb());
 
     // replace current scope
     gIR->scope() = IRScope(ifbb,elsebb);
@@ -189,7 +204,7 @@
     // do scoped statements
     ifbody->toIR(p);
     if (!gIR->scopereturned()) {
-        new llvm::BranchInst(endbb,gIR->scopebb());
+        llvm::BranchInst::Create(endbb,gIR->scopebb());
     }
 
     if (elsebody) {
@@ -197,7 +212,7 @@
         gIR->scope() = IRScope(elsebb,endbb);
         elsebody->toIR(p);
         if (!gIR->scopereturned()) {
-            new llvm::BranchInst(endbb,gIR->scopebb());
+            llvm::BranchInst::Create(endbb,gIR->scopebb());
         }
     }
 
@@ -223,10 +238,10 @@
     }
     else {
         assert(!p->scopereturned());
-        beginbb = new llvm::BasicBlock("scope", p->topfunc(), oldend);
-        new llvm::BranchInst(beginbb, p->scopebb());
+        beginbb = llvm::BasicBlock::Create("scope", p->topfunc(), oldend);
+        llvm::BranchInst::Create(beginbb, p->scopebb());
     }
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("endscope", p->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endscope", p->topfunc(), oldend);
 
     gIR->scope() = IRScope(beginbb, endbb);
 
@@ -246,13 +261,13 @@
 
     // create while blocks
     llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* whilebb = new llvm::BasicBlock("whilecond", gIR->topfunc(), oldend);
-    llvm::BasicBlock* whilebodybb = new llvm::BasicBlock("whilebody", gIR->topfunc(), oldend);
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("endwhile", gIR->topfunc(), oldend);
+    llvm::BasicBlock* whilebb = llvm::BasicBlock::Create("whilecond", gIR->topfunc(), oldend);
+    llvm::BasicBlock* whilebodybb = llvm::BasicBlock::Create("whilebody", gIR->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endwhile", gIR->topfunc(), oldend);
 
     // move into the while block
     p->ir->CreateBr(whilebb);
-    //new llvm::BranchInst(whilebb, gIR->scopebb());
+    //llvm::BranchInst::Create(whilebb, gIR->scopebb());
 
     // replace current scope
     gIR->scope() = IRScope(whilebb,endbb);
@@ -263,7 +278,7 @@
     delete cond_e;
 
     // conditional branch
-    llvm::Value* ifbreak = new llvm::BranchInst(whilebodybb, endbb, cond_val, p->scopebb());
+    llvm::Value* ifbreak = llvm::BranchInst::Create(whilebodybb, endbb, cond_val, p->scopebb());
 
     // rewrite scope
     gIR->scope() = IRScope(whilebodybb,endbb);
@@ -275,7 +290,7 @@
 
     // loop
     if (!gIR->scopereturned())
-        new llvm::BranchInst(whilebb, gIR->scopebb());
+        llvm::BranchInst::Create(whilebb, gIR->scopebb());
 
     // rewrite the scope
     gIR->scope() = IRScope(endbb,oldend);
@@ -290,12 +305,12 @@
 
     // create while blocks
     llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* dowhilebb = new llvm::BasicBlock("dowhile", gIR->topfunc(), oldend);
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("enddowhile", gIR->topfunc(), oldend);
+    llvm::BasicBlock* dowhilebb = llvm::BasicBlock::Create("dowhile", gIR->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("enddowhile", gIR->topfunc(), oldend);
 
     // move into the while block
     assert(!gIR->scopereturned());
-    new llvm::BranchInst(dowhilebb, gIR->scopebb());
+    llvm::BranchInst::Create(dowhilebb, gIR->scopebb());
 
     // replace current scope
     gIR->scope() = IRScope(dowhilebb,endbb);
@@ -311,7 +326,7 @@
     delete cond_e;
 
     // conditional branch
-    llvm::Value* ifbreak = new llvm::BranchInst(dowhilebb, endbb, cond_val, gIR->scopebb());
+    llvm::Value* ifbreak = llvm::BranchInst::Create(dowhilebb, endbb, cond_val, gIR->scopebb());
 
     // rewrite the scope
     gIR->scope() = IRScope(endbb,oldend);
@@ -326,10 +341,10 @@
 
     // create for blocks
     llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* forbb = new llvm::BasicBlock("forcond", gIR->topfunc(), oldend);
-    llvm::BasicBlock* forbodybb = new llvm::BasicBlock("forbody", gIR->topfunc(), oldend);
-    llvm::BasicBlock* forincbb = new llvm::BasicBlock("forinc", gIR->topfunc(), oldend);
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("endfor", gIR->topfunc(), oldend);
+    llvm::BasicBlock* forbb = llvm::BasicBlock::Create("forcond", gIR->topfunc(), oldend);
+    llvm::BasicBlock* forbodybb = llvm::BasicBlock::Create("forbody", gIR->topfunc(), oldend);
+    llvm::BasicBlock* forincbb = llvm::BasicBlock::Create("forinc", gIR->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endfor", gIR->topfunc(), oldend);
 
     // init
     if (init != 0)
@@ -337,7 +352,7 @@
 
     // move into the for condition block, ie. start the loop
     assert(!gIR->scopereturned());
-    new llvm::BranchInst(forbb, gIR->scopebb());
+    llvm::BranchInst::Create(forbb, gIR->scopebb());
 
     p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,forincbb,endbb));
 
@@ -351,7 +366,7 @@
 
     // conditional branch
     assert(!gIR->scopereturned());
-    new llvm::BranchInst(forbodybb, endbb, cond_val, gIR->scopebb());
+    llvm::BranchInst::Create(forbodybb, endbb, cond_val, gIR->scopebb());
 
     // rewrite scope
     gIR->scope() = IRScope(forbodybb,forincbb);
@@ -361,7 +376,7 @@
 
     // move into the for increment block
     if (!gIR->scopereturned())
-        new llvm::BranchInst(forincbb, gIR->scopebb());
+        llvm::BranchInst::Create(forincbb, gIR->scopebb());
     gIR->scope() = IRScope(forincbb, endbb);
 
     // increment
@@ -372,7 +387,7 @@
 
     // loop
     if (!gIR->scopereturned())
-        new llvm::BranchInst(forbb, gIR->scopebb());
+        llvm::BranchInst::Create(forbb, gIR->scopebb());
 
     p->loopbbs.pop_back();
 
@@ -402,7 +417,7 @@
         IRState::LoopScopeVec::reverse_iterator it;
         for(it = gIR->loopbbs.rbegin(); it != gIR->loopbbs.rend(); ++it) {
             if(it->s == targetLoopStatement) {
-                new llvm::BranchInst(it->end, gIR->scopebb());
+                llvm::BranchInst::Create(it->end, gIR->scopebb());
                 return;
             }
         }
@@ -410,7 +425,7 @@
     }
     else {
         emit_finallyblocks(p, enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally);
-        new llvm::BranchInst(gIR->loopbbs.back().end, gIR->scopebb());
+        llvm::BranchInst::Create(gIR->loopbbs.back().end, gIR->scopebb());
     }
 }
 
@@ -436,7 +451,7 @@
         IRState::LoopScopeVec::reverse_iterator it;
         for(it = gIR->loopbbs.rbegin(); it != gIR->loopbbs.rend(); ++it) {
             if(it->s == targetLoopStatement) {
-                new llvm::BranchInst(it->begin, gIR->scopebb());
+                llvm::BranchInst::Create(it->begin, gIR->scopebb());
                 return;
             }
         }
@@ -444,7 +459,7 @@
     }
     else {
         emit_finallyblocks(p, enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally);
-        new llvm::BranchInst(gIR->loopbbs.back().begin, gIR->scopebb());
+        llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb());
     }
 }
 
@@ -469,13 +484,13 @@
     // create basic blocks
     llvm::BasicBlock* oldend = p->scopeend();
 
-    llvm::BasicBlock* trybb = new llvm::BasicBlock("try", p->topfunc(), oldend);
-    llvm::BasicBlock* finallybb = new llvm::BasicBlock("finally", p->topfunc(), oldend);
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("endtryfinally", p->topfunc(), oldend);
+    llvm::BasicBlock* trybb = llvm::BasicBlock::Create("try", p->topfunc(), oldend);
+    llvm::BasicBlock* finallybb = llvm::BasicBlock::Create("finally", p->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endtryfinally", p->topfunc(), oldend);
 
     // pass the previous BB into this
     assert(!gIR->scopereturned());
-    new llvm::BranchInst(trybb, p->scopebb());
+    llvm::BranchInst::Create(trybb, p->scopebb());
 
     // do the try block
     p->scope() = IRScope(trybb,finallybb);
@@ -485,7 +500,7 @@
 
     // terminate try BB
     if (!p->scopereturned())
-        new llvm::BranchInst(finallybb, p->scopebb());
+        llvm::BranchInst::Create(finallybb, p->scopebb());
 
     // do finally block
     p->scope() = IRScope(finallybb,endbb);
@@ -494,7 +509,7 @@
 
     // terminate finally
     if (!gIR->scopereturned()) {
-        new llvm::BranchInst(endbb, p->scopebb());
+        llvm::BranchInst::Create(endbb, p->scopebb());
     }
 
     // rewrite the scope
@@ -513,13 +528,13 @@
     // create basic blocks
     llvm::BasicBlock* oldend = p->scopeend();
 
-    llvm::BasicBlock* trybb = new llvm::BasicBlock("try", p->topfunc(), oldend);
-    llvm::BasicBlock* catchbb = new llvm::BasicBlock("catch", p->topfunc(), oldend);
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("endtrycatch", p->topfunc(), oldend);
+    llvm::BasicBlock* trybb = llvm::BasicBlock::Create("try", p->topfunc(), oldend);
+    llvm::BasicBlock* catchbb = llvm::BasicBlock::Create("catch", p->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endtrycatch", p->topfunc(), oldend);
 
     // pass the previous BB into this
     assert(!gIR->scopereturned());
-    new llvm::BranchInst(trybb, p->scopebb());
+    llvm::BranchInst::Create(trybb, p->scopebb());
 
     // do the try block
     p->scope() = IRScope(trybb,catchbb);
@@ -527,11 +542,11 @@
     body->toIR(p);
 
     if (!gIR->scopereturned())
-        new llvm::BranchInst(endbb, p->scopebb());
+        llvm::BranchInst::Create(endbb, p->scopebb());
 
     // do catch
     p->scope() = IRScope(catchbb,oldend);
-    new llvm::BranchInst(endbb, p->scopebb());
+    llvm::BranchInst::Create(endbb, p->scopebb());
     /*assert(catches);
     for(size_t i=0; i<catches->dim; ++i)
     {
@@ -643,7 +658,7 @@
         CaseStatement* cs = (CaseStatement*)cases->data[i];
 
         std::string lblname("case");
-        llvm::BasicBlock* bb = new llvm::BasicBlock(lblname, p->topfunc(), oldend);
+        llvm::BasicBlock* bb = llvm::BasicBlock::Create(lblname, p->topfunc(), oldend);
         cs->bodyBB = bb;
 
         std::vector<llvm::ConstantInt*> tmp;
@@ -711,12 +726,12 @@
     // default
     llvm::BasicBlock* defbb = 0;
     if (!hasNoDefault) {
-        defbb = new llvm::BasicBlock("default", p->topfunc(), oldend);
+        defbb = llvm::BasicBlock::Create("default", p->topfunc(), oldend);
         sdefault->bodyBB = defbb;
     }
 
     // end (break point)
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("switchend", p->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("switchend", p->topfunc(), oldend);
 
     // condition var
     llvm::Value* condVal;
@@ -729,7 +744,7 @@
     else {
         condVal = call_string_switch_runtime(switchTable, condition);
     }
-    llvm::SwitchInst* si = new llvm::SwitchInst(condVal, defbb ? defbb : endbb, cases->dim, p->scopebb());
+    llvm::SwitchInst* si = llvm::SwitchInst::Create(condVal, defbb ? defbb : endbb, cases->dim, p->scopebb());
 
     // add the cases
     size_t n = vcases.size();
@@ -754,7 +769,7 @@
         llvm::BasicBlock* curbb = p->scopebb();
         if (curbb->empty() || !curbb->back().isTerminator())
         {
-            new llvm::BranchInst(nextbb, curbb);
+            llvm::BranchInst::Create(nextbb, curbb);
         }
     }
 
@@ -770,7 +785,7 @@
         llvm::BasicBlock* curbb = p->scopebb();
         if (curbb->empty() || !curbb->back().isTerminator())
         {
-            new llvm::BranchInst(endbb, curbb);
+            llvm::BranchInst::Create(endbb, curbb);
         }
     }
 
@@ -794,7 +809,7 @@
     LOG_SCOPE;
 
     llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("unrolledend", p->topfunc(), oldend);
+    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));
@@ -807,7 +822,7 @@
 
     p->loopbbs.pop_back();
 
-    new llvm::BranchInst(endbb, p->scopebb());
+    llvm::BranchInst::Create(endbb, p->scopebb());
     p->scope() = IRScope(endbb,oldend);
 }
 
@@ -916,12 +931,12 @@
     }
 
     llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* condbb = new llvm::BasicBlock("foreachcond", p->topfunc(), oldend);
-    llvm::BasicBlock* bodybb = new llvm::BasicBlock("foreachbody", p->topfunc(), oldend);
-    llvm::BasicBlock* nextbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend);
-    llvm::BasicBlock* endbb = new llvm::BasicBlock("foreachend", p->topfunc(), oldend);
+    llvm::BasicBlock* condbb = llvm::BasicBlock::Create("foreachcond", p->topfunc(), oldend);
+    llvm::BasicBlock* bodybb = llvm::BasicBlock::Create("foreachbody", p->topfunc(), oldend);
+    llvm::BasicBlock* nextbb = llvm::BasicBlock::Create("foreachnext", p->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("foreachend", p->topfunc(), oldend);
 
-    new llvm::BranchInst(condbb, p->scopebb());
+    llvm::BranchInst::Create(condbb, p->scopebb());
 
     // condition
     p->scope() = IRScope(condbb,bodybb);
@@ -936,7 +951,7 @@
         load = llvm::BinaryOperator::createSub(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb());
         new llvm::StoreInst(load, keyvar, p->scopebb());
     }
-    new llvm::BranchInst(bodybb, endbb, done, p->scopebb());
+    llvm::BranchInst::Create(bodybb, endbb, done, p->scopebb());
 
     // init body
     p->scope() = IRScope(bodybb,nextbb);
@@ -947,7 +962,7 @@
     if (aggrtype->ty == Tsarray)
         value->ir.irLocal->value = DtoGEP(val,zero,loadedKey,"tmp");
     else if (aggrtype->ty == Tarray)
-        value->ir.irLocal->value = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb());
+        value->ir.irLocal->value = llvm::GetElementPtrInst::Create(val,loadedKey,"tmp",p->scopebb());
 
     if (!value->isRef() && !value->isOut()) {
         DValue* dst = new DVarValue(value->type, valvar, true);
@@ -962,7 +977,7 @@
     p->loopbbs.pop_back();
 
     if (!p->scopereturned())
-        new llvm::BranchInst(nextbb, p->scopebb());
+        llvm::BranchInst::Create(nextbb, p->scopebb());
 
     // next
     p->scope() = IRScope(nextbb,endbb);
@@ -971,7 +986,7 @@
         load = p->ir->CreateAdd(load, llvm::ConstantInt::get(keytype, 1, false), "tmp");
         DtoStore(load, keyvar);
     }
-    new llvm::BranchInst(condbb, p->scopebb());
+    llvm::BranchInst::Create(condbb, p->scopebb());
 
     // end
     p->scope() = IRScope(endbb,oldend);
@@ -990,10 +1005,10 @@
     if (llvmBB)
         llvmBB->moveBefore(oldend);
     else
-        llvmBB = new llvm::BasicBlock("label", p->topfunc(), oldend);
+        llvmBB = llvm::BasicBlock::Create("label", p->topfunc(), oldend);
 
     if (!p->scopereturned())
-        new llvm::BranchInst(llvmBB, p->scopebb());
+        llvm::BranchInst::Create(llvmBB, p->scopebb());
 
     p->scope() = IRScope(llvmBB,oldend);
     if (statement)
@@ -1010,10 +1025,10 @@
     assert(tf == NULL);
 
     llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* bb = new llvm::BasicBlock("aftergoto", p->topfunc(), oldend);
+    llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend);
 
     if (label->statement->llvmBB == NULL)
-        label->statement->llvmBB = new llvm::BasicBlock("label", p->topfunc());
+        label->statement->llvmBB = llvm::BasicBlock::Create("label", p->topfunc());
     assert(!p->scopereturned());
 
     // find finallys between goto and label
@@ -1029,7 +1044,7 @@
     // emit code for finallys between goto and label
     emit_finallyblocks(p, enclosingtryfinally, endfinally);
 
-    new llvm::BranchInst(label->statement->llvmBB, p->scopebb());
+    llvm::BranchInst::Create(label->statement->llvmBB, p->scopebb());
     p->scope() = IRScope(bb,oldend);
 }
 
@@ -1041,14 +1056,14 @@
     LOG_SCOPE;
 
     llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* bb = new llvm::BasicBlock("aftergotodefault", p->topfunc(), oldend);
+    llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotodefault", p->topfunc(), oldend);
 
     assert(!p->scopereturned());
     assert(sw->sdefault->bodyBB);
 
     emit_finallyblocks(p, enclosingtryfinally, sw->enclosingtryfinally);
 
-    new llvm::BranchInst(sw->sdefault->bodyBB, p->scopebb());
+    llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb());
     p->scope() = IRScope(bb,oldend);
 }
 
@@ -1060,14 +1075,14 @@
     LOG_SCOPE;
 
     llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* bb = new llvm::BasicBlock("aftergotocase", p->topfunc(), oldend);
+    llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotocase", p->topfunc(), oldend);
 
     assert(!p->scopereturned());
     assert(cs->bodyBB);
 
     emit_finallyblocks(p, enclosingtryfinally, sw->enclosingtryfinally);
 
-    new llvm::BranchInst(cs->bodyBB, p->scopebb());
+    llvm::BranchInst::Create(cs->bodyBB, p->scopebb());
     p->scope() = IRScope(bb,oldend);
 }
 
@@ -1144,7 +1159,35 @@
 
     Logger::attention(loc, "volatile is currently ignored. only the body will be emitted");
 
-    statement->toIR(p);
+    // mark in volate
+    bool old = gIR->func()->inVolatile;
+    gIR->func()->inVolatile = true;
+
+    // has statement
+    if (statement != NULL)
+    {
+        // load-store
+        DtoMemoryBarrier(false, true, false, false);
+
+        // do statement
+        statement->toIR(p);
+
+        // not point in a unreachable barrier, terminating statements should insert this themselves.
+        if (statement->fallOffEnd())
+        {
+            // store-load
+            DtoMemoryBarrier(false, false, true, false);
+        }
+    }
+    // barrier only
+    else
+    {
+        // load-store & store-load
+        DtoMemoryBarrier(false, true, true, false);
+    }
+
+    // restore volatile state
+    gIR->func()->inVolatile = old;
 }
 
 //////////////////////////////////////////////////////////////////////////////