summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjasonliu <jasonliu.development@gmail.com>2020-02-11 09:52:56 +0000
committerjasonliu <jasonliu.development@gmail.com>2020-02-12 09:56:18 +0000
commit55e2678fcd4d7eca3f9a602a919da499c1103041 (patch)
treeb0123eaff54b9b56849327e2382d391fe1dd821e
parentfa74b31a3e9cd844c7ce2087978568e3f5ec8519 (diff)
[clang] Add -fignore-exceptions
Summary: This is trying to implement the functionality proposed in: http://lists.llvm.org/pipermail/cfe-dev/2017-April/053417.html An exception can throw, but no cleanup is going to happen. A module compiled with exceptions on, can catch the exception throws from module compiled with -fignore-exceptions. The use cases for enabling this option are: 1. Performance analysis of EH instrumentation overhead 2. The ability to QA non EH functionality when EH functionality is not available. 3. User of EH enabled headers knows the calls won't throw in their program and wants the performance gain from ignoring EH construct. The implementation tried to accomplish that by removing any landing pad code that might get generated. Reviewed by: aaron.ballman Differential Revision: https://reviews.llvm.org/D72644
-rw-r--r--clang/include/clang/Basic/LangOptions.def1
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--clang/lib/CodeGen/CGException.cpp12
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp5
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp1
-rw-r--r--clang/test/CodeGen/ignore-exceptions.cpp25
6 files changed, 41 insertions, 5 deletions
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 4c7f7dde1f7d..3cc7c384ac10 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -132,6 +132,7 @@ LANGOPT(DWARFExceptions , 1, 0, "dwarf exception handling")
LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling")
LANGOPT(SEHExceptions , 1, 0, "SEH .xdata exception handling")
LANGOPT(WasmExceptions , 1, 0, "WebAssembly exception handling")
+LANGOPT(IgnoreExceptions , 1, 0, "ignore exceptions")
LANGOPT(ExternCNoUnwind , 1, 0, "Assume extern C functions don't unwind")
LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation")
LANGOPT(RTTI , 1, 1, "run-time type information")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 5987e735c77a..b0e9d9590fde 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -932,6 +932,8 @@ def fseh_exceptions : Flag<["-"], "fseh-exceptions">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Use SEH style exceptions">;
def fwasm_exceptions : Flag<["-"], "fwasm-exceptions">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Use WebAssembly style exceptions">;
+def fignore_exceptions : Flag<["-"], "fignore-exceptions">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Enable support for ignoring exception handling constructs">;
def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">,
Group<clang_ignored_gcc_optimization_f_Group>;
def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index fffd9897270e..a542c3d85a84 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -703,12 +703,12 @@ llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {
assert(EHStack.requiresLandingPad());
assert(!EHStack.empty());
- // If exceptions are disabled and SEH is not in use, then there is no invoke
- // destination. SEH "works" even if exceptions are off. In practice, this
- // means that C++ destructors and other EH cleanups don't run, which is
+ // If exceptions are disabled/ignored and SEH is not in use, then there is no
+ // invoke destination. SEH "works" even if exceptions are off. In practice,
+ // this means that C++ destructors and other EH cleanups don't run, which is
// consistent with MSVC's behavior.
const LangOptions &LO = CGM.getLangOpts();
- if (!LO.Exceptions) {
+ if (!LO.Exceptions || LO.IgnoreExceptions) {
if (!LO.Borland && !LO.MicrosoftExt)
return nullptr;
if (!currentFunctionUsesSEHTry())
@@ -751,7 +751,9 @@ llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {
llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
assert(EHStack.requiresLandingPad());
-
+ assert(!CGM.getLangOpts().IgnoreExceptions &&
+ "LandingPad should not be emitted when -fignore-exceptions are in "
+ "effect.");
EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());
switch (innermostEHScope.getKind()) {
case EHScope::Terminate:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 7901f8a48f5f..4424d8e6f72c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -463,6 +463,11 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType,
}
}
+ // OPT_fignore_exceptions means exception could still be thrown,
+ // but no clean up or catch would happen in current module.
+ // So we do not set EH to false.
+ Args.AddLastArg(CmdArgs, options::OPT_fignore_exceptions);
+
if (EH)
CmdArgs.push_back("-fexceptions");
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index dca80562b445..2a7ec58b2141 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2773,6 +2773,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
if (Args.hasArg(OPT_fno_threadsafe_statics))
Opts.ThreadsafeStatics = 0;
Opts.Exceptions = Args.hasArg(OPT_fexceptions);
+ Opts.IgnoreExceptions = Args.hasArg(OPT_fignore_exceptions);
Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
diff --git a/clang/test/CodeGen/ignore-exceptions.cpp b/clang/test/CodeGen/ignore-exceptions.cpp
new file mode 100644
index 000000000000..c2770005cb73
--- /dev/null
+++ b/clang/test/CodeGen/ignore-exceptions.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -triple powerpc64-linux -fexceptions -fcxx-exceptions -fignore-exceptions -emit-llvm -o - | FileCheck %s
+
+struct A {
+ ~A(){}
+};
+
+void f(void) {
+// CHECK-NOT: personality i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*)
+ A a;
+ try {
+ throw 1;
+ } catch(...) {
+ }
+// CHECK: %a = alloca %struct.A, align 1
+// CHECK: %exception = call i8* @__cxa_allocate_exception(i64 4) #1
+// CHECK: %0 = bitcast i8* %exception to i32*
+// CHECK: store i32 1, i32* %0, align 16
+// CHECK: call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2
+// CHECK: unreachable
+
+// CHECK-NOT: invoke
+// CHECK-NOT: landingpad
+// CHECK-NOT: __cxa_begin_catch
+// CHECK-NOT: __cxa_end_catch
+}