modimo created this revision.
Herald added subscribers: hoy, wenlei.
Herald added a project: All.
modimo requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152741

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGenCXX/type-metadata-skip-vtable-filepaths.cpp
  clang/test/Driver/fskip-vtable-filepaths.c

Index: clang/test/Driver/fskip-vtable-filepaths.c
===================================================================
--- /dev/null
+++ clang/test/Driver/fskip-vtable-filepaths.c
@@ -0,0 +1,7 @@
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin 2>&1 | FileCheck --check-prefix=NOSKIP %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fwhole-program-vtables -fskip-vtable-filepaths=abc 2>&1 | FileCheck --check-prefix=SKIP %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fskip-vtable-filepaths=abc 2>&1 | FileCheck --check-prefix=ERROR1 %s
+
+// SKIP: "-fskip-vtable-filepaths=abc"
+// NOSKIP-NOT: "-fskip-vtable-filepaths=abc"
+// ERROR1: error: invalid argument '-fskip-vtable-filepaths' only allowed with '-fwhole-program-vtables'
Index: clang/test/CodeGenCXX/type-metadata-skip-vtable-filepaths.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/type-metadata-skip-vtable-filepaths.cpp
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -flto=thin -flto-unit -fwhole-program-vtables -triple x86_64-unknown-linux -fvisibility=hidden -emit-llvm -o - a.cpp | FileCheck %s
+// RUN: %clang_cc1 -flto=thin -flto-unit -fwhole-program-vtables -triple x86_64-unknown-linux -fskip-vtable-filepaths=[^p]$ -fvisibility=hidden -emit-llvm -o - a.cpp | FileCheck %s
+// RUN: %clang_cc1 -flto=thin -flto-unit -fwhole-program-vtables -triple x86_64-unknown-linux -fskip-vtable-filepaths=p$ -fvisibility=hidden -emit-llvm -o - a.cpp | FileCheck -check-prefix=SKIP-PATH %s
+
+// CHECK: !{i64 16, !"_ZTS1A"}
+// SKIP-PATH-NOT: !{i64 16, !"_ZTS1A"}
+//--- a.cpp
+
+struct A {
+  virtual int f() { return 1; }
+};
+
+int f() {
+  auto a = new A();
+  return a->f();
+}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1578,6 +1578,10 @@
   GenerateOptimizationRemark(Args, SA, OPT_Rpass_analysis_EQ, "pass-analysis",
                              Opts.OptimizationRemarkAnalysis);
 
+  if (Opts.SkipVtableFilepaths.hasValidPattern())
+    GenerateArg(Args, OPT_fskip_vtable_file_paths_EQ,
+                Opts.SkipVtableFilepaths.Pattern, SA);
+
   GenerateArg(Args, OPT_fdiagnostics_hotness_threshold_EQ,
               Opts.DiagnosticsHotnessThreshold
                   ? Twine(*Opts.DiagnosticsHotnessThreshold)
@@ -1989,6 +1993,19 @@
                      Opts.OptimizationRemarkMissed.hasValidPattern() ||
                      Opts.OptimizationRemarkAnalysis.hasValidPattern();
 
+  if (Arg *A = Args.getLastArg(OPT_fskip_vtable_file_paths_EQ)) {
+    StringRef Val = A->getValue();
+    std::string RegexError;
+    std::shared_ptr<llvm::Regex> Pattern = std::make_shared<llvm::Regex>(Val);
+    if (!Pattern->isValid(RegexError)) {
+      Diags.Report(diag::err_drv_optimization_remark_pattern)
+          << RegexError << A->getAsString(Args);
+      Pattern.reset();
+    }
+    Opts.SkipVtableFilepaths =
+        CodeGenOptions::RegexWithPattern(std::string(Val), Pattern);
+  }
+
   bool UsingSampleProfile = !Opts.SampleProfileFile.empty();
   bool UsingProfile =
       UsingSampleProfile || !Opts.ProfileInstrumentUsePath.empty();
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -7245,6 +7245,16 @@
   if (SplitLTOUnit)
     CmdArgs.push_back("-fsplit-lto-unit");
 
+  for (const Arg *A : Args.filtered(options::OPT_fskip_vtable_file_paths_EQ)) {
+    if (!WholeProgramVTables)
+      D.Diag(diag::err_drv_argument_only_allowed_with)
+          << "-fskip-vtable-filepaths"
+          << "-fwhole-program-vtables";
+    StringRef Path = A->getValue();
+    CmdArgs.push_back(Args.MakeArgString("-fskip-vtable-filepaths=" + Path));
+    A->claim();
+  }
+
   if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel,
                                options::OPT_fno_global_isel)) {
     CmdArgs.push_back("-mllvm");
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -7067,7 +7067,20 @@
                                           const CXXRecordDecl *RD) {
   llvm::Metadata *MD =
       CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
-  VTable->addTypeMetadata(Offset.getQuantity(), MD);
+
+  bool EmitForType = true;
+  if (CodeGenOpts.SkipVtableFilepaths.hasValidPattern()) {
+    const PresumedLoc &PLoc =
+        Context.getFullLoc(RD->getBeginLoc()).getPresumedLoc(true);
+    assert(PLoc.isValid() && "Source location is expected to be always valid.");
+    std::string FilePath = PLoc.getFilename();
+
+    if (CodeGenOpts.SkipVtableFilepaths.patternMatches(FilePath))
+      EmitForType = false;
+  }
+
+  if (EmitForType)
+    VTable->addTypeMetadata(Offset.getQuantity(), MD);
 
   if (CodeGenOpts.SanitizeCfiCrossDso)
     if (auto CrossDsoTypeId = CreateCrossDsoCfiTypeId(MD))
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -3157,6 +3157,8 @@
   CodeGenOpts<"WholeProgramVTables">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "Enables whole-program vtable optimization. Requires -flto">,
   NegFlag<SetFalse>, BothFlags<[CoreOption]>>;
+def fskip_vtable_file_paths_EQ : Joined<["-"], "fskip-vtable-filepaths=">, Group<f_Group>,
+  HelpText<"Skip types from participating in whole-program vtable optimization defined under these filepaths">, Flags<[CC1Option]>;
 defm split_lto_unit : BoolFOption<"split-lto-unit",
   CodeGenOpts<"EnableSplitLTOUnit">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "Enables splitting of the LTO unit">,
Index: clang/include/clang/Basic/CodeGenOptions.h
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.h
+++ clang/include/clang/Basic/CodeGenOptions.h
@@ -186,6 +186,29 @@
   /// Regexes separated by a semi-colon to filter the files to not instrument.
   std::string ProfileExcludeFiles;
 
+  /// Regular expression with it's original pattern string
+  struct RegexWithPattern {
+    std::string Pattern;
+    std::shared_ptr<llvm::Regex> Regex;
+
+    RegexWithPattern() = default;
+    RegexWithPattern(std::string Pattern, std::shared_ptr<llvm::Regex> Regex)
+        : Pattern(Pattern), Regex(Regex) {}
+
+    /// Returns true iff the optimization remark holds a valid regular
+    /// expression.
+    bool hasValidPattern() const { return Regex != nullptr; }
+
+    /// Matches the given string against the regex, if there is some.
+    bool patternMatches(StringRef String) const {
+      return hasValidPattern() && Regex->match(String);
+    }
+  };
+
+  /// Skip types defined in these paths when performing whole-program vtable
+  /// optimization.
+  RegexWithPattern SkipVtableFilepaths;
+
   /// The version string to put into coverage files.
   char CoverageVersion[4];
 
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -374,6 +374,8 @@
 CODEGENOPT(VirtualFunctionElimination, 1, 0) ///< Whether to apply the dead
                                              /// virtual function elimination
                                              /// optimization.
+CODEGENOPT(EmitVtableTypePaths, 1, 0) ///< Whether to emit filepath of class declarations
+                                      ///  in vtable type metadata.
 
 /// Whether to use public LTO visibility for entities in std and stdext
 /// namespaces. This is enabled by clang-cl's /MT and /MTd flags.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to