Prazek updated this revision to Diff 147673.
Prazek added a comment.
remove empty line
Repository:
rL LLVM
https://reviews.llvm.org/D47108
Files:
clang/docs/ClangCommandLineReference.rst
clang/docs/ReleaseNotes.rst
clang/docs/UsersManual.rst
clang/include/clang/Driver/Options.td
clang/include/clang/Frontend/CodeGenOptions.def
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/test/CodeGenCXX/vtable-available-externally.cpp
Index: clang/test/CodeGenCXX/vtable-available-externally.cpp
===================================================================
--- clang/test/CodeGenCXX/vtable-available-externally.cpp
+++ clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables
// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
// RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
@@ -13,10 +14,13 @@
// RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
// RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
// RUN: FileCheck --check-prefix=CHECK-TEST17 %s < %t.opt
+// RUN: FileCheck --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
+
#include <typeinfo>
// CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
namespace Test1 {
struct A {
@@ -213,14 +217,16 @@
// because A's key function is defined here, vtable is generated in this TU
// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
struct A {
virtual void foo();
virtual void bar();
};
void A::foo() {}
// Because key function is inline we will generate vtable as linkonce_odr.
// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
struct D : A {
void bar();
};
@@ -237,14 +243,17 @@
// can't guarantee that we will be able to refer to bar from name
// so (at the moment) we can't emit vtable available_externally.
// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
struct C : A {
void bar() {} // defined in body - not key function
virtual inline void gar(); // inline in body - not key function
virtual void car();
};
// no key function, vtable will be generated everywhere it will be used
// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+
struct E : A {};
void g(A& a) {
@@ -298,11 +307,13 @@
namespace Test12 {
// CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
struct A {
virtual void foo();
virtual ~A() {}
};
// CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
struct B : A {
void foo();
};
@@ -319,6 +330,9 @@
// CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
// CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
+
struct A {
virtual ~A();
};
@@ -371,6 +385,8 @@
// generate available_externally vtable for it.
// CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
// CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
struct S {
__attribute__((visibility("hidden"))) virtual void doStuff();
@@ -395,6 +411,10 @@
// This test checks if we emit vtables opportunistically.
// CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
// CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD1Ev(
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(
struct A {
virtual void key();
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -719,6 +719,7 @@
Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
Opts.StrictReturn = !Args.hasArg(OPT_fno_strict_return);
Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers);
+ Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables);
Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
Args.hasArg(OPT_cl_fast_relaxed_math);
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -3472,6 +3472,10 @@
options::OPT_fno_strict_vtable_pointers,
false))
CmdArgs.push_back("-fstrict-vtable-pointers");
+ if (Args.hasFlag(options::OPT_fforce_emit_vtables,
+ options::OPT_fno_force_emit_vtables,
+ false))
+ CmdArgs.push_back("-fforce-emit-vtable");
if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
options::OPT_fno_optimize_sibling_calls))
CmdArgs.push_back("-mdisable-tail-calls");
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1706,11 +1706,19 @@
if (CGM.getLangOpts().AppleKext)
return false;
- // If we don't have any not emitted inline virtual function, and if vtable is
- // not hidden, then we are safe to emit available_externally copy of vtable.
+ // If vtable is hidden then it is not safe to emit available_externally
+ // copy of vtable.
+ if (isVTableHidden(RD))
+ return false;
+
+ if (CGM.getCodeGenOpts().ForceEmitVTables)
+ return true;
+
+ // If we don't have any not emitted inline virtual function then we are safe
+ // to emit available_externally copy of vtable.
// FIXME we can still emit a copy of the vtable if we
// can emit definition of the inline functions.
- return !hasAnyUnusedVirtualInlineFunction(RD) && !isVTableHidden(RD);
+ return !hasAnyUnusedVirtualInlineFunction(RD);
}
static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF,
Address InitialPtr,
Index: clang/include/clang/Frontend/CodeGenOptions.def
===================================================================
--- clang/include/clang/Frontend/CodeGenOptions.def
+++ clang/include/clang/Frontend/CodeGenOptions.def
@@ -332,6 +332,10 @@
/// Whether to embed source in DWARF debug line section.
CODEGENOPT(EmbedSource, 1, 0)
+/// Whether to emit all vtables
+CODEGENOPT(ForceEmitVTables, 1, 0)
+
+
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
#undef VALUE_CODEGENOPT
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1669,6 +1669,11 @@
HelpText<"Enables whole-program vtable optimization. Requires -flto">;
def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>,
Flags<[CoreOption]>;
+def fforce_emit_vtables : Flag<["-"], "fforce-emit-vtables">, Group<f_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Emits more virtual tables to improve devirtualization">;
+def fno_force_emit_vtables : Flag<["-"], "fno-force-emit-vtables">, Group<f_Group>,
+ Flags<[CoreOption]>;
def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Treat signed integer overflow as two's complement">;
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>,
Index: clang/docs/UsersManual.rst
===================================================================
--- clang/docs/UsersManual.rst
+++ clang/docs/UsersManual.rst
@@ -1269,6 +1269,12 @@
devirtualization and virtual constant propagation, for classes with
:doc:`hidden LTO visibility <LTOVisibility>`. Requires ``-flto``.
+.. option:: -fforce-emit-vtables
+
+ In order to improve devirtualization, forces emitting of vtables even in
+ modules where it isn't necessary. It causes more inline virtual functions
+ to be emitted.
+
.. option:: -fno-assume-sane-operator-new
Don't assume that the C++'s new operator is sane.
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -112,6 +112,12 @@
'no-strict' option, Clang attempts to match the overflowing behavior of the
target's native float-to-int conversion instructions.
+- :option: `-fforce-emit-vtables` and `-fno-force-emit-vtables`.
+
+ In order to improve devirtualization, forces emitting of vtables even in
+ modules where it isn't necessary. It causes more inline virtual functions
+ to be emitted.
+
- ...
Deprecated Compiler Flags
Index: clang/docs/ClangCommandLineReference.rst
===================================================================
--- clang/docs/ClangCommandLineReference.rst
+++ clang/docs/ClangCommandLineReference.rst
@@ -1934,6 +1934,12 @@
Enables whole-program vtable optimization. Requires -flto
+.. option:: -fforce-emit-vtables, -fno-force-emit-vtables
+
+In order to improve devirtualization, forces emitting of vtables even in
+modules where it isn't necessary. It causes more inline virtual functions
+to be emitted.
+
.. option:: -fwrapv, -fno-wrapv
Treat signed integer overflow as two's complement
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits