diff gen/toir.cpp @ 131:5825d48b27d1 trunk

[svn r135] * Merged DMD 1.025 * * Fixed a minor linking order mishap * * Added an command line option -annotate * * Fixed some problems with running optimizations * * Added std.stdio and dependencies to lphobos (still not 100% working, but compiles and links) * * Fixed problems with passing aggregate types to variadic functions * * Added initial code towards full GC support, currently based on malloc and friends, not all the runtime calls the GC yet for memory * * Fixed problems with resolving nested function context pointers for some heavily nested cases * * Redid function argument passing + other minor code cleanups, still lots to do on this end... *
author lindquist
date Fri, 04 Jan 2008 01:38:42 +0100
parents 8096ba7082db
children 1700239cab2e
line wrap: on
line diff
--- a/gen/toir.cpp	Fri Dec 28 23:52:40 2007 +0100
+++ b/gen/toir.cpp	Fri Jan 04 01:38:42 2008 +0100
@@ -31,6 +31,7 @@
 #include "gen/complex.h"
 #include "gen/dvalue.h"
 #include "gen/aa.h"
+#include "gen/functions.h"
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
@@ -51,6 +52,9 @@
         }
         else
         {
+            if (global.params.llvmAnnotate)
+                DtoAnnotation(toChars());
+
             Logger::println("vdtype = %s", vd->type->toChars());
             // referenced by nested delegate?
             if (vd->nestedref) {
@@ -600,7 +604,16 @@
     }
     DtoAssign(l, res);
 
-    return l;
+    // used as lvalue :/
+    if (p->topexp() && p->topexp()->e1 == this)
+    {
+        assert(!l->isLRValue());
+        return l;
+    }
+    else
+    {
+        return res;
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -650,6 +663,7 @@
 
     DValue* res;
     if (DtoDType(e1->type)->ty == Tpointer) {
+        Logger::println("ptr");
         llvm::Value* tmp = r->getRVal();
         llvm::Value* zero = llvm::ConstantInt::get(tmp->getType(),0,false);
         tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb());
@@ -657,9 +671,11 @@
         res = new DImValue(type, tmp);
     }
     else if (t->iscomplex()) {
+        Logger::println("complex");
         res = DtoComplexSub(type, l, r);
     }
     else {
+        Logger::println("basic");
         res = DtoBinSub(l,r);
     }
     DtoAssign(l, res);
@@ -904,7 +920,7 @@
         Logger::cout() << "what are we calling? : " << *funcval << '\n';
     }
     assert(llfnty);
-    Logger::cout() << "Function LLVM type: " << *llfnty << '\n';
+    //Logger::cout() << "Function LLVM type: " << *llfnty << '\n';
 
     // argument handling
     llvm::FunctionType::param_iterator argiter = llfnty->param_begin();
@@ -969,7 +985,7 @@
     // nested call
     else if (dfn && dfn->func && dfn->func->isNested()) {
         Logger::println("Nested Call");
-        llvm::Value* contextptr = p->func()->decl->llvmNested;
+        llvm::Value* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration());
         if (!contextptr)
             contextptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty));
         llargs[j] = DtoBitCast(contextptr, llvm::PointerType::get(llvm::Type::Int8Ty));
@@ -978,7 +994,8 @@
     }
 
     // va arg function special argument passing
-    if (va_magic) {
+    if (va_magic)
+    {
         size_t n = va_intrinsic ? arguments->dim : 1;
         for (int i=0; i<n; i++,j++)
         {
@@ -989,7 +1006,9 @@
         }
     }
     // regular arguments
-    else {
+    else
+    {
+        // d variadic function?
         if (tf->linkage == LINKd && tf->varargs == 1)
         {
             Logger::println("doing d-style variadic arguments");
@@ -997,53 +1016,71 @@
             size_t nimplicit = j;
 
             std::vector<const llvm::Type*> vtypes;
-            std::vector<llvm::Value*> vvalues;
             std::vector<llvm::Value*> vtypeinfos;
 
-            for (int i=0; i<arguments->dim; i++) {
-                Argument* fnarg = Argument::getNth(tf->parameters, i);
+            // build struct with argument types
+            for (int i=0; i<arguments->dim; i++)
+            {
+                Expression* argexp = (Expression*)arguments->data[i];
+                vtypes.push_back(DtoType(argexp->type));
+            }
+            const llvm::StructType* vtype = llvm::StructType::get(vtypes);
+            Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n';
+            llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
+
+            // store arguments in the struct
+            for (int i=0; i<arguments->dim; i++)
+            {
                 Expression* argexp = (Expression*)arguments->data[i];
-                vvalues.push_back(DtoArgument(NULL, fnarg, argexp));
-                vtypes.push_back(vvalues.back()->getType());
-
+                if (global.params.llvmAnnotate)
+                    DtoAnnotation(argexp->toChars());
+                DtoVariadicArgument(argexp, DtoGEPi(mem,0,i,"tmp"));
+            }
+
+            // build type info array
+            assert(Type::typeinfo->llvmConstInit);
+            const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmConstInit->getType());
+            Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n';
+            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++)
+            {
+                Expression* argexp = (Expression*)arguments->data[i];
                 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration();
                 DtoForceDeclareDsymbol(tidecl);
                 assert(tidecl->llvmValue);
                 vtypeinfos.push_back(tidecl->llvmValue);
-            }
-
-            const llvm::StructType* vtype = llvm::StructType::get(vtypes);
-            llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
-            for (unsigned i=0; i<vtype->getNumElements(); ++i)
-                p->ir->CreateStore(vvalues[i], DtoGEPi(mem,0,i,"tmp"));
-
-            //llvm::Constant* typeinfoparam = llvm::ConstantPointerNull::get(isaPointer(llfnty->getParamType(j)));
-            assert(Type::typeinfo->llvmConstInit);
-            const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmConstInit->getType());
-            Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n';
-            const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
-            llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint());
-            for (unsigned i=0; i<vtype->getNumElements(); ++i) {
                 llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp");
                 p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp"));
             }
 
+            // put data in d-array
             llvm::Value* typeinfoarrayparam = new llvm::AllocaInst(llfnty->getParamType(j)->getContainedType(0),"_arguments_array",p->topallocapoint());
             p->ir->CreateStore(DtoConstSize_t(vtype->getNumElements()), DtoGEPi(typeinfoarrayparam,0,0,"tmp"));
             llvm::Value* casttypeinfomem = p->ir->CreateBitCast(typeinfomem, llvm::PointerType::get(typeinfotype), "tmp");
             p->ir->CreateStore(casttypeinfomem, DtoGEPi(typeinfoarrayparam,0,1,"tmp"));
 
+            // specify arguments
             llargs[j] = typeinfoarrayparam;;
             j++;
             llargs[j] = p->ir->CreateBitCast(mem, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp");
             j++;
             llargs.resize(nimplicit+2);
         }
+        // normal function
         else {
             Logger::println("doing normal arguments");
             for (int i=0; i<arguments->dim; i++,j++) {
                 Argument* fnarg = Argument::getNth(tf->parameters, i);
-                llargs[j] = DtoArgument(llfnty->getParamType(j), fnarg, (Expression*)arguments->data[i]);
+                if (global.params.llvmAnnotate)
+                    DtoAnnotation(((Expression*)arguments->data[i])->toChars());
+                DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
+                llargs[j] = argval->getRVal();
+                if (fnarg && llargs[j]->getType() != llfnty->getParamType(j)) {
+                    llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
+                }
+
                 // this hack is necessary :/
                 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
                     if (llfnty->getParamType(j) != NULL) {
@@ -1850,7 +1887,11 @@
             {
                 Expression* ex = (Expression*)arguments->data[i];
                 Argument* fnarg = Argument::getNth(tf->parameters, i);
-                llvm::Value* a = DtoArgument(fn->getFunctionType()->getParamType(i+1), fnarg, ex);
+                DValue* argval = DtoArgument(fnarg, ex);
+                llvm::Value* a = argval->getRVal();
+                const llvm::Type* aty = fn->getFunctionType()->getParamType(i+1);
+                if (a->getType() != aty) // this param might have type mismatch
+                    a = DtoBitCast(a, aty);
                 ctorargs.push_back(a);
             }
             llvm::CallInst* call = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", p->scopebb());
@@ -2895,7 +2936,7 @@
 AsmStatement::AsmStatement(Loc loc, Token *tokens) :
     Statement(loc)
 {
-    Logger::println("Ignoring AsmStatement");
+    this->tokens = tokens;
 }
 Statement *AsmStatement::syntaxCopy()
 {