changeset 442:76078c8ab5b9

Move DtoArrayBoundsCheck from llvmhelpers to arrays.
author Christian Kamm <kamm incasoftware de>
date Thu, 31 Jul 2008 19:14:49 +0200
parents ca80e42d11e0
children 44f08170f4ef
files gen/arrays.cpp gen/arrays.h gen/llvmhelpers.cpp gen/llvmhelpers.h
diffstat 4 files changed, 80 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/gen/arrays.cpp	Wed Jul 30 20:25:46 2008 +0200
+++ b/gen/arrays.cpp	Thu Jul 31 19:14:49 2008 +0200
@@ -1028,3 +1028,80 @@
 
     return new DImValue(to, rval);
 }
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice)
+{
+    Type* arrty = arr->getType()->toBasetype();
+    assert((arrty->ty == Tsarray || arrty->ty == Tarray) && "Can only array bounds check for static or dynamic arrays");
+
+    // static arrays can get static checks for static indices
+
+    if(arr->getType()->ty == Tsarray)
+    {
+        TypeSArray* tsa = (TypeSArray*)arrty;
+        size_t tdim = tsa->dim->toInteger();
+
+        if(llvm::ConstantInt* cindex = llvm::dyn_cast<llvm::ConstantInt>(index->getRVal()))
+            if(cindex->uge(tdim + (isslice ? 1 : 0))) {
+                size_t cindexval = cindex->getValue().getZExtValue();
+                if(!isslice)
+                    error(loc, "index %u is larger or equal array size %u", cindexval, tdim);
+                else
+                    error(loc, "slice upper bound %u is larger than array size %u", cindexval, tdim);
+                return;
+            }
+    }
+
+    // runtime check
+
+    llvm::BasicBlock* oldend = gIR->scopeend();
+    llvm::BasicBlock* failbb = llvm::BasicBlock::Create("arrayboundscheckfail", gIR->topfunc(), oldend);
+    llvm::BasicBlock* okbb = llvm::BasicBlock::Create("arrayboundsok", gIR->topfunc(), oldend);
+
+    llvm::ICmpInst::Predicate cmpop = isslice ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_ULT;
+    LLValue* cond = gIR->ir->CreateICmp(cmpop, index->getRVal(), DtoArrayLen(arr), "boundscheck");
+    gIR->ir->CreateCondBr(cond, okbb, failbb);
+
+    // set up failbb to call the array bounds error runtime function
+
+    gIR->scope() = IRScope(failbb, okbb);
+
+    std::vector<LLValue*> args;
+    llvm::PAListPtr palist;
+
+    // file param
+    // FIXME: every array bounds check creates a global for the filename !!!
+    LLConstant* c = DtoConstString(loc.filename);
+
+    llvm::AllocaInst* alloc = gIR->func()->srcfileArg;
+    if (!alloc)
+    {
+        alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint());
+        gIR->func()->srcfileArg = alloc;
+    }
+    LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp");
+    DtoStore(c->getOperand(0), ptr);
+    ptr = DtoGEPi(alloc, 0,1, "tmp");
+    DtoStore(c->getOperand(1), ptr);
+
+    args.push_back(alloc);
+    palist = palist.addAttr(1, llvm::ParamAttr::ByVal);
+
+    // line param
+    c = DtoConstUint(loc.linnum);
+    args.push_back(c);
+
+    // call
+    llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_bounds");
+    CallOrInvoke* call = gIR->CreateCallOrInvoke(errorfn, args.begin(), args.end());
+    call->setParamAttrs(palist);
+
+    // the function does not return
+    gIR->ir->CreateUnreachable();
+
+
+    // if ok, proceed in okbb
+    gIR->scope() = IRScope(okbb, oldend);
+}
--- a/gen/arrays.h	Wed Jul 30 20:25:46 2008 +0200
+++ b/gen/arrays.h	Thu Jul 31 19:14:49 2008 +0200
@@ -42,4 +42,7 @@
 
 DValue* DtoCastArray(Loc& loc, DValue* val, Type* to);
 
+// generates an array bounds check
+void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice);
+
 #endif // LLVMC_GEN_ARRAYS_H
--- a/gen/llvmhelpers.cpp	Wed Jul 30 20:25:46 2008 +0200
+++ b/gen/llvmhelpers.cpp	Thu Jul 31 19:14:49 2008 +0200
@@ -153,85 +153,6 @@
     gIR->ir->CreateUnreachable();
 }
 
-/****************************************************************************************/
-/*////////////////////////////////////////////////////////////////////////////////////////
-// ARRAY BOUNDS HELPER
-////////////////////////////////////////////////////////////////////////////////////////*/
-
-void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice)
-{
-    Type* arrty = arr->getType()->toBasetype();
-    assert((arrty->ty == Tsarray || arrty->ty == Tarray) && "Can only array bounds check for static or dynamic arrays");
-
-    // static arrays can get static checks for static indices
-
-    if(arr->getType()->ty == Tsarray)
-    {
-        TypeSArray* tsa = (TypeSArray*)arrty;
-        size_t tdim = tsa->dim->toInteger();
-
-        if(llvm::ConstantInt* cindex = llvm::dyn_cast<llvm::ConstantInt>(index->getRVal()))
-            if(cindex->uge(tdim + (isslice ? 1 : 0))) {
-                size_t cindexval = cindex->getValue().getZExtValue();
-                if(!isslice)
-                    error(loc, "index %u is larger or equal array size %u", cindexval, tdim);
-                else
-                    error(loc, "slice upper bound %u is larger than array size %u", cindexval, tdim);
-                return;
-            }
-    }
-
-    // runtime check
-
-    llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* failbb = llvm::BasicBlock::Create("arrayboundscheckfail", gIR->topfunc(), oldend);
-    llvm::BasicBlock* okbb = llvm::BasicBlock::Create("arrayboundsok", gIR->topfunc(), oldend);
-
-    llvm::ICmpInst::Predicate cmpop = isslice ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_ULT;
-    LLValue* cond = gIR->ir->CreateICmp(cmpop, index->getRVal(), DtoArrayLen(arr), "boundscheck");
-    gIR->ir->CreateCondBr(cond, okbb, failbb);
-
-    // set up failbb to call the array bounds error runtime function
-
-    gIR->scope() = IRScope(failbb, okbb);
-
-    std::vector<LLValue*> args;
-    llvm::PAListPtr palist;
-
-    // file param
-    // FIXME: every array bounds check creates a global for the filename !!!
-    LLConstant* c = DtoConstString(loc.filename);
-
-    llvm::AllocaInst* alloc = gIR->func()->srcfileArg;
-    if (!alloc)
-    {
-        alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint());
-        gIR->func()->srcfileArg = alloc;
-    }
-    LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp");
-    DtoStore(c->getOperand(0), ptr);
-    ptr = DtoGEPi(alloc, 0,1, "tmp");
-    DtoStore(c->getOperand(1), ptr);
-
-    args.push_back(alloc);
-    palist = palist.addAttr(1, llvm::ParamAttr::ByVal);
-
-    // line param
-    c = DtoConstUint(loc.linnum);
-    args.push_back(c);
-
-    // call
-    llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_bounds");
-    CallOrInvoke* call = gIR->CreateCallOrInvoke(errorfn, args.begin(), args.end());
-    call->setParamAttrs(palist);
-
-    // the function does not return
-    gIR->ir->CreateUnreachable();
-
-
-    // if ok, proceed in okbb
-    gIR->scope() = IRScope(okbb, oldend);
-}
 
 /****************************************************************************************/
 /*////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/llvmhelpers.h	Wed Jul 30 20:25:46 2008 +0200
+++ b/gen/llvmhelpers.h	Thu Jul 31 19:14:49 2008 +0200
@@ -13,8 +13,6 @@
 
 // assertion generator
 void DtoAssert(Loc* loc, DValue* msg);
-// array boundary check generator
-void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice);
 
 // return the LabelStatement from the current function with the given identifier or NULL if not found
 LabelStatement* DtoLabelStatement(Identifier* ident);