[llvm-branch-commits] [cfe-branch] r114160 - in /cfe/branches/Apple/whitney-IB/src/tools/clang: ./ lib/CodeGen/CGException.cpp lib/CodeGen/CGException.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h

Daniel Dunbar daniel at zuster.org
Thu Sep 16 20:37:15 PDT 2010


Author: ddunbar
Date: Thu Sep 16 22:37:15 2010
New Revision: 114160

URL: http://llvm.org/viewvc/llvm-project?rev=114160&view=rev
Log:
--- Merging r114070 into 'src/tools/clang':
U    src/tools/clang/lib/CodeGen/CGException.cpp
U    src/tools/clang/lib/CodeGen/CodeGenModule.h
U    src/tools/clang/lib/CodeGen/CodeGenModule.cpp
U    src/tools/clang/lib/CodeGen/CGException.h


Modified:
    cfe/branches/Apple/whitney-IB/src/tools/clang/   (props changed)
    cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp
    cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.h
    cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.cpp
    cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.h

Propchange: cfe/branches/Apple/whitney-IB/src/tools/clang/
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Thu Sep 16 22:37:15 2010
@@ -0,0 +1,2 @@
+/cfe/trunk:114070
+/llvm/branches/Apple/Pertwee/tools/clang:110850,110961

Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp?rev=114160&r1=114159&r2=114160&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp Thu Sep 16 22:37:15 2010
@@ -14,6 +14,7 @@
 #include "clang/AST/StmtCXX.h"
 
 #include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
 #include "llvm/Support/CallSite.h"
 
 #include "CGObjCRuntime.h"
@@ -287,7 +288,7 @@
 }
 
 static llvm::Constant *getCatchallRethrowFn(CodeGenFunction &CGF,
-                                            const char *Name) {
+                                            llvm::StringRef Name) {
   const llvm::Type *Int8PtrTy =
     llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
   std::vector<const llvm::Type*> Args(1, Int8PtrTy);
@@ -357,17 +358,95 @@
     return getCPersonality(L);
 }
 
-static llvm::Constant *getPersonalityFn(CodeGenFunction &CGF,
+static llvm::Constant *getPersonalityFn(CodeGenModule &CGM,
                                         const EHPersonality &Personality) {
-  const char *Name = Personality.getPersonalityFnName();
-
   llvm::Constant *Fn =
-    CGF.CGM.CreateRuntimeFunction(llvm::FunctionType::get(
-                                    llvm::Type::getInt32Ty(
-                                      CGF.CGM.getLLVMContext()),
-                                    true),
-                            Name);
-  return llvm::ConstantExpr::getBitCast(Fn, CGF.CGM.PtrToInt8Ty);
+    CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+                                llvm::Type::getInt32Ty(CGM.getLLVMContext()),
+                                true),
+                              Personality.getPersonalityFnName());
+  return Fn;
+}
+
+static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,
+                                        const EHPersonality &Personality) {
+  llvm::Constant *Fn = getPersonalityFn(CGM, Personality);
+  return llvm::ConstantExpr::getBitCast(Fn, CGM.PtrToInt8Ty);
+}
+
+/// Check whether a personality function could reasonably be swapped
+/// for a C++ personality function.
+static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {
+  for (llvm::Constant::use_iterator
+         I = Fn->use_begin(), E = Fn->use_end(); I != E; ++I) {
+    llvm::User *User = *I;
+
+    // Conditionally white-list bitcasts.
+    if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(User)) {
+      if (CE->getOpcode() != llvm::Instruction::BitCast) return false;
+      if (!PersonalityHasOnlyCXXUses(CE))
+        return false;
+      continue;
+    }
+
+    // Otherwise, it has to be a selector call.
+    if (!isa<llvm::EHSelectorInst>(User)) return false;
+
+    llvm::EHSelectorInst *Selector = cast<llvm::EHSelectorInst>(User);
+    for (unsigned I = 2, E = Selector->getNumArgOperands(); I != E; ++I) {
+      // Look for something that would've been returned by the ObjC
+      // runtime's GetEHType() method.
+      llvm::GlobalVariable *GV
+        = dyn_cast<llvm::GlobalVariable>(Selector->getArgOperand(I));
+      if (!GV) continue;
+
+      // ObjC EH selector entries are always global variables with
+      // names starting like this.
+      if (GV->getName().startswith("OBJC_EHTYPE"))
+        return false;
+    }
+  }
+
+  return true;
+}
+
+/// Try to use the C++ personality function in ObjC++.  Not doing this
+/// can cause some incompatibilities with gcc, which is more
+/// aggressive about only using the ObjC++ personality in a function
+/// when it really needs it.
+void CodeGenModule::SimplifyPersonality() {
+  // For now, this is really a Darwin-specific operation.
+  if (Context.Target.getTriple().getOS() != llvm::Triple::Darwin)
+    return;
+
+  // If we're not in ObjC++ -fexceptions, there's nothing to do.
+  if (!Features.CPlusPlus || !Features.ObjC1 || !Features.Exceptions)
+    return;
+
+  const EHPersonality &ObjCXX = EHPersonality::get(Features);
+  const EHPersonality &CXX = getCXXPersonality(Features);
+  if (&ObjCXX == &CXX ||
+      ObjCXX.getPersonalityFnName() == CXX.getPersonalityFnName())
+    return;
+
+  llvm::Function *Fn =
+    getModule().getFunction(ObjCXX.getPersonalityFnName());
+
+  // Nothing to do if it's unused.
+  if (!Fn || Fn->use_empty()) return;
+  
+  // Can't do the optimization if it has non-C++ uses.
+  if (!PersonalityHasOnlyCXXUses(Fn)) return;
+
+  // Create the C++ personality function and kill off the old
+  // function.
+  llvm::Constant *CXXFn = getPersonalityFn(*this, CXX);
+
+  // This can happen if the user is screwing with us.
+  if (Fn->getType() != CXXFn->getType()) return;
+
+  Fn->replaceAllUsesWith(CXXFn);
+  Fn->eraseFromParent();
 }
 
 /// Returns the value to inject into a selector to indicate the
@@ -757,7 +836,7 @@
   // Build the selector arguments.
   llvm::SmallVector<llvm::Value*, 8> EHSelector;
   EHSelector.push_back(Exn);
-  EHSelector.push_back(getPersonalityFn(*this, Personality));
+  EHSelector.push_back(getOpaquePersonalityFn(CGM, Personality));
 
   // Accumulate all the handlers in scope.
   llvm::DenseMap<llvm::Value*, UnwindDest> EHHandlers;
@@ -1502,7 +1581,7 @@
   
   // Tell the backend what the exception table should be:
   // nothing but a catch-all.
-  llvm::Value *Args[3] = { Exn, getPersonalityFn(*this, Personality),
+  llvm::Value *Args[3] = { Exn, getOpaquePersonalityFn(CGM, Personality),
                            getCatchAllValue(*this) };
   Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
                      Args, Args+3, "eh.selector")
@@ -1553,8 +1632,9 @@
 
   // This can always be a call because we necessarily didn't find
   // anything on the EH stack which needs our help.
+  llvm::StringRef RethrowName = Personality.getCatchallRethrowFnName();
   llvm::Constant *RethrowFn;
-  if (const char *RethrowName = Personality.getCatchallRethrowFnName())
+  if (!RethrowName.empty())
     RethrowFn = getCatchallRethrowFn(*this, RethrowName);
   else
     RethrowFn = getUnwindResumeOrRethrowFn();

Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.h?rev=114160&r1=114159&r2=114160&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.h (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.h Thu Sep 16 22:37:15 2010
@@ -29,15 +29,15 @@
 
 /// The exceptions personality for a function.  When 
 class EHPersonality {
-  const char *PersonalityFn;
+  llvm::StringRef PersonalityFn;
 
   // If this is non-null, this personality requires a non-standard
   // function for rethrowing an exception after a catchall cleanup.
   // This function must have prototype void(void*).
-  const char *CatchallRethrowFn;
+  llvm::StringRef CatchallRethrowFn;
 
-  EHPersonality(const char *PersonalityFn,
-                const char *CatchallRethrowFn = 0)
+  EHPersonality(llvm::StringRef PersonalityFn,
+                llvm::StringRef CatchallRethrowFn = llvm::StringRef())
     : PersonalityFn(PersonalityFn),
       CatchallRethrowFn(CatchallRethrowFn) {}
 
@@ -49,8 +49,8 @@
   static const EHPersonality GNU_CPlusPlus;
   static const EHPersonality GNU_CPlusPlus_SJLJ;
 
-  const char *getPersonalityFnName() const { return PersonalityFn; }
-  const char *getCatchallRethrowFnName() const { return CatchallRethrowFn; }
+  llvm::StringRef getPersonalityFnName() const { return PersonalityFn; }
+  llvm::StringRef getCatchallRethrowFnName() const { return CatchallRethrowFn; }
 };
 
 /// A protected scope for zero-cost EH handling.

Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.cpp?rev=114160&r1=114159&r2=114160&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.cpp Thu Sep 16 22:37:15 2010
@@ -110,6 +110,8 @@
   EmitAnnotations();
   EmitLLVMUsed();
 
+  SimplifyPersonality();
+
   if (getCodeGenOpts().EmitDeclMetadata)
     EmitDeclMetadata();
 }

Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.h?rev=114160&r1=114159&r2=114160&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenModule.h Thu Sep 16 22:37:15 2010
@@ -613,6 +613,10 @@
   /// lazily; this is only relevant for definitions. The given decl
   /// must be either a function or var decl.
   bool MayDeferGeneration(const ValueDecl *D);
+
+  /// SimplifyPersonality - Check whether we can use a "simpler", more
+  /// core exceptions personality function.
+  void SimplifyPersonality();
 };
 }  // end namespace CodeGen
 }  // end namespace clang





More information about the llvm-branch-commits mailing list