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