[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