changeset 1246:6ef97d65ca60

Merge.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Fri, 17 Apr 2009 14:48:37 +0200
parents 465a77c904d4 (current diff) 5f340a6dc749 (diff)
children 2a92c115461d
files
diffstat 3 files changed, 46 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/gen/nested.cpp	Fri Apr 17 14:38:29 2009 +0200
+++ b/gen/nested.cpp	Fri Apr 17 14:48:37 2009 +0200
@@ -5,6 +5,7 @@
 #include "gen/llvmhelpers.h"
 #include "gen/logger.h"
 #include "gen/tollvm.h"
+#include "gen/functions.h"
 
 #include "llvm/Support/CommandLine.h"
 namespace cl = llvm::cl;
@@ -228,42 +229,52 @@
     {
         ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
         if (!cd || !cd->vthis)
-            return getNullPtr(getVoidPtrType());
+            return llvm::UndefValue::get(getVoidPtrType());
         val = DtoLoad(irfunc->thisArg);
         val = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
     }
     else
     {
-        return getNullPtr(getVoidPtrType());
+        return llvm::UndefValue::get(getVoidPtrType());
     }
     if (nestedCtx == NCHybrid) {
-        // If sym is a nested function, and it's parent context is different than the
-        // one we got, adjust it.
-        
-        if (FuncDeclaration* fd = getParentFunc(sym->isFuncDeclaration(), true)) {
-            Logger::println("For nested function, parent is %s", fd->toChars());
-            FuncDeclaration* ctxfd = irfunc->decl;
-            Logger::println("Current function is %s", ctxfd->toChars());
-            if (fromParent) {
-                ctxfd = getParentFunc(ctxfd, true);
-                assert(ctxfd && "Context from outer function, but no outer function?");
-            }
-            Logger::println("Context is from %s", ctxfd->toChars());
+        if (FuncDeclaration* symfd = sym->isFuncDeclaration()) {
+            // Make sure we've had a chance to analyze nested context usage
+            DtoDefineFunction(symfd);
+            
+            // if this is for a function that doesn't access variables from
+            // enclosing scopes, it doesn't matter what we pass.
+            // Tell LLVM about it by passing an 'undef'.
+            if (symfd && symfd->ir.irFunc->depth == -1)
+                return llvm::UndefValue::get(getVoidPtrType());
             
-            unsigned neededDepth = fd->ir.irFunc->depth;
-            unsigned ctxDepth = ctxfd->ir.irFunc->depth;
-            
-            Logger::cout() << "Needed depth: " << neededDepth << '\n';
-            Logger::cout() << "Context depth: " << ctxDepth << '\n';
-            
-            if (neededDepth >= ctxDepth) {
-                assert(neededDepth <= ctxDepth + 1 && "How are we going more than one nesting level up?");
-                // fd needs the same context as we do, so all is well
-                Logger::println("Calling sibling function or directly nested function");
-            } else {
-                val = DtoBitCast(val, LLPointerType::getUnqual(ctxfd->ir.irFunc->frameType));
-                val = DtoGEPi(val, 0, neededDepth);
-                val = DtoAlignedLoad(val, (std::string(".frame.") + fd->toChars()).c_str());
+            // If sym is a nested function, and it's parent context is different than the
+            // one we got, adjust it.
+            if (FuncDeclaration* fd = getParentFunc(symfd, true)) {
+                Logger::println("For nested function, parent is %s", fd->toChars());
+                FuncDeclaration* ctxfd = irfunc->decl;
+                Logger::println("Current function is %s", ctxfd->toChars());
+                if (fromParent) {
+                    ctxfd = getParentFunc(ctxfd, true);
+                    assert(ctxfd && "Context from outer function, but no outer function?");
+                }
+                Logger::println("Context is from %s", ctxfd->toChars());
+                
+                unsigned neededDepth = fd->ir.irFunc->depth;
+                unsigned ctxDepth = ctxfd->ir.irFunc->depth;
+                
+                Logger::cout() << "Needed depth: " << neededDepth << '\n';
+                Logger::cout() << "Context depth: " << ctxDepth << '\n';
+                
+                if (neededDepth >= ctxDepth) {
+                    assert(neededDepth <= ctxDepth + 1 && "How are we going more than one nesting level up?");
+                    // fd needs the same context as we do, so all is well
+                    Logger::println("Calling sibling function or directly nested function");
+                } else {
+                    val = DtoBitCast(val, LLPointerType::getUnqual(ctxfd->ir.irFunc->frameType));
+                    val = DtoGEPi(val, 0, neededDepth);
+                    val = DtoAlignedLoad(val, (std::string(".frame.") + fd->toChars()).c_str());
+                }
             }
         }
     }
@@ -370,15 +381,15 @@
             // start with adding all enclosing parent frames until a static parent is reached
             
             const LLStructType* innerFrameType = NULL;
-            unsigned depth = 0;
+            unsigned depth = -1;
             if (!fd->isStatic()) {
                 if (FuncDeclaration* parfd = getParentFunc(fd, true)) {
                     innerFrameType = parfd->ir.irFunc->frameType;
                     if (innerFrameType)
-                        depth = parfd->ir.irFunc->depth + 1;
+                        depth = parfd->ir.irFunc->depth;
                 }
             }
-            fd->ir.irFunc->depth = depth;
+            fd->ir.irFunc->depth = ++depth;
             
             Logger::cout() << "Function " << fd->toChars() << " has depth " << depth << '\n';
             
--- a/ir/irfunction.cpp	Fri Apr 17 14:38:29 2009 +0200
+++ b/ir/irfunction.cpp	Fri Apr 17 14:48:37 2009 +0200
@@ -112,7 +112,7 @@
 
     nestedVar = NULL;
     frameType = NULL;
-    depth = 0;
+    depth = -1;
     
     _arguments = NULL;
     _argptr = NULL;
--- a/ir/irfunction.h	Fri Apr 17 14:38:29 2009 +0200
+++ b/ir/irfunction.h	Fri Apr 17 14:48:37 2009 +0200
@@ -46,7 +46,9 @@
     
     llvm::Value* nestedVar; // nested var alloca
     const llvm::StructType* frameType; // type of nested context (not for -nested-ctx=array)
-    unsigned depth; // number of enclosing functions with variables accessed by nested functions
+    // number of enclosing functions with variables accessed by nested functions
+    // (-1 if neither this function nor any enclosing ones access variables from enclosing functions)
+    int depth;
     
     llvm::Value* _arguments;
     llvm::Value* _argptr;