changeset 315:a9697749e898 trunk

[svn r336] Made sure calls within a landing pad area are invokes. Nested trys still need some consideration.
author ChristianK
date Thu, 03 Jul 2008 22:05:45 +0200
parents 8d98e42ece93
children 163cad969791
files gen/aa.cpp gen/arrays.cpp gen/classes.cpp gen/irstate.cpp gen/irstate.h gen/llvmhelpers.cpp gen/statements.cpp gen/toir.cpp gen/tollvm.cpp gen/toobj.cpp
diffstat 10 files changed, 166 insertions(+), 108 deletions(-) [+]
line wrap: on
line diff
--- a/gen/aa.cpp	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/aa.cpp	Thu Jul 03 22:05:45 2008 +0200
@@ -87,7 +87,7 @@
     pkey = DtoBitCast(pkey, funcTy->getParamType(3));
 
     // call runtime
-    LLValue* ret = gIR->ir->CreateCall4(func, aaval, keyti, valsize, pkey, "aa.index");
+    LLValue* ret = gIR->CreateCallOrInvoke4(func, aaval, keyti, valsize, pkey, "aa.index")->get();
 
     // cast return value
     const LLType* targettype = getPtrToType(DtoType(type));
@@ -125,7 +125,7 @@
     pkey = DtoBitCast(pkey, funcTy->getParamType(2));
 
     // call runtime
-    LLValue* ret = gIR->ir->CreateCall3(func, aaval, keyti, pkey, "aa.in");
+    LLValue* ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.in")->get();
 
     // cast return value
     const LLType* targettype = DtoType(type);
@@ -169,5 +169,5 @@
     args.push_back(pkey);
 
     // call runtime
-    gIR->ir->CreateCall(func, args.begin(), args.end(),"");
+    gIR->CreateCallOrInvoke(func, args.begin(), args.end());
 }
--- a/gen/arrays.cpp	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/arrays.cpp	Thu Jul 03 22:05:45 2008 +0200
@@ -232,7 +232,7 @@
     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
     assert(fn);
     Logger::cout() << "calling array init function: " << *fn <<'\n';
-    llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb());
+    CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end());
     call->setCallingConv(llvm::CallingConv::C);
 }
 
@@ -412,7 +412,7 @@
     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
 
     // call allocator
-    LLValue* newptr = gIR->ir->CreateCall2(fn, arrayTypeInfo, arrayLen, ".gc_mem");
+    LLValue* newptr = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem")->get();
 
     // cast to wanted type
     const LLType* dstType = DtoType(arrayType)->getContainedType(1);
@@ -460,7 +460,7 @@
     }
 
     // call allocator
-    LLValue* newptr = gIR->ir->CreateCall3(fn, arrayTypeInfo, DtoConstSize_t(ndims), dimsArg, ".gc_mem");
+    LLValue* newptr = gIR->CreateCallOrInvoke3(fn, arrayTypeInfo, DtoConstSize_t(ndims), dimsArg, ".gc_mem")->get();
 
     // cast to wanted type
     const LLType* dstType = DtoType(arrayType)->getContainedType(1);
@@ -506,7 +506,7 @@
     Logger::cout() << "arrPtr = " << *arrPtr << '\n';
     args.push_back(DtoBitCast(arrPtr, fn->getFunctionType()->getParamType(3), "tmp"));
 
-    LLValue* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem");
+    LLValue* newptr = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".gc_mem")->get();
     if (newptr->getType() != arrPtr->getType())
         newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem");
 
@@ -753,7 +753,7 @@
         args.push_back(DtoBitCast(tival, pt));
     }
 
-    llvm::CallInst* call = gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp");
+    CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), "tmp");
 
     // set param attrs
     llvm::PAListPtr palist;
@@ -761,7 +761,7 @@
     palist = palist.addAttr(2, llvm::ParamAttr::ByVal);
     call->setParamAttrs(palist);
 
-    return call;
+    return call->get();
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -854,7 +854,7 @@
     args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false));
 
     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
-    return llvm::CallInst::Create(fn, args.begin(), args.end(), "tmp", gIR->scopebb());
+    return gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), "tmp")->get();
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/classes.cpp	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/classes.cpp	Thu Jul 03 22:05:45 2008 +0200
@@ -803,14 +803,14 @@
         llvm::Function* fn = newexp->allocator->ir.irFunc->func;
         assert(fn);
         DValue* arg = ((Expression*)newexp->newargs->data[0])->toElem(gIR);
-        mem = gIR->ir->CreateCall(fn, arg->getRVal(), "newclass_custom_alloc");
+        mem = gIR->CreateCallOrInvoke(fn, arg->getRVal(), "newclass_custom_alloc")->get();
         mem = DtoBitCast(mem, DtoType(tc), "newclass_custom");
     }
     // default allocator
     else
     {
         llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass");
-        mem = gIR->ir->CreateCall(fn, tc->sym->ir.irStruct->classInfo, "newclass_gc_alloc");
+        mem = gIR->CreateCallOrInvoke(fn, tc->sym->ir.irStruct->classInfo, "newclass_gc_alloc")->get();
         mem = DtoBitCast(mem, DtoType(tc), "newclass_gc");
     }
 
@@ -914,11 +914,11 @@
         if (fnarg && fnarg->llvmByVal)
             palist = palist.addAttr(i+2, llvm::ParamAttr::ByVal); // return,this is 2
     }
-    llvm::CallInst* call = llvm::CallInst::Create(fn, ctorargs.begin(), ctorargs.end(), "tmp", gIR->scopebb());
+    CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, ctorargs.begin(), ctorargs.end(), "tmp");
     call->setCallingConv(DtoCallingConv(LINKd));
     call->setParamAttrs(palist);
 
-    return new DImValue(type, call, false);
+    return new DImValue(type, call->get(), false);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -931,7 +931,7 @@
     LLSmallVector<LLValue*,1> arg;
     arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
     // call
-    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
+    gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end(), "");
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -1016,7 +1016,7 @@
     assert(funcTy->getParamType(1) == cinfo->getType());
 
     // call it
-    LLValue* ret = gIR->ir->CreateCall2(func, obj, cinfo, "tmp");
+    LLValue* ret = gIR->CreateCallOrInvoke2(func, obj, cinfo, "tmp")->get();
 
     // cast return value
     ret = DtoBitCast(ret, DtoType(_to));
@@ -1039,7 +1039,7 @@
     tmp = DtoBitCast(tmp, funcTy->getParamType(0));
 
     // call it
-    LLValue* ret = gIR->ir->CreateCall(func, tmp, "tmp");
+    LLValue* ret = gIR->CreateCallOrInvoke(func, tmp, "tmp")->get();
 
     // cast return value
     if (to != NULL)
@@ -1079,7 +1079,7 @@
     cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
 
     // call it
-    LLValue* ret = gIR->ir->CreateCall2(func, ptr, cinfo, "tmp");
+    LLValue* ret = gIR->CreateCallOrInvoke2(func, ptr, cinfo, "tmp")->get();
 
     // cast return value
     ret = DtoBitCast(ret, DtoType(_to));
@@ -1369,7 +1369,7 @@
         DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
         DtoForceDeclareDsymbol(d);
         assert(d->ir.irFunc->func);
-        builder.CreateCall(d->ir.irFunc->func, thisptr);
+        gIR->CreateCallOrInvoke(d->ir.irFunc->func, thisptr);
     }
     builder.CreateRetVoid();
 
--- a/gen/irstate.cpp	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/irstate.cpp	Thu Jul 03 22:05:45 2008 +0200
@@ -123,6 +123,47 @@
     return !scopebb()->empty() && scopebb()->back().isTerminator();
 }
 
+CallOrInvoke* IRState::CreateCallOrInvoke(LLValue* Callee, const char* Name)
+{
+    LLSmallVector<LLValue*, 1> args;
+    return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
+}
+
+CallOrInvoke* IRState::CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name)
+{
+    LLSmallVector<LLValue*, 1> args;
+    args.push_back(Arg1);
+    return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
+}
+
+CallOrInvoke* IRState::CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name)
+{
+    LLSmallVector<LLValue*, 2> args;
+    args.push_back(Arg1);
+    args.push_back(Arg2);
+    return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
+}
+
+CallOrInvoke* IRState::CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name)
+{
+    LLSmallVector<LLValue*, 3> args;
+    args.push_back(Arg1);
+    args.push_back(Arg2);
+    args.push_back(Arg3);
+    return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
+}
+
+CallOrInvoke* IRState::CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2,  LLValue* Arg3, LLValue* Arg4, const char* Name)
+{
+    LLSmallVector<LLValue*, 4> args;
+    args.push_back(Arg1);
+    args.push_back(Arg2);
+    args.push_back(Arg3);
+    args.push_back(Arg4);
+    return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name);
+}
+
+
 //////////////////////////////////////////////////////////////////////////////////////////
 
 IRBuilder* IRBuilderHelper::operator->()
--- a/gen/irstate.h	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/irstate.h	Thu Jul 03 22:05:45 2008 +0200
@@ -89,6 +89,42 @@
     std::vector<Identifier*> internalLabels;
 };
 
+// llvm::CallInst and llvm::InvokeInst don't share a common base
+// but share common functionality. to avoid duplicating code for
+// adjusting these common properties these structs are made
+struct CallOrInvoke
+{
+    virtual void setParamAttrs(const llvm::PAListPtr& Attrs) = 0;
+    virtual void setCallingConv(unsigned CC) = 0;
+    virtual llvm::Instruction* get() = 0;
+};
+
+struct CallOrInvoke_Call : public CallOrInvoke
+{
+    llvm::CallInst* inst;
+    CallOrInvoke_Call(llvm::CallInst* call) : inst(call) {}
+
+    virtual void setParamAttrs(const llvm::PAListPtr& Attrs)
+    { inst->setParamAttrs(Attrs); }
+    virtual void setCallingConv(unsigned CC)
+    { inst->setCallingConv(CC); }
+    virtual llvm::Instruction* get()
+    { return inst; }
+};
+
+struct CallOrInvoke_Invoke : public CallOrInvoke
+{
+    llvm::InvokeInst* inst;
+    CallOrInvoke_Invoke(llvm::InvokeInst* invoke) : inst(invoke) {}
+
+    virtual void setParamAttrs(const llvm::PAListPtr& Attrs)
+    { inst->setParamAttrs(Attrs); }
+    virtual void setCallingConv(unsigned CC)
+    { inst->setCallingConv(CC); }
+    virtual llvm::Instruction* get()
+    { return inst; }
+};
+
 // represents the module
 struct IRState
 {
@@ -140,6 +176,16 @@
     typedef std::vector<llvm::BasicBlock*> BBVec;
     BBVec landingPads;
 
+    // create a call or invoke, depending on the landing pad info
+    // the template function is defined further down in this file
+    template <typename InputIterator>
+    CallOrInvoke* CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke(LLValue* Callee, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2,  LLValue* Arg3, LLValue* Arg4, const char* Name="");
+
     // loop blocks
     typedef std::vector<IRLoopScope> LoopScopeVec;
     LoopScopeVec loopbbs;
@@ -180,4 +226,18 @@
     LLGlobalVariable* dwarfGVs;
 };
 
+template <typename InputIterator>
+CallOrInvoke* IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name)
+{
+    if(landingPads.empty())
+        return new CallOrInvoke_Call(ir->CreateCall(Callee, ArgBegin, ArgEnd, Name));
+    else
+    {
+        llvm::BasicBlock* postinvoke = llvm::BasicBlock::Create("postinvoke", topfunc(), scopeend());
+        llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, *landingPads.rbegin(), ArgBegin, ArgEnd, Name);
+        scope() = IRScope(postinvoke, scopeend());
+        return new CallOrInvoke_Invoke(invoke);
+    }
+}
+
 #endif // LLVMDC_GEN_IRSTATE_H
--- a/gen/llvmhelpers.cpp	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/llvmhelpers.cpp	Thu Jul 03 22:05:45 2008 +0200
@@ -30,7 +30,7 @@
     LLConstant* ti = DtoTypeInfoOf(newtype);
     assert(isaPointer(ti));
     // call runtime allocator
-    LLValue* mem = gIR->ir->CreateCall(fn, ti, ".gc_mem");
+    LLValue* mem = gIR->CreateCallOrInvoke(fn, ti, ".gc_mem")->get();
     // cast
     return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem");
 }
@@ -43,7 +43,7 @@
     LLSmallVector<LLValue*,1> arg;
     arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp"));
     // call
-    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
+    gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
 }
 
 void DtoDeleteClass(LLValue* inst)
@@ -54,7 +54,7 @@
     LLSmallVector<LLValue*,1> arg;
     arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
     // call
-    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
+    gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
 }
 
 void DtoDeleteInterface(LLValue* inst)
@@ -65,7 +65,7 @@
     LLSmallVector<LLValue*,1> arg;
     arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
     // call
-    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
+    gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
 }
 
 void DtoDeleteArray(DValue* arr)
@@ -77,7 +77,7 @@
     arg.push_back(DtoArrayLen(arr));
     arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp"));
     // call
-    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
+    gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
 }
 
 /****************************************************************************************/
@@ -143,7 +143,7 @@
     args.push_back(c);
 
     // call
-    llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb());
+    CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end());
     call->setParamAttrs(palist);
 
     // after assert is always unreachable
@@ -275,27 +275,27 @@
 void DtoEnterCritical(LLValue* g)
 {
     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_criticalenter");
-    gIR->ir->CreateCall(fn, g, "");
+    gIR->CreateCallOrInvoke(fn, g);
 }
 
 void DtoLeaveCritical(LLValue* g)
 {
     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_criticalexit");
-    gIR->ir->CreateCall(fn, g, "");
+    gIR->CreateCallOrInvoke(fn, g);
 }
 
 void DtoEnterMonitor(LLValue* v)
 {
     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_monitorenter");
     v = DtoBitCast(v, fn->getFunctionType()->getParamType(0));
-    gIR->ir->CreateCall(fn, v, "");
+    gIR->CreateCallOrInvoke(fn, v);
 }
 
 void DtoLeaveMonitor(LLValue* v)
 {
     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_monitorexit");
     v = DtoBitCast(v, fn->getFunctionType()->getParamType(0));
-    gIR->ir->CreateCall(fn, v, "");
+    gIR->CreateCallOrInvoke(fn, v);
 }
 
 /****************************************************************************************/
--- a/gen/statements.cpp	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/statements.cpp	Thu Jul 03 22:05:45 2008 +0200
@@ -713,7 +713,7 @@
     //Logger::cout() << "calling: " << *fn << '\n';
     LLValue* arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0));
     //Logger::cout() << "arg: " << *arg << '\n';
-    gIR->ir->CreateCall(fn, arg, "");
+    gIR->CreateCallOrInvoke(fn, arg);
     gIR->ir->CreateUnreachable();
 
     // need a block after the throw for now
@@ -781,14 +781,14 @@
     }
     assert(llval->getType() == fn->getFunctionType()->getParamType(1));
 
-    llvm::CallInst* call = gIR->ir->CreateCall2(fn, table, llval, "tmp");
+    CallOrInvoke* call = gIR->CreateCallOrInvoke2(fn, table, llval, "tmp");
 
     llvm::PAListPtr palist;
     palist = palist.addAttr(1, llvm::ParamAttr::ByVal);
     palist = palist.addAttr(2, llvm::ParamAttr::ByVal);
     call->setParamAttrs(palist);
 
-    return call;
+    return call->get();
 }
 
 void SwitchStatement::toIR(IRState* p)
--- a/gen/toir.cpp	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/toir.cpp	Thu Jul 03 22:05:45 2008 +0200
@@ -1246,81 +1246,38 @@
     //Logger::cout() << "Calling: " << *funcval << '\n';
 
     // call the function
-    LLValue* retllval;
-    if(p->landingPads.empty())
-    {
-        llvm::CallInst* call = llvm::CallInst::Create(funcval, llargs.begin(), llargs.end(), varname, p->scopebb());
-
-        retllval = (retinptr) ? llargs[0] : call;
-
-        if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) {
-            const LLType* rettype = getPtrToType(DtoType(type));
-            if (retllval->getType() != rettype) {
-                Logger::println("llvmRunTimeHack==true - force casting return value");
-                Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n';
-                retllval = DtoBitCast(retllval, rettype);
-            }
+    CallOrInvoke* call = gIR->CreateCallOrInvoke(funcval, llargs.begin(), llargs.end(), varname);
+
+    LLValue* retllval = (retinptr) ? llargs[0] : call->get();
+
+    if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) {
+        const LLType* rettype = getPtrToType(DtoType(type));
+        if (retllval->getType() != rettype) {
+            Logger::println("llvmRunTimeHack==true - force casting return value");
+            Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n';
+            retllval = DtoBitCast(retllval, rettype);
         }
-
-        // set calling convention
-        if (dfn && dfn->func) {
-            int li = dfn->func->llvmInternal;
-            if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic) {
-                call->setCallingConv(DtoCallingConv(dlink));
-            }
-        }
-        /*else if (delegateCall) {
-            call->setCallingConv(DtoCallingConv(dlink));
-        }*/
-        else if (dfn && dfn->cc != (unsigned)-1) {
-            call->setCallingConv(dfn->cc);
-        }
-        else {
+    }
+
+    // set calling convention
+    if (dfn && dfn->func) {
+        int li = dfn->func->llvmInternal;
+        if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic) {
             call->setCallingConv(DtoCallingConv(dlink));
         }
-
-        // param attrs
-        call->setParamAttrs(palist);
     }
-    else
-    {
-        llvm::BasicBlock* postinvoke = llvm::BasicBlock::Create("postinvoke", p->topfunc(), p->scopeend());
-        llvm::InvokeInst* call = llvm::InvokeInst::Create(funcval, postinvoke, *p->landingPads.rbegin(), llargs.begin(), llargs.end(), varname, p->scopebb());
-        p->scope() = IRScope(postinvoke, p->scopeend());
-
-
-        //FIXME: Code duplication!
-        retllval = (retinptr) ? llargs[0] : call;
-
-        if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) {
-            const LLType* rettype = getPtrToType(DtoType(type));
-            if (retllval->getType() != rettype) {
-                Logger::println("llvmRunTimeHack==true - force casting return value");
-                Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n';
-                retllval = DtoBitCast(retllval, rettype);
-            }
-        }
-
-        // set calling convention
-        if (dfn && dfn->func) {
-            int li = dfn->func->llvmInternal;
-            if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic) {
-                call->setCallingConv(DtoCallingConv(dlink));
-            }
-        }
-        /*else if (delegateCall) {
-            call->setCallingConv(DtoCallingConv(dlink));
-        }*/
-        else if (dfn && dfn->cc != (unsigned)-1) {
-            call->setCallingConv(dfn->cc);
-        }
-        else {
-            call->setCallingConv(DtoCallingConv(dlink));
-        }
-
-        // param attrs
-        call->setParamAttrs(palist);
+    /*else if (delegateCall) {
+        call->setCallingConv(DtoCallingConv(dlink));
+    }*/
+    else if (dfn && dfn->cc != (unsigned)-1) {
+        call->setCallingConv(dfn->cc);
     }
+    else {
+        call->setCallingConv(DtoCallingConv(dlink));
+    }
+
+    // param attrs
+    call->setParamAttrs(palist);
 
     return new DImValue(type, retllval, isInPlace);
 }
--- a/gen/tollvm.cpp	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/tollvm.cpp	Thu Jul 03 22:05:45 2008 +0200
@@ -410,7 +410,7 @@
     else
         fn = GET_INTRINSIC_DECL(memset_i32);
 
-    gIR->ir->CreateCall4(fn, dst, DtoConstUbyte(0), nbytes, DtoConstUint(0), "");
+    gIR->CreateCallOrInvoke4(fn, dst, DtoConstUbyte(0), nbytes, DtoConstUint(0));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -426,7 +426,7 @@
     else
         fn = GET_INTRINSIC_DECL(memcpy_i32);
 
-    gIR->ir->CreateCall4(fn, dst, src, nbytes, DtoConstUint(0), "");
+    gIR->CreateCallOrInvoke4(fn, dst, src, nbytes, DtoConstUint(0));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -459,7 +459,7 @@
     llargs.push_back(DtoConstBool(ss));
     llargs.push_back(DtoConstBool(device));
 
-    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
+    gIR->CreateCallOrInvoke(fn, llargs.begin(), llargs.end());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/toobj.cpp	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/toobj.cpp	Thu Jul 03 22:05:45 2008 +0200
@@ -220,7 +220,7 @@
 
     for (size_t i=0; i<n; i++) {
         llvm::Function* f = gIR->ctors[i]->ir.irFunc->func;
-        llvm::CallInst* call = builder.CreateCall(f,"");
+        CallOrInvoke* call = gIR->CreateCallOrInvoke(f);
         call->setCallingConv(llvm::CallingConv::Fast);
     }
 
@@ -254,7 +254,7 @@
 
     for (size_t i=0; i<n; i++) {
         llvm::Function* f = gIR->dtors[i]->ir.irFunc->func;
-        llvm::CallInst* call = builder.CreateCall(f,"");
+        CallOrInvoke* call = gIR->CreateCallOrInvoke(f);
         call->setCallingConv(llvm::CallingConv::Fast);
     }
 
@@ -288,7 +288,7 @@
 
     for (size_t i=0; i<n; i++) {
         llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func;
-        llvm::CallInst* call = builder.CreateCall(f,"");
+        CallOrInvoke* call = gIR->CreateCallOrInvoke(f);
         call->setCallingConv(llvm::CallingConv::Fast);
     }