Prazek created this revision.
Prazek added reviewers: rsmith, rjmccall, majnemer, nlewycky.
Prazek added a subscriber: cfe-commits.
Keep in mind, that I will not push it untill I will update GVN for using 
!invariant.group metadata

http://reviews.llvm.org/D12312

Files:
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.def
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CGExprCXX.cpp
  lib/Driver/Tools.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGenCXX/virtual-base-ctor.cpp

Index: test/CodeGenCXX/virtual-base-ctor.cpp
===================================================================
--- test/CodeGenCXX/virtual-base-ctor.cpp
+++ test/CodeGenCXX/virtual-base-ctor.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - -O2 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - -O2 -fstrict-vptrs | FileCheck %s
 
 struct B;
 extern B x;
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -493,6 +493,7 @@
   Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
   Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
   Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
+  Opts.StrictVPtrs = Args.hasArg(OPT_fstrict_vptrs);
   Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
                       Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
                       Args.hasArg(OPT_cl_fast_relaxed_math);
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -3368,6 +3368,9 @@
   if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
                    false))
     CmdArgs.push_back("-fstrict-enums");
+  if (Args.hasFlag(options::OPT_fstrict_vptrs, options::OPT_fno_strict_vptrs,
+                   false))
+    CmdArgs.push_back("-fstrict-vptrs");
   if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
                     options::OPT_fno_optimize_sibling_calls))
     CmdArgs.push_back("-mdisable-tail-calls");
Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp
+++ lib/CodeGen/CGExprCXX.cpp
@@ -1354,6 +1354,11 @@
   llvm::Type *elementPtrTy = elementTy->getPointerTo(AS);
   llvm::Value *result = Builder.CreateBitCast(allocation, elementPtrTy);
 
+  // Passing pointer through invariant.group.barrier to avoid propagation of
+  // vptrs information which may be included in previous type.
+  if (CGM.getCodeGenOpts().StrictVPtrs)
+    result = Builder.CreateInvariantGroupBarrier(result);
+
   EmitNewInitializer(*this, E, allocType, elementTy, result, numElements,
                      allocSizeWithoutCookie);
   if (E->isArray()) {
Index: lib/CodeGen/CGClass.cpp
===================================================================
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1253,10 +1253,11 @@
       CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl);
     assert(BaseCtorContinueBB);
   }
-
+  bool BaseVPtrsInitialized = false;
   // Virtual base initializers first.
   for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
     EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
+    BaseVPtrsInitialized = true;
   }
 
   if (BaseCtorContinueBB) {
@@ -1269,8 +1270,14 @@
   for (; B != E && (*B)->isBaseInitializer(); B++) {
     assert(!(*B)->isBaseVirtual());
     EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
+    BaseVPtrsInitialized = true;
   }
 
+  // Pointer to this requires to be passed through invariant.group.barrier
+  // only if we've initilized any base vptrs.
+  if (CGM.getCodeGenOpts().StrictVPtrs && BaseVPtrsInitialized)
+    CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
+
   InitializeVTablePointers(ClassDecl);
 
   // And finally, initialize class members.
@@ -1476,8 +1483,13 @@
     EnterDtorCleanups(Dtor, Dtor_Base);
 
     // Initialize the vtable pointers before entering the body.
-    if (!CanSkipVTablePointerInitialization(getContext(), Dtor))
-        InitializeVTablePointers(Dtor->getParent());
+    if (!CanSkipVTablePointerInitialization(getContext(), Dtor)) {
+      // Inserting llvm.invariant.group.barrier intrinsic before base vptrs
+      // initialization to stop propagating previous vptr value.
+      if (CGM.getCodeGenOpts().StrictVPtrs)
+        CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
+      InitializeVTablePointers(Dtor->getParent());
+    }
 
     if (isTryBody)
       EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def
+++ include/clang/Frontend/CodeGenOptions.def
@@ -132,6 +132,7 @@
 CODEGENOPT(SimplifyLibCalls  , 1, 1) ///< Set when -fbuiltin is enabled.
 CODEGENOPT(SoftFloat         , 1, 0) ///< -soft-float.
 CODEGENOPT(StrictEnums       , 1, 0) ///< Optimize based on strict enum definition.
+CODEGENOPT(StrictVPtrs       , 1, 0) 
 CODEGENOPT(TimePasses        , 1, 0) ///< Set when -ftime-report is enabled.
 CODEGENOPT(UnitAtATime       , 1, 1) ///< Unused. For mirroring GCC optimization
                                      ///< selection.
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -858,6 +858,7 @@
 def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
 def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
 def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
+def fno_strict_vptrs: Flag<["-"], "fno-strict-vptrs">, Group<f_Group>, Flags<[CC1Option]>;
 def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
 def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>,
   Flags<[CC1Option]>, HelpText<"Do not emit code to make initialization of local statics thread safe">;
@@ -986,6 +987,7 @@
 def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable optimizations based on the strict definition of an enum's "
            "value range">;
+def fstrict_vptrs: Flag<["-"], "fstrict-vptrs">, Group<f_Group>, Flags<[CC1Option]>;
 def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
 def fsyntax_only : Flag<["-"], "fsyntax-only">,
   Flags<[DriverOption,CoreOption,CC1Option]>, Group<Action_Group>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to