diff gen/tollvm.cpp @ 1482:d9c5f5a43403

Run `semantic3` on imported modules, and emit new symbols with `available_externally` linkage. This allows the inliner to inline functions from other modules while telling the code generator to ignore those functions (treat them as declarations) Still generates a few extra `TypeInfo`s and strings... Disabled when generating debug info because I don't really understand it, and it doesn't like this.
author Frits van Bommel <fvbommel wxs.nl>
date Sun, 07 Jun 2009 16:00:13 +0200
parents b3ba2c6ff038
children 8b9f236dd051
line wrap: on
line diff
--- a/gen/tollvm.cpp	Sun Jun 07 15:07:29 2009 +0200
+++ b/gen/tollvm.cpp	Sun Jun 07 16:00:13 2009 +0200
@@ -241,6 +241,13 @@
     // global variable
     if (VarDeclaration* vd = sym->isVarDeclaration())
     {
+        if (mustDefineSymbol(vd))
+            Logger::println("Variable %savailable externally: %s", (vd->availableExternally ? "" : "not "), vd->toChars());
+#if LLVM_REV >= 68940
+        // generated by inlining semantics run
+        if (vd->availableExternally && mustDefineSymbol(sym))
+            return llvm::GlobalValue::AvailableExternallyLinkage;
+#endif
         // template
         if (needsTemplateLinkage(sym))
             return TEMPLATE_LINKAGE_TYPE;
@@ -248,15 +255,22 @@
     // function
     else if (FuncDeclaration* fdecl = sym->isFuncDeclaration())
     {
+        if (mustDefineSymbol(fdecl))
+            Logger::println("Function %savailable externally: %s", (fdecl->availableExternally ? "" : "not "), fdecl->toChars());
         assert(fdecl->type->ty == Tfunction);
         TypeFunction* ft = (TypeFunction*)fdecl->type;
 
+        // intrinsics are always external
+        if (fdecl->llvmInternal == LLVMintrinsic)
+            return llvm::GlobalValue::ExternalLinkage;
+#if LLVM_REV >= 68940
+        // generated by inlining semantics run
+        if (fdecl->availableExternally && mustDefineSymbol(sym))
+            return llvm::GlobalValue::AvailableExternallyLinkage;
+#endif
         // array operations are always template linkage
         if (fdecl->isArrayOp)
             return TEMPLATE_LINKAGE_TYPE;
-        // intrinsics are always external
-        if (fdecl->llvmInternal == LLVMintrinsic)
-            return llvm::GlobalValue::ExternalLinkage;
         // template instances should have weak linkage
         // but only if there's a body, and it's not naked
         // otherwise we make it external
@@ -269,6 +283,13 @@
     // class
     else if (ClassDeclaration* cd = sym->isClassDeclaration())
     {
+        if (mustDefineSymbol(cd))
+            Logger::println("Class %savailable externally: %s", (cd->availableExternally ? "" : "not "), vd->toChars());
+#if LLVM_REV >= 68940
+        // generated by inlining semantics run
+        if (cd->availableExternally && mustDefineSymbol(sym))
+            return llvm::GlobalValue::AvailableExternallyLinkage;
+#endif
         // template
         if (needsTemplateLinkage(cd))
             return TEMPLATE_LINKAGE_TYPE;
@@ -278,8 +299,8 @@
         assert(0 && "not global/function");
     }
     
-    // The following breaks for nested naked functions, so check for that.
-    bool skipNestedCheck = false;
+    // The following breaks for nested naked functions and other declarations, so check for that.
+    bool skipNestedCheck = !mustDefineSymbol(sym);
     if (FuncDeclaration* fd = sym->isFuncDeclaration())
         skipNestedCheck = (fd->naked != 0);
     
@@ -306,16 +327,36 @@
     return llvm::GlobalValue::ExternalLinkage;
 }
 
+static bool isAvailableExternally(Dsymbol* sym)
+{
+    if (VarDeclaration* vd = sym->isVarDeclaration())
+        return vd->availableExternally;
+    if (FuncDeclaration* fd = sym->isFuncDeclaration())
+        return fd->availableExternally;
+    if (AggregateDeclaration* ad = sym->isAggregateDeclaration())
+        return ad->availableExternally;
+    return false;
+}
+
 llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym)
 {
-    if (needsTemplateLinkage(sym))
+    if (needsTemplateLinkage(sym)) {
+#if LLVM_REV >= 68940
+        if (isAvailableExternally(sym) && mustDefineSymbol(sym))
+            return llvm::GlobalValue::AvailableExternallyLinkage;
+#endif
         return TEMPLATE_LINKAGE_TYPE;
+    }
     else
         return llvm::GlobalValue::InternalLinkage;
 }
 
 llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym)
 {
+#if LLVM_REV >= 68940
+    if (isAvailableExternally(sym) && mustDefineSymbol(sym))
+        return llvm::GlobalValue::AvailableExternallyLinkage;
+#endif
     if (needsTemplateLinkage(sym))
         return TEMPLATE_LINKAGE_TYPE;
     else