[llvm-commits] [llvm-gcc-4.2] r106564 - in /llvm-gcc-4.2/trunk/gcc: cp/cp-lang.c langhooks-def.h langhooks.h llvm-backend.cpp llvm-convert.cpp

Bill Wendling isanbard at gmail.com
Tue Jun 22 12:56:08 PDT 2010


Author: void
Date: Tue Jun 22 14:56:07 2010
New Revision: 106564

URL: http://llvm.org/viewvc/llvm-project?rev=106564&view=rev
Log:
A thunk should take the linkage and visibility of the call it's thunking. This
requires us to set the linkage and visibility after all other functions have had
theirs set.

If there is a thunk that points to a thunk, then we need to process the thunk
that calls a non-thunk first and so on until all thunks are processed.

Modified:
    llvm-gcc-4.2/trunk/gcc/cp/cp-lang.c
    llvm-gcc-4.2/trunk/gcc/langhooks-def.h
    llvm-gcc-4.2/trunk/gcc/langhooks.h
    llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Modified: llvm-gcc-4.2/trunk/gcc/cp/cp-lang.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/cp-lang.c?rev=106564&r1=106563&r2=106564&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cp/cp-lang.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cp/cp-lang.c Tue Jun 22 14:56:07 2010
@@ -38,6 +38,8 @@
 static void cp_init_ts (void);
 /* LLVM LOCAL <rdar://problem/7929157> */
 static bool cp_function_thunk_p (tree fndecl);
+/* LLVM LOCAL <rdar://problem/8104369> */
+static tree cp_thunk_target (tree thunk);
 
 /* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h;
    consequently, there should be very few hooks below.  */
@@ -56,6 +58,10 @@
 #undef LANG_HOOKS_FUNCTION_THUNK_P
 #define LANG_HOOKS_FUNCTION_THUNK_P     cp_function_thunk_p
 /* LLVM LOCAL end <rdar://problem/7929157> */
+/* LLVM LOCAL begin <rdar://problem/8104369> */
+#undef LANG_HOOKS_THUNK_TARGET
+#define LANG_HOOKS_THUNK_TARGET         cp_thunk_target
+/* LLVM LOCAL end <rdar://problem/8104369> */
 
 /* Each front end provides its own lang hook initializer.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -152,13 +158,21 @@
 }
 
 /* LLVM LOCAL begin <rdar://problem/7929157> */
-bool
+static bool
 cp_function_thunk_p (tree fndecl)
 {
   return DECL_THUNK_P (fndecl);
 }
 /* LLVM LOCAL end <rdar://problem/7929157> */
 
+/* LLVM LOCAL begin <rdar://problem/8104369> */
+static tree
+cp_thunk_target (tree thunk)
+{
+  return THUNK_TARGET (thunk);
+}
+/* LLVM LOCAL begin <rdar://problem/8104369> */
+
 void
 finish_file (void)
 {

Modified: llvm-gcc-4.2/trunk/gcc/langhooks-def.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/langhooks-def.h?rev=106564&r1=106563&r2=106564&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/langhooks-def.h (original)
+++ llvm-gcc-4.2/trunk/gcc/langhooks-def.h Tue Jun 22 14:56:07 2010
@@ -159,6 +159,9 @@
 /* LLVM LOCAL <rdar://problem/7929157> */
 #define LANG_HOOKS_FUNCTION_THUNK_P     hook_bool_tree_false
 
+/* LLVM LOCAL <rdar://problem/8104369> */
+#define LANG_HOOKS_THUNK_TARGET         lhd_return_null_tree
+
 /* APPLE LOCAL begin radar 6353006  */
 #define LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE \
   lhd_build_generic_block_struct_type
@@ -366,6 +369,8 @@
       LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE,       \
       /* LLVM LOCAL <rdar://problem/7929157> */         \
       LANG_HOOKS_FUNCTION_THUNK_P,                      \
+      /* LLVM LOCAL <rdar://problem/8104369> */         \
+      LANG_HOOKS_THUNK_TARGET,                          \
 }
 
 #endif /* GCC_LANG_HOOKS_DEF_H */

Modified: llvm-gcc-4.2/trunk/gcc/langhooks.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/langhooks.h?rev=106564&r1=106563&r2=106564&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/langhooks.h (original)
+++ llvm-gcc-4.2/trunk/gcc/langhooks.h Tue Jun 22 14:56:07 2010
@@ -490,6 +490,11 @@
   bool (*function_is_thunk_p) (tree fndecl);
   /* LLVM LOCAL end <rdar://problem/7929157> */
 
+  /* LLVM LOCAL begin <rdar://problem/8104369> */
+  /* Returns the target of a thunk.  */
+  tree (*thunk_target) (tree thunk);
+  /* LLVM LOCAL end <rdar://problem/8104369> */
+
   /* Whenever you add entries here, make sure you adjust langhooks-def.h
      and langhooks.c accordingly.  */
 };

Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=106564&r1=106563&r2=106564&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Tue Jun 22 14:56:07 2010
@@ -91,6 +91,9 @@
 TargetFolder *TheFolder = 0;
 TypeConverter *TheTypeConverter = 0;
 
+// A list of thunks to post-process.
+std::vector<tree> Thunks;
+
 /// DisableLLVMOptimizations - Allow the user to specify:
 /// "-mllvm -disable-llvm-optzns" on the llvm-gcc command line to force llvm
 /// optimizations off.
@@ -121,8 +124,8 @@
 // than the LLVM Value pointer while using PCH.
 
 // Collection of LLVM Values
-static std::vector<Value *> LLVMValues;
-typedef DenseMap<Value *, unsigned> LLVMValuesMapTy;
+static std::vector<Value*> LLVMValues;
+typedef DenseMap<Value*, unsigned> LLVMValuesMapTy;
 static LLVMValuesMapTy LLVMValuesMap;
 
 /// LocalLLVMValueIDs - This is the set of local IDs we have in our mapping,
@@ -859,6 +862,47 @@
   timevar_push(TV_LLVM_PERFILE);
   LLVMContext &Context = getGlobalContext();
 
+  // Assign the correct linkage to the thunks now that we've set the linkage and
+  // visibility to their targets.
+  SmallPtrSet<tree, 4> ThunkOfThunk;
+
+  for (std::vector<tree>::iterator
+         I = Thunks.begin(), E = Thunks.end(); I != E; ++I) {
+    tree thunk = *I;
+    tree thunk_target = lang_hooks.thunk_target(thunk);
+
+    if (lang_hooks.function_is_thunk_p (thunk_target)) {
+      ThunkOfThunk.insert(thunk);
+      continue;
+    }
+
+    Function *Thunk = cast<Function>(DECL_LLVM(thunk));
+    const Function *ThunkTarget = cast<Function>(DECL_LLVM(thunk_target));
+
+    Thunk->setLinkage(ThunkTarget->getLinkage());
+    Thunk->setVisibility(ThunkTarget->getVisibility());
+  }
+
+  // There's a situation where a thunk calls another thunk. In that case, we
+  // want to process first the thunk that calls a non-thunk. Then we process
+  // each thunk in turn until all thunks have been processed.
+  while (!ThunkOfThunk.empty())
+    for (SmallPtrSet<tree, 4>::iterator
+           I = ThunkOfThunk.begin(), E = ThunkOfThunk.end(); I != E; ++I) {
+      tree thunk = *I;
+      tree thunk_target = lang_hooks.thunk_target(thunk);
+
+      if (!ThunkOfThunk.count(thunk_target)) {
+        Function *Thunk = cast<Function>(DECL_LLVM(thunk));
+        const Function *ThunkTarget = cast<Function>(DECL_LLVM(thunk_target));
+
+        Thunk->setLinkage(ThunkTarget->getLinkage());
+        Thunk->setVisibility(ThunkTarget->getVisibility());
+        ThunkOfThunk.erase(thunk);
+        break;
+      }
+    }
+
   performLateBackendInitialization();
   createPerFunctionOptimizationPasses();
 

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=106564&r1=106563&r2=106564&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Jun 22 14:56:07 2010
@@ -75,6 +75,8 @@
 
 static LLVMContext &Context = getGlobalContext();
 
+extern std::vector<tree> Thunks;
+
 // Check for GCC bug 17347: C++ FE sometimes creates bogus ctor trees
 // which we should throw out
 #define BOGUS_CTOR(exp)                                                \
@@ -528,34 +530,41 @@
   // The function should not already have a body.
   assert(Fn->empty() && "Function expanded multiple times!");
 
-  // Compute the linkage that the function should get.
-  if (DECL_LLVM_PRIVATE(FnDecl)) {
-    Fn->setLinkage(Function::PrivateLinkage);
-  } else if (DECL_LLVM_LINKER_PRIVATE(FnDecl)) {
-    Fn->setLinkage(Function::LinkerPrivateLinkage);
-  } else if (!TREE_PUBLIC(FnDecl) /*|| lang_hooks.llvm_is_in_anon(subr)*/) {
-    Fn->setLinkage(Function::InternalLinkage);
-  } else if (DECL_EXTERNAL(FnDecl) && 
-             lookup_attribute ("always_inline", DECL_ATTRIBUTES (FnDecl))) {
-    Fn->setLinkage(Function::AvailableExternallyLinkage);
-  } else if (DECL_COMDAT(FnDecl)) {
-    Fn->setLinkage(Function::getLinkOnceLinkage(flag_odr));
-  } else if (DECL_WEAK(FnDecl) && !lang_hooks.function_is_thunk_p (FnDecl)) {
-    // The user may have explicitly asked for weak linkage - ignore flag_odr.
-    Fn->setLinkage(Function::WeakAnyLinkage);
-  } else if (DECL_ONE_ONLY(FnDecl) || lang_hooks.function_is_thunk_p (FnDecl)) {
-    Fn->setLinkage(Function::getWeakLinkage(flag_odr));
-  } else if (IS_EXTERN_INLINE(FnDecl)) {
-    // gcc "extern inline", C99 "inline"
-    Fn->setLinkage(Function::AvailableExternallyLinkage);
-  }
+  if (!lang_hooks.function_is_thunk_p (FnDecl)) {
+    // Compute the linkage that the function should get.
+    if (DECL_LLVM_PRIVATE(FnDecl)) {
+      Fn->setLinkage(Function::PrivateLinkage);
+    } else if (DECL_LLVM_LINKER_PRIVATE(FnDecl)) {
+      Fn->setLinkage(Function::LinkerPrivateLinkage);
+    } else if (!TREE_PUBLIC(FnDecl) /*|| lang_hooks.llvm_is_in_anon(subr)*/) {
+      Fn->setLinkage(Function::InternalLinkage);
+    } else if (DECL_EXTERNAL(FnDecl) && 
+               lookup_attribute ("always_inline", DECL_ATTRIBUTES (FnDecl))) {
+      Fn->setLinkage(Function::AvailableExternallyLinkage);
+    } else if (DECL_COMDAT(FnDecl)) {
+      Fn->setLinkage(Function::getLinkOnceLinkage(flag_odr));
+    } else if (DECL_WEAK(FnDecl)) {
+      // The user may have explicitly asked for weak linkage - ignore flag_odr.
+      Fn->setLinkage(Function::WeakAnyLinkage);
+    } else if (DECL_ONE_ONLY(FnDecl) || lang_hooks.function_is_thunk_p (FnDecl)) {
+      Fn->setLinkage(Function::getWeakLinkage(flag_odr));
+    } else if (IS_EXTERN_INLINE(FnDecl)) {
+      // gcc "extern inline", C99 "inline"
+      Fn->setLinkage(Function::AvailableExternallyLinkage);
+    }
 
 #ifdef TARGET_ADJUST_LLVM_LINKAGE
-  TARGET_ADJUST_LLVM_LINKAGE(Fn,FnDecl);
+    TARGET_ADJUST_LLVM_LINKAGE(Fn, FnDecl);
 #endif /* TARGET_ADJUST_LLVM_LINKAGE */
 
-  // Handle visibility style
-  handleVisibility(FnDecl, Fn);
+    // Handle visibility style.
+    handleVisibility(FnDecl, Fn);
+  } else {
+    // A thunk should get its visibility and linkage from the function being
+    // thunked. Set the information after all functions have been processed
+    // through here.
+    Thunks.push_back(FnDecl);
+  }
 
   // Handle attribute "aligned".
   if (DECL_ALIGN (FnDecl) != FUNCTION_BOUNDARY)





More information about the llvm-commits mailing list