changeset 144:a27941d00351 trunk

[svn r149] fixed: a bunch of D-style variadics problems. fixed: GotoDefaultStatement implemented. fixed: some other minor bugs.
author lindquist
date Sat, 26 Jan 2008 17:13:22 +0100
parents 336ec4f4bbb3
children 8f704cb9969b
files dmd/statement.c dmd/statement.h gen/arrays.cpp gen/functions.cpp gen/statements.cpp gen/toir.cpp gen/tollvm.cpp llvmdc.kdevelop llvmdc.kdevelop.filelist tango/tango/core/Vararg.d tango/tango/stdc/stdarg.d tango/tango/text/convert/Layout.d
diffstat 12 files changed, 158 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/statement.c	Fri Jan 25 01:42:36 2008 +0100
+++ b/dmd/statement.c	Sat Jan 26 17:13:22 2008 +0100
@@ -1955,6 +1955,8 @@
     sdefault = NULL;
     cases = NULL;
     hasNoDefault = 0;
+    // LLVMDC
+    defaultBB = NULL;
 }
 
 Statement *SwitchStatement::syntaxCopy()
--- a/dmd/statement.h	Fri Jan 25 01:42:36 2008 +0100
+++ b/dmd/statement.h	Sat Jan 26 17:13:22 2008 +0100
@@ -416,6 +416,9 @@
     Statement *inlineScan(InlineScanState *iss);
 
     void toIR(IRState *irs);
+
+    // LLVMDC
+    llvm::BasicBlock* defaultBB;
 };
 
 struct CaseStatement : Statement
--- a/gen/arrays.cpp	Fri Jan 25 01:42:36 2008 +0100
+++ b/gen/arrays.cpp	Sat Jan 26 17:13:22 2008 +0100
@@ -446,6 +446,7 @@
 //////////////////////////////////////////////////////////////////////////////////////////
 void DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src)
 {
+    Logger::cout() << "static array copy: " << *dst << " from " << *src << '\n';
     assert(dst->getType() == src->getType());
     size_t arrsz = getABITypeSize(dst->getType()->getContainedType(0));
     llvm::Value* n = llvm::ConstantInt::get(DtoSize_t(), arrsz, false);
--- a/gen/functions.cpp	Fri Jan 25 01:42:36 2008 +0100
+++ b/gen/functions.cpp	Sat Jan 26 17:13:22 2008 +0100
@@ -321,7 +321,12 @@
     bool declareOnly = false;
     bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent);
     if (!templInst && fdecl->getModule() != gIR->dmodule)
+    {
+        Logger::println("not template instance, and not in this module. declare only!");
+        Logger::println("current module: %s", gIR->dmodule->ident->toChars());
+        Logger::println("func module: %s", fdecl->getModule()->ident->toChars());
         declareOnly = true;
+    }
     else if (fdecl->llvmInternal == LLVMva_start)
         declareOnly = true;
 
@@ -548,11 +553,15 @@
                     }
                     for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
                         VarDeclaration* vd = *i;
+                        Logger::println("referenced nested variable %s", vd->toChars());
                         if (!vd->irLocal)
                             vd->irLocal = new IrLocal(vd);
                         vd->irLocal->nestedIndex = j++;
                         if (vd->isParameter()) {
-                            
+                            if (!vd->irLocal->value) {
+                                assert(vd == fd->vthis);
+                                vd->irLocal->value = fd->irFunc->thisVar;
+                            }
                             assert(vd->irLocal->value);
                             nestTypes.push_back(vd->irLocal->value->getType());
                         }
--- a/gen/statements.cpp	Fri Jan 25 01:42:36 2008 +0100
+++ b/gen/statements.cpp	Sat Jan 26 17:13:22 2008 +0100
@@ -52,13 +52,7 @@
 
     if (exp)
     {
-        Logger::println("return type is: %s", exp->type->toChars());
-
-        Type* exptype = DtoDType(exp->type);
-        TY expty = exptype->ty;
         if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
-            assert(DtoIsPassedByRef(exptype));
-
             IrFunction* f = p->func();
             assert(f->type->llvmRetInPtr);
             assert(f->decl->irFunc->retArg);
@@ -320,6 +314,7 @@
     init->toIR(p);
 
     // move into the for condition block, ie. start the loop
+    assert(!gIR->scopereturned());
     new llvm::BranchInst(forbb, gIR->scopebb());
 
     p->loopbbs.push_back(IRScope(forincbb,endbb));
@@ -333,7 +328,8 @@
     delete cond_e;
 
     // conditional branch
-    llvm::Value* ifbreak = new llvm::BranchInst(forbodybb, endbb, cond_val, forbb);
+    assert(!gIR->scopereturned());
+    new llvm::BranchInst(forbodybb, endbb, cond_val, gIR->scopebb());
 
     // rewrite scope
     gIR->scope() = IRScope(forbodybb,forincbb);
@@ -674,6 +670,7 @@
     llvm::BasicBlock* defbb = 0;
     if (!hasNoDefault) {
         defbb = new llvm::BasicBlock("default", p->topfunc(), oldend);
+        defaultBB = defbb;
     }
 
     // end (break point)
@@ -982,6 +979,22 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+void GotoDefaultStatement::toIR(IRState* p)
+{
+    Logger::println("GotoDefaultStatement::toIR(): %s", loc.toChars());
+    LOG_SCOPE;
+
+    llvm::BasicBlock* oldend = gIR->scopeend();
+    llvm::BasicBlock* bb = new llvm::BasicBlock("aftergotodefault", p->topfunc(), oldend);
+
+    assert(!p->scopereturned());
+    assert(sw->defaultBB);
+    new llvm::BranchInst(sw->defaultBB, p->scopebb());
+    p->scope() = IRScope(bb,oldend);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
 void WithStatement::toIR(IRState* p)
 {
     Logger::println("WithStatement::toIR(): %s", loc.toChars());
@@ -1085,7 +1098,7 @@
 //STUBST(LabelStatement);
 //STUBST(ThrowStatement);
 STUBST(GotoCaseStatement);
-STUBST(GotoDefaultStatement);
+//STUBST(GotoDefaultStatement);
 //STUBST(GotoStatement);
 //STUBST(UnrolledLoopStatement);
 //STUBST(OnScopeStatement);
--- a/gen/toir.cpp	Fri Jan 25 01:42:36 2008 +0100
+++ b/gen/toir.cpp	Sat Jan 26 17:13:22 2008 +0100
@@ -153,19 +153,25 @@
         if (vd->ident == Id::_arguments)
         {
             Logger::println("Id::_arguments");
-            if (!vd->getIrValue())
+            /*if (!vd->getIrValue())
                 vd->getIrValue() = p->func()->decl->irFunc->_arguments;
             assert(vd->getIrValue());
-            return new DVarValue(vd, vd->getIrValue(), true);
+            return new DVarValue(vd, vd->getIrValue(), true);*/
+            llvm::Value* v = p->func()->decl->irFunc->_arguments;
+            assert(v);
+            return new DVarValue(vd, v, true);
         }
         // _argptr
         else if (vd->ident == Id::_argptr)
         {
             Logger::println("Id::_argptr");
-            if (!vd->getIrValue())
+            /*if (!vd->getIrValue())
                 vd->getIrValue() = p->func()->decl->irFunc->_argptr;
             assert(vd->getIrValue());
-            return new DVarValue(vd, vd->getIrValue(), true);
+            return new DVarValue(vd, vd->getIrValue(), true);*/
+            llvm::Value* v = p->func()->decl->irFunc->_argptr;
+            assert(v);
+            return new DVarValue(vd, v, true);
         }
         // _dollar
         else if (vd->ident == Id::dollar)
@@ -1048,9 +1054,14 @@
             std::vector<const llvm::Type*> vtypes;
             std::vector<llvm::Value*> vtypeinfos;
 
+            // number of non variadic args
+            int begin = tf->parameters->dim;
+            Logger::println("num non vararg params = %d", begin);
+
             // build struct with argument types
-            for (int i=0; i<arguments->dim; i++)
+            for (int i=begin; i<arguments->dim; i++)
             {
+                Argument* argu = Argument::getNth(tf->parameters, i);
                 Expression* argexp = (Expression*)arguments->data[i];
                 vtypes.push_back(DtoType(argexp->type));
             }
@@ -1059,30 +1070,30 @@
             llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
 
             // store arguments in the struct
-            for (int i=0; i<arguments->dim; i++)
+            for (int i=begin,k=0; i<arguments->dim; i++,k++)
             {
                 Expression* argexp = (Expression*)arguments->data[i];
                 if (global.params.llvmAnnotate)
                     DtoAnnotation(argexp->toChars());
-                DtoVariadicArgument(argexp, DtoGEPi(mem,0,i,"tmp"));
+                DtoVariadicArgument(argexp, DtoGEPi(mem,0,k,"tmp"));
             }
 
             // build type info array
             assert(Type::typeinfo->irStruct->constInit);
-            const llvm::Type* typeinfotype = getPtrToType(Type::typeinfo->irStruct->constInit->getType());
-            Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n';
+            const llvm::Type* typeinfotype = DtoType(Type::typeinfo->type);
             const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
 
             llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint());
-            for (int i=0; i<arguments->dim; i++)
+            Logger::cout() << "_arguments storage: " << *typeinfomem << '\n';
+            for (int i=begin,k=0; i<arguments->dim; i++,k++)
             {
                 Expression* argexp = (Expression*)arguments->data[i];
                 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration();
                 DtoForceDeclareDsymbol(tidecl);
                 assert(tidecl->getIrValue());
                 vtypeinfos.push_back(tidecl->getIrValue());
-                llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp");
-                p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp"));
+                llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[k], typeinfotype, "tmp");
+                p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,k,"tmp"));
             }
 
             // put data in d-array
@@ -1096,7 +1107,18 @@
             j++;
             llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp");
             j++;
-            llargs.resize(nimplicit+2);
+
+            // pass non variadic args
+            for (int i=0; i<begin; i++)
+            {
+                Argument* fnarg = Argument::getNth(tf->parameters, i);
+                DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
+                llargs[j] = argval->getRVal();
+                j++;
+            }
+
+            // make sure arg vector has the right size
+            llargs.resize(nimplicit+begin+2);
         }
         // normal function
         else {
@@ -1122,20 +1144,23 @@
                     }
                 }
             }
-            Logger::println("%d params passed", n);
-            for (int i=0; i<n; ++i) {
-                assert(llargs[i]);
-                Logger::cout() << *llargs[i] << '\n';
-            }
         }
     }
 
+    #if 1
+    Logger::println("%d params passed", n);
+    for (int i=0; i<llargs.size(); ++i) {
+        assert(llargs[i]);
+        Logger::cout() << "arg["<<i<<"] = " << *llargs[i] << '\n';
+    }
+    #endif
+
     // void returns cannot not be named
     const char* varname = "";
     if (llfnty->getReturnType() != llvm::Type::VoidTy)
         varname = "tmp";
 
-    //Logger::cout() << "Calling: " << *funcval << '\n';
+    Logger::cout() << "Calling: " << *funcval << '\n';
 
     // call the function
     llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb());
@@ -2263,6 +2288,11 @@
         }
         eval = DtoDynArrayIs(op,l,r);
     }
+    else if (t1->isfloating())
+    {
+        llvm::FCmpInst::Predicate pred = (op == TOKidentity) ? llvm::FCmpInst::FCMP_OEQ : llvm::FCmpInst::FCMP_ONE;
+        eval = new llvm::FCmpInst(pred, l, r, "tmp", p->scopebb());
+    }
     else {
         llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
         if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) {
@@ -2283,6 +2313,7 @@
 
     DValue* u = e1->toElem(p);
     DValue* v = e2->toElem(p);
+    assert(e2->type == type);
     return v;
 }
 
@@ -2991,7 +3022,9 @@
 }
 Statement *AsmStatement::syntaxCopy()
 {
-    assert(0);
+    /*error("%s: inline asm is not yet implemented", loc.toChars());
+    fatal();
+    assert(0);*/
     return 0;
 }
 
@@ -3008,7 +3041,9 @@
 
 int AsmStatement::comeFrom()
 {
-    assert(0);
+    /*error("%s: inline asm is not yet implemented", loc.toChars());
+    fatal();
+    assert(0);*/
     return 0;
 }
 
--- a/gen/tollvm.cpp	Fri Jan 25 01:42:36 2008 +0100
+++ b/gen/tollvm.cpp	Sat Jan 26 17:13:22 2008 +0100
@@ -346,13 +346,16 @@
 
 llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc)
 {
+    // turns out we can't really make anything internal with the way D works :(
+    // the things we can need much more info than this can extract.
+    // TODO : remove this useless function
     switch(prot)
     {
     case PROTprivate:
-        if (stc & STCextern)
+        //if (stc & STCextern)
             return llvm::GlobalValue::ExternalLinkage;
-        else
-            return llvm::GlobalValue::InternalLinkage;
+        //else
+        //    return llvm::GlobalValue::InternalLinkage;
 
     case PROTpublic:
     case PROTpackage:
@@ -902,7 +905,12 @@
         }
     }
     else if (t->ty == Tsarray) {
-        DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal());
+        if (DtoType(lhs->getType()) == DtoType(rhs->getType())) {
+            DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal());
+        }
+        else {
+            DtoArrayInit(lhs->getLVal(), rhs->getRVal());
+        }
     }
     else if (t->ty == Tdelegate) {
         if (rhs->isNull())
--- a/llvmdc.kdevelop	Fri Jan 25 01:42:36 2008 +0100
+++ b/llvmdc.kdevelop	Sat Jan 26 17:13:22 2008 +0100
@@ -601,7 +601,7 @@
       </environments>
     </make>
     <general>
-      <activedir>ir</activedir>
+      <activedir>tangotests</activedir>
     </general>
   </kdevcustomproject>
   <cppsupportpart>
--- a/llvmdc.kdevelop.filelist	Fri Jan 25 01:42:36 2008 +0100
+++ b/llvmdc.kdevelop.filelist	Sat Jan 26 17:13:22 2008 +0100
@@ -765,7 +765,9 @@
 tangotests/q.d
 tangotests/r.d
 tangotests/s.d
+tangotests/stdout1.d
 tangotests/t.d
+tangotests/v.d
 test
 test/a.d
 test/aa1.d
--- a/tango/tango/core/Vararg.d	Fri Jan 25 01:42:36 2008 +0100
+++ b/tango/tango/core/Vararg.d	Sat Jan 26 17:13:22 2008 +0100
@@ -15,6 +15,33 @@
 {
     public import std.stdarg;
 }
+else version( LLVMDC )
+{
+    /**
+     * The base vararg list type.
+     */
+    alias void* va_list;
+
+    /**
+     * This function returns the next argument in the sequence referenced by
+     * the supplied argument pointer.  The argument pointer will be adjusted
+     * to point to the next arggument in the sequence.
+     *
+     * Params:
+     *  vp  = The argument pointer.
+     *
+     * Returns:
+     *  The next argument in the sequence.  The result is undefined if vp
+     *  does not point to a valid argument.
+     */
+    T va_arg(T)(ref va_list vp)
+    {
+        size_t size = T.sizeof > size_t.sizeof ? size_t.sizeof : T.sizeof;
+        va_list vptmp = cast(va_list)((cast(size_t)vp + size - 1) &  ~(size - 1));
+        vp = vptmp + T.sizeof;
+        return *cast(T*)vptmp;
+    }
+}
 else
 {
     /**
--- a/tango/tango/stdc/stdarg.d	Fri Jan 25 01:42:36 2008 +0100
+++ b/tango/tango/stdc/stdarg.d	Sat Jan 26 17:13:22 2008 +0100
@@ -13,6 +13,22 @@
 {
     public import std.c.stdarg;
 }
+else version( LLVMDC )
+{
+    alias void* va_list;
+
+    pragma(LLVM_internal, "va_start")
+        void va_start(T)(va_list ap, ref T);
+
+    pragma(LLVM_internal, "va_arg")
+        T va_arg(T)(va_list ap);
+
+    pragma(LLVM_internal, "va_intrinsic", "llvm.va_end")
+        void va_end(va_list args);
+
+    pragma(LLVM_internal, "va_intrinsic", "llvm.va_copy")
+        void va_copy(va_list dst, va_list src);
+}
 else
 {
     alias void* va_list;
--- a/tango/tango/text/convert/Layout.d	Fri Jan 25 01:42:36 2008 +0100
+++ b/tango/tango/text/convert/Layout.d	Sat Jan 26 17:13:22 2008 +0100
@@ -44,6 +44,12 @@
         alias void* Arg;
         alias void* ArgList;
         }
+else version(LLVMDC)
+        {
+        private import tango.core.Vararg;
+        alias void* Arg;
+        alias va_list ArgList;
+        }
      else
         version (X86_64)
                 {
@@ -617,7 +623,7 @@
 
         protected T[] unknown (T[] result, T[] format, TypeInfo type, Arg p)
         {
-                return "{unhandled argument type: " ~ fromUtf8 (type.toString, result) ~ "}";
+                return cast(T[])("{unhandled argument type: " ~ fromUtf8 (type.toString, result) ~ "}");
         }
 
         /**********************************************************************