https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/228729
>From 952926c5958234e2e5a86c0f103a35047a2e1e44 Mon Sep 17 00:00:00 2001 From: Fangrui Song <[email protected]> Date: Sat, 3 Oct 2026 08:05:12 -0700 Subject: [PATCH] [CodeGen] Declare command line options in TableGen Move the cl::opts of TargetPassConfig.cpp and CodeGenPrepare.cpp into CodeGenOptions.td, private to lib/CodeGen; other files will follow. -enable-machine-outliner (cl::ValueOptional) and -regalloc (RegisterPassParser) stay cl::opt. CodeGenPrepare and its addressing-mode helpers hold `const CodeGenOptions &Opts`; TargetPassConfig functions read CodeGenOptions::Global. getCGPassBuilderOption() converts BoolOrDefault members to the cl::boolOrDefault and std::optional<bool> fields of the public CGPassBuilderOption. -basic-block-section-match-infer, which was not cl::Hidden, is now listed by -help-hidden only. Aided by Opus 5.5 --- llvm/lib/CodeGen/CMakeLists.txt | 8 + llvm/lib/CodeGen/CodeGenOptions.cpp | 15 + llvm/lib/CodeGen/CodeGenOptions.h | 19 + llvm/lib/CodeGen/CodeGenOptions.td | 199 ++++++++ llvm/lib/CodeGen/CodeGenPrepare.cpp | 316 ++++-------- llvm/lib/CodeGen/RegisterUsageInfo.cpp | 7 +- llvm/lib/CodeGen/TargetPassConfig.cpp | 462 ++++++------------ .../gn/secondary/llvm/lib/CodeGen/BUILD.gn | 10 + .../llvm-project-overlay/llvm/BUILD.bazel | 11 + 9 files changed, 504 insertions(+), 543 deletions(-) create mode 100644 llvm/lib/CodeGen/CodeGenOptions.cpp create mode 100644 llvm/lib/CodeGen/CodeGenOptions.h create mode 100644 llvm/lib/CodeGen/CodeGenOptions.td diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index 7db7c1ca932437..211ce644a4162d 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -33,6 +33,11 @@ elseif (DEFINED LLVM_HAVE_TF_AOT OR LLVM_HAVE_TFLITE) endif() endif() +set(LLVM_TABLEGEN_PROJECT LLVM_HEADERS) +set(LLVM_TARGET_DEFINITIONS CodeGenOptions.td) +tablegen(LLVM CodeGenOptions.inc -gen-opt-parser-defs) +add_public_tablegen_target(CodeGenOptionsTableGen) + add_llvm_component_library(LLVMCodeGen AggressiveAntiDepBreaker.cpp AllocationOrder.cpp @@ -54,6 +59,7 @@ add_llvm_component_library(LLVMCodeGen CFIInstrInserter.cpp CodeGen.cpp CodeGenCommonISel.cpp + CodeGenOptions.cpp CodeGenPrepare.cpp CommandFlags.cpp ComplexDeinterleavingPass.cpp @@ -284,6 +290,7 @@ add_llvm_component_library(LLVMCodeGen LINK_LIBS ${LLVM_PTHREAD_LIB} ${MLLinkDeps} DEPENDS + CodeGenOptionsTableGen intrinsics_gen vt_gen ${MLDeps} @@ -297,6 +304,7 @@ add_llvm_component_library(LLVMCodeGen Core MC ObjCARC + Option ProfileData Scalar Support diff --git a/llvm/lib/CodeGen/CodeGenOptions.cpp b/llvm/lib/CodeGen/CodeGenOptions.cpp new file mode 100644 index 00000000000000..31cb2dafa020b2 --- /dev/null +++ b/llvm/lib/CodeGen/CodeGenOptions.cpp @@ -0,0 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CodeGenOptions.h" +#include "llvm/Option/LibraryOptions.h" + +#define OPTIONS_STRUCT_DEFS +#include "CodeGenOptions.inc" + +static llvm::opt::RegisterLibraryOptions<llvm::CodeGenOptions> Registration; diff --git a/llvm/lib/CodeGen/CodeGenOptions.h b/llvm/lib/CodeGen/CodeGenOptions.h new file mode 100644 index 00000000000000..657850dcbe5dff --- /dev/null +++ b/llvm/lib/CodeGen/CodeGenOptions.h @@ -0,0 +1,19 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_CODEGEN_CODEGENOPTIONS_H +#define LLVM_LIB_CODEGEN_CODEGENOPTIONS_H + +#include "llvm/Target/TargetOptions.h" +#include <cstdint> +#include <optional> + +#define OPTIONS_STRUCT_DECL +#include "CodeGenOptions.inc" + +#endif // LLVM_LIB_CODEGEN_CODEGENOPTIONS_H diff --git a/llvm/lib/CodeGen/CodeGenOptions.td b/llvm/lib/CodeGen/CodeGenOptions.td new file mode 100644 index 00000000000000..7e57091aec67df --- /dev/null +++ b/llvm/lib/CodeGen/CodeGenOptions.td @@ -0,0 +1,199 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +include "llvm/Option/LibraryOptions.td" + +def CodeGenOptions : OptionsStruct; + +defm : BoolField<"basic-block-section-match-infer", "false", + "Enable matching and inference when generating basic block sections">; +defm : BoolField<"bbsections-guided-section-prefix", "true", + "Use the basic-block-sections profile to determine the text section prefix for hot functions. " + "Functions with basic-block-sections profile will be placed in `.text.hot` regardless of their FDO profile info. " + "Other functions won't be impacted, i.e., their prefixes will be decided by FDO/sampleFDO profiles">; +defm : BoolField<"cgp-addr-sink-combine-base-gv", "true", + "Allow combining of BaseGV field in Address sinking">; +defm : BoolField<"cgp-addr-sink-combine-base-offs", "true", + "Allow combining of BaseOffs field in Address sinking">; +defm : BoolField<"cgp-addr-sink-combine-base-reg", "true", + "Allow combining of BaseReg field in Address sinking">; +defm : BoolField<"cgp-addr-sink-combine-scaled-reg", "true", + "Allow combining of ScaledReg field in Address sinking">; +defm : BoolField<"cgp-addr-sink-new-phis", "false", + "Allow creation of Phis in Address sinking">; +defm : BoolField<"cgp-addr-sink-new-select", "true", + "Allow creation of selects in Address sinking">; +defm : OptionalBoolField<"cgp-addr-sink-using-gep", + "Address sinking in CGP using GEPs">; +defm : BoolField<"cgp-andcmp-sinking", "true", + "Enable sinking and/cmp into branches">; +defm : BoolField<"cgp-branch-opts", "true", + "Enable branch optimizations in CodeGenPrepare">; +defm : BoolField<"cgp-complex-addr-modes", "true", + "Enable combining addressing modes with different parts in optimizeMemoryInst">; +defm : BoolField<"cgp-delete-phis", "true", + "Enable elimination of dead PHI nodes">; +defm : BoolField<"cgp-ext-ld-promotion", "true", + "Enable ext(promotable(ld)) -> promoted(ext(ld)) optimization in CodeGenPrepare">; +defm : BoolField<"cgp-force-split-store", "false", + "Force store splitting no matter what the target query says">; +defm : ValueField<"cgp-freq-ratio-to-skip-merge", "uint64_t", "2", + "Skip merging empty blocks if (frequency of empty block) / (frequency of destination block) is greater than this ratio">; +defm : BoolField<"cgp-gc-opts", "true", + "Enable GC optimizations in CodeGenPrepare">; +defm : ValueField<"cgp-huge-func", "unsigned", "10000", + "Least BB number of huge function">; +defm : BoolField<"cgp-icmp-eq2icmp-st", "false", + "Enable ICMP_EQ to ICMP_S(L|G)T conversion">; +defm : ValueField<"cgp-max-address-users-to-scan", "unsigned", "100", + "Max number of address users to look at">; +defm : BoolField<"cgp-optimize-phi-types", "true", + "Enable converting phi types in CodeGenPrepare">; +defm : BoolField<"cgp-preheader-prot", "true", + "Protect loop preheaders from removal">; +defm : BoolField<"cgp-select2branch", "true", + "Enable select to branch conversion">; +defm : BoolField<"cgp-split-large-offset-gep", "true", + "Enable splitting large offset of GEP">; +defm : BoolField<"cgp-store-extract", "true", + "Enable store(extract) optimizations in CodeGenPrepare">; +defm : BoolField<"cgp-stress-ext-ld-promotion", "false", + "Stress test ext(promotable(ld)) -> promoted(ext(ld)) optimization in CodeGenPrepare">; +defm : BoolField<"cgp-stress-store-extract", "false", + "Stress test store(extract) optimizations in CodeGenPrepare">; +defm : BoolField<"cgp-type-promotion-merge", "true", + "Enable merging of redundant sexts when one is dominating the other">; +defm : BoolField<"cgp-verify-bfi-updates", "false", + "Enable BFI update verification for CodeGenPrepare">; +defm : BoolField<"codegen-pipeline-trigger-crash", "false", + "Trigger crash in codegen pipeline">; +defm : OptionalBoolField<"debugify-and-strip-all-safe", + "Debugify MIR before and Strip debug after each pass except those known to be unsafe when debug info is present">; +defm : OptionalBoolField<"debugify-check-and-strip-all-safe", + "Debugify MIR before, by checking and stripping the debug info after, each pass except those known to be unsafe when debug info is present">; +defm : BoolField<"disable-atexit-based-global-dtor-lowering", "false", + "For MachO, disable atexit()-based global destructor lowering">; +defm : BoolField<"disable-block-placement", "false", + "Disable probability-driven block placement">; +defm : BoolField<"disable-branch-fold", "false", + "Disable branch folding">; +// Disable the pass to fix unwind information. Whether the pass is included in +// the pipeline is controlled via the target options, this option serves as +// manual override. +defm : BoolField<"disable-cfi-fixup", "false", + "Disable the CFI fixup pass">; +defm : BoolField<"disable-cgp", "false", + "Disable Codegen Prepare">; +defm : BoolField<"disable-constant-hoisting", "false", + "Disable ConstantHoisting">; +defm : BoolField<"disable-copyprop", "false", + "Disable Copy Propagation pass">; +defm : BoolField<"disable-early-ifcvt", "false", + "Disable Early If-conversion">; +defm : BoolField<"disable-early-taildup", "false", + "Disable pre-register allocation tail duplication">; +defm : BoolField<"disable-expand-reductions", "false", + "Disable the expand reduction intrinsics pass from running">; +// Disable MIRProfileLoader before BlockPlacement. This is for debugging and +// tuning purposes. +defm : BoolField<"disable-layout-fsprofile-loader", "false", + "Disable MIRProfileLoader before BlockPlacement">; +defm : BoolField<"disable-lsr", "false", + "Disable Loop Strength Reduction Pass">; +defm : BoolField<"disable-machine-cse", "false", + "Disable Machine Common Subexpression Elimination">; +defm : BoolField<"disable-machine-dce", "false", + "Disable Machine Dead Code Elimination">; +defm : BoolField<"disable-machine-licm", "false", + "Disable Machine LICM">; +defm : BoolField<"disable-machine-sink", "false", + "Disable Machine Sinking">; +defm : BoolField<"disable-partial-libcall-inlining", "false", + "Disable Partial Libcall Inlining">; +defm : BoolField<"disable-post-ra", "false", + "Disable Post Regalloc Scheduler">; +defm : BoolField<"disable-postra-machine-licm", "false", + "Disable Machine LICM">; +defm : BoolField<"disable-postra-machine-sink", "false", + "Disable PostRA Machine Sinking">; +// Disable MIRProfileLoader before RegAlloc. This is for debugging and tuning +// purpose. +defm : BoolField<"disable-ra-fsprofile-loader", "false", + "Disable MIRProfileLoader before RegAlloc">; +defm : BoolField<"disable-replace-with-vec-lib", "false", + "Disable replace with vector math call pass">; +defm : BoolField<"disable-select-optimize", "true", + "Disable the select-optimization pass from running">; +defm : BoolField<"disable-ssc", "false", + "Disable Stack Slot Coloring">; +defm : BoolField<"disable-tail-duplicate", "false", + "Disable tail duplication">; +defm : BoolField<"enable-block-placement-stats", "false", + "Collect probability-driven block placement stats">; +defm : BoolField<"enable-gc-empty-basic-blocks", "false", + "Enable garbage-collecting empty basic blocks">; +defm : BoolField<"enable-global-merge-func", "false", + "Enable global merge functions that are based on hash function">; +defm : BoolField<"enable-implicit-null-checks", "false", + "Fold null checks into faulting memory operations">; +defm : OptionalBoolField<"enable-ipra", + "Enable interprocedural register allocation to reduce load/store at procedure calls">; +defm : BoolField<"enable-split-machine-functions", "false", + "Split out cold blocks from machine functions based on profile information">; +// -fast-isel selects FastISel at any optimization level, and -fast-isel=0 +// disables it at -O0, where it is used unless GlobalISel is enabled. +defm : OptionalBoolField<"fast-isel", + "Enable the \"fast\" instruction selector">; +let MetaVarName = "<filename>" in +defm : ValueField<"fs-profile-file", "StringRef", "", + "Flow Sensitive profile file name">; +let MetaVarName = "<filename>" in +defm : ValueField<"fs-remapping-file", "StringRef", "", + "Flow Sensitive profile remapping file name">; +defm : OptionalBoolField<"global-isel", + "Enable the \"global\" instruction selector">; +defm : EnumField<"global-isel-abort", "std::optional<GlobalISelAbortMode>", "std::nullopt", + "0,1,2", ["GlobalISelAbortMode::Disable", "GlobalISelAbortMode::Enable", + "GlobalISelAbortMode::DisableWithDiag"], + "Enable abort calls when \"global\" instruction selection fails to lower/select an instruction">; +// Temporary option to allow experimenting with MachineScheduler as a post-RA +// scheduler. Targets can "properly" enable this with +// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID). +// Targets can return true in targetSchedulesPostRAScheduling() and +// insert a PostRA scheduling pass wherever it wants. +defm : BoolField<"misched-postra", "false", + "Run MachineScheduler post regalloc (independent of preRA sched)">; +// FIXME: remove this after switching to NPM or GlobalISel, whichever gets there +// first... +defm : BoolField<"print-after-isel", "false", + "Print machine instrs after ISel">; +defm : BoolField<"print-isel-input", "false", + "Print LLVM IR input to isel pass">; +defm : BoolField<"print-regusage", "false", + "Print register usage details collected for IPRA">; +defm : BoolField<"profile-guided-section-prefix", "true", + "Use profile info to add section prefix for hot/cold functions">; +defm : BoolField<"profile-unknown-in-special-section", "false", + "In profiling mode like sampleFDO, if a function doesn't have profile, we cannot tell the function is cold for sure because it may be a function newly added without ever being sampled. " + "With the flag enabled, compiler can put such profile unknown functions into a special section, so runtime system can choose to handle it in a different way than .text section, to save RAM for example">; +defm : BoolField<"split-static-data", "false", + "Split static data sections into hot and cold sections using profile information">; +let MetaVarName = "<pass-name>" in +defm : ValueField<"start-after", "StringRef", "", + "Resume compilation after a specific pass">; +let MetaVarName = "<pass-name>" in +defm : ValueField<"start-before", "StringRef", "", + "Resume compilation before a specific pass">; +let MetaVarName = "<pass-name>" in +defm : ValueField<"stop-after", "StringRef", "", + "Stop compilation after a specific pass">; +let MetaVarName = "<pass-name>" in +defm : ValueField<"stop-before", "StringRef", "", + "Stop compilation before a specific pass">; +defm : OptionalBoolField<"verify-machineinstrs", + "Verify generated machine code">; diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index bf88bcaeb466f7..f6e9f3cd42db75 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/CodeGenPrepare.h" +#include "CodeGenOptions.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -137,146 +138,6 @@ STATISTIC(NumDbgValueMoved, "Number of debug value instructions moved"); STATISTIC(NumSelectsExpanded, "Number of selects turned into branches"); STATISTIC(NumStoreExtractExposed, "Number of store(extractelement) exposed"); -static cl::opt<bool> - EnableBranchOpts("cgp-branch-opts", cl::Hidden, cl::init(true), - cl::desc("Enable branch optimizations in CodeGenPrepare")); - -static cl::opt<bool> - EnableGCOpts("cgp-gc-opts", cl::Hidden, cl::init(true), - cl::desc("Enable GC optimizations in CodeGenPrepare")); - -static cl::opt<bool> - EnableSelectToBranch("cgp-select2branch", cl::Hidden, cl::init(true), - cl::desc("Enable select to branch conversion.")); - -static cl::opt<bool> - AddrSinkUsingGEPs("cgp-addr-sink-using-gep", cl::Hidden, cl::init(true), - cl::desc("Address sinking in CGP using GEPs.")); - -static cl::opt<bool> - EnableAndCmpSinking("cgp-andcmp-sinking", cl::Hidden, cl::init(true), - cl::desc("Enable sinking and/cmp into branches.")); - -static cl::opt<bool> EnableStoreExtract( - "cgp-store-extract", cl::Hidden, cl::init(true), - cl::desc("Enable store(extract) optimizations in CodeGenPrepare")); - -static cl::opt<bool> StressStoreExtract( - "cgp-stress-store-extract", cl::Hidden, cl::init(false), - cl::desc("Stress test store(extract) optimizations in CodeGenPrepare")); - -static cl::opt<bool> EnableExtLdPromotion( - "cgp-ext-ld-promotion", cl::Hidden, cl::init(true), - cl::desc("Enable ext(promotable(ld)) -> promoted(ext(ld)) optimization in " - "CodeGenPrepare")); - -static cl::opt<bool> StressExtLdPromotion( - "cgp-stress-ext-ld-promotion", cl::Hidden, cl::init(false), - cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) " - "optimization in CodeGenPrepare")); - -static cl::opt<bool> - EnablePreheaderProtect("cgp-preheader-prot", cl::Hidden, cl::init(true), - cl::desc("Protect loop preheaders from removal")); - -static cl::opt<bool> ProfileGuidedSectionPrefix( - "profile-guided-section-prefix", cl::Hidden, cl::init(true), - cl::desc("Use profile info to add section prefix for hot/cold functions")); - -static cl::opt<bool> ProfileUnknownInSpecialSection( - "profile-unknown-in-special-section", cl::Hidden, - cl::desc("In profiling mode like sampleFDO, if a function doesn't have " - "profile, we cannot tell the function is cold for sure because " - "it may be a function newly added without ever being sampled. " - "With the flag enabled, compiler can put such profile unknown " - "functions into a special section, so runtime system can choose " - "to handle it in a different way than .text section, to save " - "RAM for example. ")); - -static cl::opt<bool> BBSectionsGuidedSectionPrefix( - "bbsections-guided-section-prefix", cl::Hidden, cl::init(true), - cl::desc("Use the basic-block-sections profile to determine the text " - "section prefix for hot functions. Functions with " - "basic-block-sections profile will be placed in `.text.hot` " - "regardless of their FDO profile info. Other functions won't be " - "impacted, i.e., their prefixes will be decided by FDO/sampleFDO " - "profiles.")); - -static cl::opt<uint64_t> FreqRatioToSkipMerge( - "cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2), - cl::desc("Skip merging empty blocks if (frequency of empty block) / " - "(frequency of destination block) is greater than this ratio")); - -static cl::opt<bool> ForceSplitStore( - "cgp-force-split-store", cl::Hidden, cl::init(false), - cl::desc("Force store splitting no matter what the target query says.")); - -static cl::opt<bool> EnableTypePromotionMerge( - "cgp-type-promotion-merge", cl::Hidden, - cl::desc("Enable merging of redundant sexts when one is dominating" - " the other."), - cl::init(true)); - -static cl::opt<bool> EnableComplexAddrModes( - "cgp-complex-addr-modes", cl::Hidden, cl::init(true), - cl::desc("Enable combining addressing modes with different parts " - "in optimizeMemoryInst.")); - -static cl::opt<bool> - AddrSinkNewPhis("cgp-addr-sink-new-phis", cl::Hidden, cl::init(false), - cl::desc("Allow creation of Phis in Address sinking.")); - -static cl::opt<bool> AddrSinkNewSelects( - "cgp-addr-sink-new-select", cl::Hidden, cl::init(true), - cl::desc("Allow creation of selects in Address sinking.")); - -static cl::opt<bool> AddrSinkCombineBaseReg( - "cgp-addr-sink-combine-base-reg", cl::Hidden, cl::init(true), - cl::desc("Allow combining of BaseReg field in Address sinking.")); - -static cl::opt<bool> AddrSinkCombineBaseGV( - "cgp-addr-sink-combine-base-gv", cl::Hidden, cl::init(true), - cl::desc("Allow combining of BaseGV field in Address sinking.")); - -static cl::opt<bool> AddrSinkCombineBaseOffs( - "cgp-addr-sink-combine-base-offs", cl::Hidden, cl::init(true), - cl::desc("Allow combining of BaseOffs field in Address sinking.")); - -static cl::opt<bool> AddrSinkCombineScaledReg( - "cgp-addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true), - cl::desc("Allow combining of ScaledReg field in Address sinking.")); - -static cl::opt<bool> - EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden, - cl::init(true), - cl::desc("Enable splitting large offset of GEP.")); - -static cl::opt<bool> EnableICMP_EQToICMP_ST( - "cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false), - cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion.")); - -static cl::opt<bool> - VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false), - cl::desc("Enable BFI update verification for " - "CodeGenPrepare.")); - -static cl::opt<bool> - OptimizePhiTypes("cgp-optimize-phi-types", cl::Hidden, cl::init(true), - cl::desc("Enable converting phi types in CodeGenPrepare")); - -static cl::opt<unsigned> - HugeFuncThresholdInCGPP("cgp-huge-func", cl::init(10000), cl::Hidden, - cl::desc("Least BB number of huge function.")); - -static cl::opt<unsigned> - MaxAddressUsersToScan("cgp-max-address-users-to-scan", cl::init(100), - cl::Hidden, - cl::desc("Max number of address users to look at")); - -static cl::opt<bool> - EnableDeletePHIs("cgp-delete-phis", cl::Hidden, cl::init(true), - cl::desc("Enable elimination of dead PHI nodes.")); - namespace { enum ExtType { @@ -307,6 +168,7 @@ class TypePromotionTransaction; class CodeGenPrepare { friend class CodeGenPrepareLegacyPass; + const CodeGenOptions &Opts = CodeGenOptions::Global; const TargetMachine *TM = nullptr; const TargetSubtargetInfo *SubtargetInfo = nullptr; const TargetLowering *TLI = nullptr; @@ -587,10 +449,10 @@ bool CodeGenPrepare::_run(Function &F) { OptSize = F.hasOptSize(); // Use the basic-block-sections profile to promote hot functions to .text.hot // if requested. - if (BBSectionsGuidedSectionPrefix && BBSectionsProfileReader && + if (Opts.bbsections_guided_section_prefix && BBSectionsProfileReader && BBSectionsProfileReader->isFunctionHot(F.getName())) { (void)F.setSectionPrefix("hot"); - } else if (ProfileGuidedSectionPrefix) { + } else if (Opts.profile_guided_section_prefix) { // The hot attribute overwrites profile count based hotness while profile // counts based hotness overwrite the cold attribute. // This is a conservative behabvior. @@ -603,8 +465,8 @@ bool CodeGenPrepare::_run(Function &F) { else if (PSI->isFunctionColdInCallGraph(&F, *BFI) || F.hasFnAttribute(Attribute::Cold)) (void)F.setSectionPrefix("unlikely"); - else if (ProfileUnknownInSpecialSection && PSI->hasPartialSampleProfile() && - PSI->isFunctionHotnessUnknown(F)) + else if (Opts.profile_unknown_in_special_section && + PSI->hasPartialSampleProfile() && PSI->isFunctionHotnessUnknown(F)) (void)F.setSectionPrefix("unknown"); } @@ -641,7 +503,7 @@ bool CodeGenPrepare::_run(Function &F) { if (ResetLI) resetLoopInfo(); - if (EnableBranchOpts) + if (Opts.cgp_branch_opts) EverMadeChange |= splitBranchCondition(F); // Split some critical edges where one of the sources is an indirect branch, @@ -663,7 +525,7 @@ bool CodeGenPrepare::_run(Function &F) { // If we are optimzing huge function, we need to consider the build time. // Because the basic algorithm's complex is near O(N!). - IsHugeFunc = F.size() > HugeFuncThresholdInCGPP; + IsHugeFunc = F.size() > Opts.cgp_huge_func; bool MadeChange = true; bool FuncIterated = false; @@ -707,7 +569,7 @@ bool CodeGenPrepare::_run(Function &F) { // We have iterated all the BB in the (only work for huge) function. FuncIterated = IsHugeFunc; - if (EnableTypePromotionMerge && !ValToSExtendedUses.empty()) + if (Opts.cgp_type_promotion_merge && !ValToSExtendedUses.empty()) MadeChange |= mergeSExts(F); if (!LargeOffsetGEPMap.empty()) MadeChange |= splitLargeGEPOffsets(); @@ -743,7 +605,7 @@ bool CodeGenPrepare::_run(Function &F) { // LoopInfo is not needed anymore and ConstantFoldTerminator can break it. LI = nullptr; - if (EnableBranchOpts) { + if (Opts.cgp_branch_opts) { MadeChange = false; // Use a set vector to get deterministic iteration order. The order the // blocks are removed may affect whether or not PHI nodes in successors @@ -784,7 +646,7 @@ bool CodeGenPrepare::_run(Function &F) { EverMadeChange |= MadeChange; } - if (EnableGCOpts) { + if (Opts.cgp_gc_opts) { SmallVector<GCStatepointInst *, 2> Statepoints; for (BasicBlock &BB : F) for (Instruction &I : BB) @@ -800,7 +662,7 @@ bool CodeGenPrepare::_run(Function &F) { EverMadeChange |= placePseudoProbes(F); #ifndef NDEBUG - if (VerifyBFIUpdates) + if (Opts.cgp_verify_bfi_updates) verifyBFIUpdates(F); #endif @@ -951,7 +813,7 @@ bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &F, bool &ResetLI) { // Note that this intentionally skips the entry block. for (auto &Block : llvm::drop_begin(F)) { // Delete phi nodes that could block deleting other empty blocks. - if (EnableDeletePHIs) + if (Opts.cgp_delete_phis) MadeChange |= DeleteDeadPHIs(&Block, TLInfo, nullptr, &KnownNonDeadPHIs); } @@ -977,7 +839,7 @@ bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB, // Loop preheaders can be good locations to spill registers. If the // preheader is deleted and we create a critical edge, registers may be // spilled in the loop body instead. - if (EnablePreheaderProtect && isPreheader && + if (Opts.cgp_preheader_prot && isPreheader && !(BB->getSinglePredecessor() && BB->getSinglePredecessor()->getSingleSuccessor())) return false; @@ -1050,7 +912,8 @@ bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB, DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB)) BBFreq += BFI->getBlockFreq(SameValueBB); - std::optional<BlockFrequency> Limit = BBFreq.mul(FreqRatioToSkipMerge); + std::optional<BlockFrequency> Limit = + BBFreq.mul(Opts.cgp_freq_ratio_to_skip_merge); return !Limit || PredFreq <= *Limit; } @@ -2012,9 +1875,9 @@ static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI, /// comparison. /// /// Return true if any changes are made. -static bool foldICmpWithDominatingICmp(CmpInst *Cmp, - const TargetLowering &TLI) { - if (!EnableICMP_EQToICMP_ST && TLI.isEqualityCmpFoldedWithSignedCmp()) +static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI, + bool EnableICmpEqToICmpSt) { + if (!EnableICmpEqToICmpSt && TLI.isEqualityCmpFoldedWithSignedCmp()) return false; ICmpInst::Predicate Pred = Cmp->getPredicate(); @@ -2318,7 +2181,7 @@ bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) { if (unfoldPowerOf2Test(Cmp)) return true; - if (foldICmpWithDominatingICmp(Cmp, *TLI)) + if (foldICmpWithDominatingICmp(Cmp, *TLI, Opts.cgp_icmp_eq2icmp_st)) return true; if (swapICmpOperandsToExposeCSEOpportunities(Cmp)) @@ -3158,7 +3021,7 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB, // Duplicate the return into TailCallBB. (void)FoldReturnIntoUncondBranch(RetI, BB, TailCallBB, DTU); - assert(!VerifyBFIUpdates || + assert(!Opts.cgp_verify_bfi_updates || BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB)); BFI->setBlockFreq(BB, (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB))); @@ -3890,6 +3753,7 @@ class AddressingModeMatcher { ProfileSummaryInfo *PSI; BlockFrequencyInfo *BFI; + const CodeGenOptions &Opts; AddressingModeMatcher( SmallVectorImpl<Instruction *> &AMI, const TargetLowering &TLI, @@ -3899,12 +3763,13 @@ class AddressingModeMatcher { const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT, std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP, - bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) - : AddrModeInsts(AMI), TLI(TLI), TRI(TRI), - DL(MI->getDataLayout()), LI(LI), getDTFn(getDTFn), - AccessTy(AT), AddrSpace(AS), MemoryInst(MI), AddrMode(AM), - InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT), - LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) { + bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, + const CodeGenOptions &Opts) + : AddrModeInsts(AMI), TLI(TLI), TRI(TRI), DL(MI->getDataLayout()), LI(LI), + getDTFn(getDTFn), AccessTy(AT), AddrSpace(AS), MemoryInst(MI), + AddrMode(AM), InsertedInsts(InsertedInsts), + PromotedInsts(PromotedInsts), TPT(TPT), LargeOffsetGEP(LargeOffsetGEP), + OptSize(OptSize), PSI(PSI), BFI(BFI), Opts(Opts) { IgnoreProfitability = false; } @@ -3924,13 +3789,14 @@ class AddressingModeMatcher { const TargetRegisterInfo &TRI, const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT, std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP, - bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) { + bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, + const CodeGenOptions &Opts) { ExtAddrMode Result; - bool Success = AddressingModeMatcher(AddrModeInsts, TLI, TRI, LI, getDTFn, - AccessTy, AS, MemoryInst, Result, - InsertedInsts, PromotedInsts, TPT, - LargeOffsetGEP, OptSize, PSI, BFI) + bool Success = AddressingModeMatcher( + AddrModeInsts, TLI, TRI, LI, getDTFn, AccessTy, AS, + MemoryInst, Result, InsertedInsts, PromotedInsts, TPT, + LargeOffsetGEP, OptSize, PSI, BFI, Opts) .matchAddr(V, 0); (void)Success; assert(Success && "Couldn't select *anything*?"); @@ -4170,6 +4036,7 @@ class AddressingModeCombiner { Type *CommonType = nullptr; const DataLayout &DL; + const CodeGenOptions &Opts; /// Original Address. Value *Original; @@ -4178,8 +4045,9 @@ class AddressingModeCombiner { Value *CommonValue = nullptr; public: - AddressingModeCombiner(const DataLayout &DL, Value *OriginalValue) - : DL(DL), Original(OriginalValue) {} + AddressingModeCombiner(const DataLayout &DL, const CodeGenOptions &Opts, + Value *OriginalValue) + : DL(DL), Opts(Opts), Original(OriginalValue) {} ~AddressingModeCombiner() { eraseCommonValueIfDead(); } @@ -4351,14 +4219,14 @@ class AddressingModeCombiner { // Second Step, fill new nodes by merged values and simplify if possible. FillPlaceholders(Map, TraverseOrder, ST); - if (!AddrSinkNewSelects && ST.countNewSelectNodes() > 0) { + if (!Opts.cgp_addr_sink_new_select && ST.countNewSelectNodes() > 0) { ST.destroyNewNodes(CommonType); return nullptr; } // Now we'd like to match New Phi nodes to existed ones. unsigned PhiNotMatchedCount = 0; - if (!MatchPhiSet(ST, AddrSinkNewPhis, PhiNotMatchedCount)) { + if (!MatchPhiSet(ST, Opts.cgp_addr_sink_new_phis, PhiNotMatchedCount)) { ST.destroyNewNodes(CommonType); return nullptr; } @@ -4551,19 +4419,19 @@ class AddressingModeCombiner { } bool addrModeCombiningAllowed() { - if (!EnableComplexAddrModes) + if (!Opts.cgp_complex_addr_modes) return false; switch (DifferentField) { default: return false; case ExtAddrMode::BaseRegField: - return AddrSinkCombineBaseReg; + return Opts.cgp_addr_sink_combine_base_reg; case ExtAddrMode::BaseGVField: - return AddrSinkCombineBaseGV; + return Opts.cgp_addr_sink_combine_base_gv; case ExtAddrMode::BaseOffsField: - return AddrSinkCombineBaseOffs; + return Opts.cgp_addr_sink_combine_base_offs; case ExtAddrMode::ScaledRegField: - return AddrSinkCombineScaledReg; + return Opts.cgp_addr_sink_combine_scaled_reg; } } }; @@ -5331,26 +5199,26 @@ bool AddressingModeMatcher::matchOperationAddr(User *AddrInst, unsigned Opcode, } AddrMode.BaseOffs -= ConstantOffset; - if (EnableGEPOffsetSplit && isa<GetElementPtrInst>(AddrInst) && + if (Opts.cgp_split_large_offset_gep && isa<GetElementPtrInst>(AddrInst) && TLI.shouldConsiderGEPOffsetSplit() && Depth == 0 && ConstantOffset > 0) { - // Record GEPs with non-zero offsets as candidates for splitting in - // the event that the offset cannot fit into the r+i addressing mode. - // Simple and common case that only one GEP is used in calculating the - // address for the memory access. - Value *Base = AddrInst->getOperand(0); - auto *BaseI = dyn_cast<Instruction>(Base); - auto *GEP = cast<GetElementPtrInst>(AddrInst); - if (isa<Argument>(Base) || isa<GlobalValue>(Base) || - (BaseI && !isa<CastInst>(BaseI) && - !isa<GetElementPtrInst>(BaseI))) { - // Make sure the parent block allows inserting non-PHI instructions - // before the terminator. - BasicBlock *Parent = BaseI ? BaseI->getParent() - : &GEP->getFunction()->getEntryBlock(); - if (!Parent->getTerminator()->isEHPad()) + // Record GEPs with non-zero offsets as candidates for splitting in + // the event that the offset cannot fit into the r+i addressing mode. + // Simple and common case that only one GEP is used in calculating the + // address for the memory access. + Value *Base = AddrInst->getOperand(0); + auto *BaseI = dyn_cast<Instruction>(Base); + auto *GEP = cast<GetElementPtrInst>(AddrInst); + if (isa<Argument>(Base) || isa<GlobalValue>(Base) || + (BaseI && !isa<CastInst>(BaseI) && + !isa<GetElementPtrInst>(BaseI))) { + // Make sure the parent block allows inserting non-PHI instructions + // before the terminator. + BasicBlock *Parent = + BaseI ? BaseI->getParent() : &GEP->getFunction()->getEntryBlock(); + if (!Parent->getTerminator()->isEHPad()) LargeOffsetGEP = std::make_pair(GEP, ConstantOffset); - } + } } return false; @@ -5593,7 +5461,7 @@ static bool FindAllMemoryUses( Instruction *I, SmallVectorImpl<std::pair<Use *, Type *>> &MemoryUses, SmallPtrSetImpl<Instruction *> &ConsideredInsts, const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI, - BlockFrequencyInfo *BFI, unsigned &SeenInsts) { + BlockFrequencyInfo *BFI, unsigned &SeenInsts, unsigned MaxUsersToScan) { // If we already considered this instruction, we're done. if (!ConsideredInsts.insert(I).second) return false; @@ -5606,7 +5474,7 @@ static bool FindAllMemoryUses( for (Use &U : I->uses()) { // Conservatively return true if we're seeing a large number or a deep chain // of users. This avoids excessive compilation times in pathological cases. - if (SeenInsts++ >= MaxAddressUsersToScan) + if (SeenInsts++ >= MaxUsersToScan) return true; Instruction *UserI = cast<Instruction>(U.getUser()); @@ -5668,7 +5536,7 @@ static bool FindAllMemoryUses( } if (FindAllMemoryUses(UserI, MemoryUses, ConsideredInsts, TLI, TRI, OptSize, - PSI, BFI, SeenInsts)) + PSI, BFI, SeenInsts, MaxUsersToScan)) return true; } @@ -5678,14 +5546,13 @@ static bool FindAllMemoryUses( static bool FindAllMemoryUses( Instruction *I, SmallVectorImpl<std::pair<Use *, Type *>> &MemoryUses, const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize, - ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) { + ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, unsigned MaxUsersToScan) { unsigned SeenInsts = 0; SmallPtrSet<Instruction *, 16> ConsideredInsts; return FindAllMemoryUses(I, MemoryUses, ConsideredInsts, TLI, TRI, OptSize, - PSI, BFI, SeenInsts); + PSI, BFI, SeenInsts, MaxUsersToScan); } - /// Return true if Val is already known to be live at the use site that we're /// folding it into. If so, there is no cost to include it in the addressing /// mode. KnownLive1 and KnownLive2 are two values that we know are live at the @@ -5768,7 +5635,8 @@ bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode( // for another (at worst.) In this context, folding an addressing mode into // the use is just a particularly nice way of sinking it. SmallVector<std::pair<Use *, Type *>, 16> MemoryUses; - if (FindAllMemoryUses(I, MemoryUses, TLI, TRI, OptSize, PSI, BFI)) + if (FindAllMemoryUses(I, MemoryUses, TLI, TRI, OptSize, PSI, BFI, + Opts.cgp_max_address_users_to_scan)) return false; // Has a non-memory, non-foldable use! // Now that we know that all uses of this instruction are part of a chain of @@ -5798,7 +5666,7 @@ bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode( AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI, TRI, LI, getDTFn, AddressAccessTy, AS, UserI, Result, InsertedInsts, PromotedInsts, TPT, - LargeOffsetGEP, OptSize, PSI, BFI); + LargeOffsetGEP, OptSize, PSI, BFI, Opts); Matcher.IgnoreProfitability = true; bool Success = Matcher.matchAddr(Address, 0); (void)Success; @@ -5890,7 +5758,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, // the graph are compatible. bool PhiOrSelectSeen = false; SmallVector<Instruction *, 16> AddrModeInsts; - AddressingModeCombiner AddrModes(*DL, Addr); + AddressingModeCombiner AddrModes(*DL, Opts, Addr); TypePromotionTransaction TPT(RemovedInsts); TypePromotionTransaction::ConstRestorationPt LastKnownGood = TPT.getRestorationPoint(); @@ -5936,7 +5804,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, ExtAddrMode NewAddrMode = AddressingModeMatcher::Match( V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn, *TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI, - BFI); + BFI, Opts); GetElementPtrInst *GEP = LargeOffsetGEP.first; if (GEP && !NewGEPBases.count(GEP)) { @@ -6020,8 +5888,9 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, } else SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType()); } - } else if (AddrSinkUsingGEPs || (!AddrSinkUsingGEPs.getNumOccurrences() && - SubtargetInfo->addrSinkUsingGEPs())) { + } else if (valueOr(Opts.cgp_addr_sink_using_gep, true) || + (Opts.cgp_addr_sink_using_gep == BoolOrDefault::Default && + SubtargetInfo->addrSinkUsingGEPs())) { // By default, we use the GEP-based method when AA is used later. This // prevents new inttoptr/ptrtoint pairs from degrading AA capabilities. LLVM_DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode @@ -6719,7 +6588,7 @@ bool CodeGenPrepare::tryToPromoteExts( // this check inside the for loop is to catch the case where an extension // is directly fed by a load because in such case the extension can be moved // up without any promotion on its operands. - if (!TLI->enableExtLdPromotion() || !EnableExtLdPromotion) + if (!TLI->enableExtLdPromotion() || !Opts.cgp_ext_ld_promotion) return false; // Get the action to perform the promotion. @@ -6757,7 +6626,7 @@ bool CodeGenPrepare::tryToPromoteExts( // conservatively ceiling it to 0. TotalCreatedInstsCost = std::max((long long)0, (TotalCreatedInstsCost - ExtCost)); - if (!StressExtLdPromotion && + if (!Opts.cgp_stress_ext_ld_promotion && (TotalCreatedInstsCost > 1 || !isPromotedInstructionLegal(*TLI, *DL, PromotedVal) || (ExtCost == 0 && NewExts.size() > 1))) { @@ -6778,7 +6647,8 @@ bool CodeGenPrepare::tryToPromoteExts( // If we have reached to a load, we need this extra profitability check // as it could potentially be merged into an ext(load). if (isa<LoadInst>(ExtOperand) && - !(StressExtLdPromotion || NewCreatedInstsCost <= ExtCost || + !(Opts.cgp_stress_ext_ld_promotion || + NewCreatedInstsCost <= ExtCost || (ExtOperand->hasOneUse() || hasSameExtUse(ExtOperand, *TLI)))) continue; @@ -7141,7 +7011,7 @@ bool CodeGenPrepare::optimizePhiType( } bool CodeGenPrepare::optimizePhiTypes(Function &F) { - if (!OptimizePhiTypes) + if (!Opts.cgp_optimize_phi_types) return false; bool Changed = false; @@ -7739,7 +7609,7 @@ bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) { /// If we have a SelectInst that will likely profit from branch prediction, /// turn it into a branch. bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { - if (!EnableSelectToBranch) + if (!Opts.cgp_select2branch) return false; // If the SelectOptimize pass is enabled, selects have already been optimized. @@ -8205,6 +8075,8 @@ class VectorPromoteHelper { /// Cost of combining a store and an extract. unsigned StoreExtractCombineCost; + bool StressStoreExtract; + /// Instruction that will be combined with the transition. Instruction *CombineInst = nullptr; @@ -8370,9 +8242,10 @@ class VectorPromoteHelper { public: VectorPromoteHelper(const DataLayout &DL, const TargetLowering &TLI, const TargetTransformInfo &TTI, Instruction *Transition, - unsigned CombineCost) + unsigned CombineCost, bool StressStoreExtract) : DL(DL), TLI(TLI), TTI(TTI), Transition(Transition), - StoreExtractCombineCost(CombineCost) { + StoreExtractCombineCost(CombineCost), + StressStoreExtract(StressStoreExtract) { assert(Transition && "Do not know how to promote null"); } @@ -8493,8 +8366,8 @@ void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) { /// has this feature and this is profitable. bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) { unsigned CombineCost = std::numeric_limits<unsigned>::max(); - if (!EnableStoreExtract || - (!StressStoreExtract && + if (!Opts.cgp_store_extract || + (!Opts.cgp_stress_store_extract && !TLI->canCombineStoreAndExtract(Inst->getOperand(0)->getType(), Inst->getOperand(1), CombineCost))) return false; @@ -8508,7 +8381,8 @@ bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) { // we do not do that for now. BasicBlock *Parent = Inst->getParent(); LLVM_DEBUG(dbgs() << "Found an interesting transition: " << *Inst << '\n'); - VectorPromoteHelper VPH(*DL, *TLI, *TTI, Inst, CombineCost); + VectorPromoteHelper VPH(*DL, *TLI, *TTI, Inst, CombineCost, + Opts.cgp_stress_store_extract); // If the transition has more than one use, assume this is not going to be // beneficial. while (Inst->hasOneUse()) { @@ -8577,7 +8451,8 @@ bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) { /// multiple BBs. The logic in DAG Combine is kept to catch case generated /// during code expansion. static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, - const TargetLowering &TLI) { + const TargetLowering &TLI, + bool ForceSplitStore) { // Handle simple but common cases only. Type *StoreType = SI.getValueOperand()->getType(); @@ -9001,7 +8876,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { } if (StoreInst *SI = dyn_cast<StoreInst>(I)) { - if (splitMergedValStore(*SI, *DL, *TLI)) + if (splitMergedValStore(*SI, *DL, *TLI, Opts.cgp_force_split_store)) return true; SI->setMetadata(LLVMContext::MD_invariant_group, nullptr); unsigned AS = SI->getPointerAddressSpace(); @@ -9022,7 +8897,8 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { BinaryOperator *BinOp = dyn_cast<BinaryOperator>(I); - if (BinOp && BinOp->getOpcode() == Instruction::And && EnableAndCmpSinking && + if (BinOp && BinOp->getOpcode() == Instruction::And && + Opts.cgp_andcmp_sinking && sinkAndCmp0Expression(BinOp, *TLI, InsertedInsts)) return true; diff --git a/llvm/lib/CodeGen/RegisterUsageInfo.cpp b/llvm/lib/CodeGen/RegisterUsageInfo.cpp index d139bd430fb20b..bf2ee0fc57b83f 100644 --- a/llvm/lib/CodeGen/RegisterUsageInfo.cpp +++ b/llvm/lib/CodeGen/RegisterUsageInfo.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/RegisterUsageInfo.h" +#include "CodeGenOptions.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/TargetRegisterInfo.h" @@ -22,7 +23,6 @@ #include "llvm/IR/PassManager.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include <cstdint> @@ -31,9 +31,6 @@ using namespace llvm; -// Defined in TargetPassConfig.cpp -extern cl::opt<bool> PrintRegUsage; - INITIALIZE_PASS(PhysicalRegisterUsageInfoWrapperLegacy, "reg-usage-info", "Register Usage Information Storage", false, true) @@ -49,7 +46,7 @@ bool PhysicalRegisterUsageInfo::doInitialization(Module &M) { } bool PhysicalRegisterUsageInfo::doFinalization(Module &M) { - if (PrintRegUsage) + if (CodeGenOptions::Global.print_regusage) print(errs()); RegMasks.shrink_and_clear(); diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp index 9683d988e80848..d4d0b90591c27f 100644 --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -12,6 +12,7 @@ //===---------------------------------------------------------------------===// #include "llvm/CodeGen/TargetPassConfig.h" +#include "CodeGenOptions.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -57,51 +58,6 @@ using namespace llvm; -static cl::opt<bool> - EnableIPRA("enable-ipra", cl::init(false), cl::Hidden, - cl::desc("Enable interprocedural register allocation " - "to reduce load/store at procedure calls.")); -static cl::opt<bool> DisablePostRASched("disable-post-ra", cl::Hidden, - cl::desc("Disable Post Regalloc Scheduler")); -static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden, - cl::desc("Disable branch folding")); -static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden, - cl::desc("Disable tail duplication")); -static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden, - cl::desc("Disable pre-register allocation tail duplication")); -static cl::opt<bool> DisableBlockPlacement("disable-block-placement", - cl::Hidden, cl::desc("Disable probability-driven block placement")); -static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats", - cl::Hidden, cl::desc("Collect probability-driven block placement stats")); -static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden, - cl::desc("Disable Stack Slot Coloring")); -static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden, - cl::desc("Disable Machine Dead Code Elimination")); -static cl::opt<bool> DisableEarlyIfConversion("disable-early-ifcvt", cl::Hidden, - cl::desc("Disable Early If-conversion")); -static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden, - cl::desc("Disable Machine LICM")); -static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden, - cl::desc("Disable Machine Common Subexpression Elimination")); -static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm", - cl::Hidden, - cl::desc("Disable Machine LICM")); -static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden, - cl::desc("Disable Machine Sinking")); -static cl::opt<bool> DisablePostRAMachineSink("disable-postra-machine-sink", - cl::Hidden, - cl::desc("Disable PostRA Machine Sinking")); -static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden, - cl::desc("Disable Loop Strength Reduction Pass")); -static cl::opt<bool> DisableConstantHoisting("disable-constant-hoisting", - cl::Hidden, cl::desc("Disable ConstantHoisting")); -static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden, - cl::desc("Disable Codegen Prepare")); - -static cl::opt<bool> - TriggerCrash("codegen-pipeline-trigger-crash", cl::init(false), cl::Hidden, - cl::desc("Trigger crash in codegen pipeline")); - namespace { class TriggerCrashFunctionLegacyPass : public FunctionPass { public: @@ -117,37 +73,6 @@ class TriggerCrashFunctionLegacyPass : public FunctionPass { char TriggerCrashFunctionLegacyPass::ID = 0; -static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden, - cl::desc("Disable Copy Propagation pass")); -static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inlining", - cl::Hidden, cl::desc("Disable Partial Libcall Inlining")); -static cl::opt<bool> DisableAtExitBasedGlobalDtorLowering( - "disable-atexit-based-global-dtor-lowering", cl::Hidden, - cl::desc("For MachO, disable atexit()-based global destructor lowering")); -static cl::opt<bool> EnableImplicitNullChecks( - "enable-implicit-null-checks", - cl::desc("Fold null checks into faulting memory operations"), - cl::init(false), cl::Hidden); -static cl::opt<bool> - PrintISelInput("print-isel-input", cl::Hidden, - cl::desc("Print LLVM IR input to isel pass")); -cl::opt<bool> - PrintRegUsage("print-regusage", cl::Hidden, - cl::desc("Print register usage details collected for IPRA")); -static cl::opt<cl::boolOrDefault> - VerifyMachineCode("verify-machineinstrs", cl::Hidden, - cl::desc("Verify generated machine code")); -static cl::opt<cl::boolOrDefault> - DebugifyAndStripAll("debugify-and-strip-all-safe", cl::Hidden, - cl::desc("Debugify MIR before and Strip debug after " - "each pass except those known to be unsafe " - "when debug info is present")); -static cl::opt<cl::boolOrDefault> DebugifyCheckAndStripAll( - "debugify-check-and-strip-all-safe", cl::Hidden, - cl::desc( - "Debugify MIR before, by checking and stripping the debug info after, " - "each pass except those known to be unsafe when debug info is " - "present")); // Enable or disable the MachineOutliner. static cl::opt<RunOutliner> EnableMachineOutliner( "enable-machine-outliner", cl::desc("Enable the machine outliner"), @@ -164,73 +89,6 @@ static cl::opt<RunOutliner> EnableMachineOutliner( clEnumValN(RunOutliner::NeverOutline, "never", "Disable all outlining"), // Sentinel value for unspecified option. clEnumValN(RunOutliner::AlwaysOutline, "", ""))); -static cl::opt<bool> EnableGlobalMergeFunc( - "enable-global-merge-func", cl::Hidden, - cl::desc("Enable global merge functions that are based on hash function")); -// Disable the pass to fix unwind information. Whether the pass is included in -// the pipeline is controlled via the target options, this option serves as -// manual override. -static cl::opt<bool> DisableCFIFixup("disable-cfi-fixup", cl::Hidden, - cl::desc("Disable the CFI fixup pass")); -// Enable or disable FastISel. Both options are needed, because -// FastISel is enabled by default with -fast, and we wish to be -// able to enable or disable fast-isel independently from -O0. -static cl::opt<cl::boolOrDefault> -EnableFastISelOption("fast-isel", cl::Hidden, - cl::desc("Enable the \"fast\" instruction selector")); - -static cl::opt<cl::boolOrDefault> EnableGlobalISelOption( - "global-isel", cl::Hidden, - cl::desc("Enable the \"global\" instruction selector")); - -// FIXME: remove this after switching to NPM or GlobalISel, whichever gets there -// first... -static cl::opt<bool> - PrintAfterISel("print-after-isel", cl::init(false), cl::Hidden, - cl::desc("Print machine instrs after ISel")); - -static cl::opt<GlobalISelAbortMode> EnableGlobalISelAbort( - "global-isel-abort", cl::Hidden, - cl::desc("Enable abort calls when \"global\" instruction selection " - "fails to lower/select an instruction"), - cl::values( - clEnumValN(GlobalISelAbortMode::Disable, "0", "Disable the abort"), - clEnumValN(GlobalISelAbortMode::Enable, "1", "Enable the abort"), - clEnumValN(GlobalISelAbortMode::DisableWithDiag, "2", - "Disable the abort but emit a diagnostic on failure"))); - -// Disable MIRProfileLoader before RegAlloc. This is for for debugging and -// tuning purpose. -static cl::opt<bool> DisableRAFSProfileLoader( - "disable-ra-fsprofile-loader", cl::init(false), cl::Hidden, - cl::desc("Disable MIRProfileLoader before RegAlloc")); -// Disable MIRProfileLoader before BloackPlacement. This is for for debugging -// and tuning purpose. -static cl::opt<bool> DisableLayoutFSProfileLoader( - "disable-layout-fsprofile-loader", cl::init(false), cl::Hidden, - cl::desc("Disable MIRProfileLoader before BlockPlacement")); -// Specify FSProfile file name. -static cl::opt<std::string> - FSProfileFile("fs-profile-file", cl::init(""), cl::value_desc("filename"), - cl::desc("Flow Sensitive profile file name."), cl::Hidden); -// Specify Remapping file for FSProfile. -static cl::opt<std::string> FSRemappingFile( - "fs-remapping-file", cl::init(""), cl::value_desc("filename"), - cl::desc("Flow Sensitive profile remapping file name."), cl::Hidden); - -// Temporary option to allow experimenting with MachineScheduler as a post-RA -// scheduler. Targets can "properly" enable this with -// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID). -// Targets can return true in targetSchedulesPostRAScheduling() and -// insert a PostRA scheduling pass wherever it wants. -static cl::opt<bool> MISchedPostRA( - "misched-postra", cl::Hidden, - cl::desc( - "Run MachineScheduler post regalloc (independent of preRA sched)")); - -static cl::opt<bool> DisableReplaceWithVecLib( - "disable-replace-with-vec-lib", cl::Hidden, - cl::desc("Disable replace with vector math call pass")); /// Option names for limiting the codegen pipeline. /// Those are used in error reporting and we didn't want @@ -240,59 +98,6 @@ static const char StartBeforeOptName[] = "start-before"; static const char StopAfterOptName[] = "stop-after"; static const char StopBeforeOptName[] = "stop-before"; -static cl::opt<std::string> - StartAfterOpt(StringRef(StartAfterOptName), - cl::desc("Resume compilation after a specific pass"), - cl::value_desc("pass-name"), cl::init(""), cl::Hidden); - -static cl::opt<std::string> - StartBeforeOpt(StringRef(StartBeforeOptName), - cl::desc("Resume compilation before a specific pass"), - cl::value_desc("pass-name"), cl::init(""), cl::Hidden); - -static cl::opt<std::string> - StopAfterOpt(StringRef(StopAfterOptName), - cl::desc("Stop compilation after a specific pass"), - cl::value_desc("pass-name"), cl::init(""), cl::Hidden); - -static cl::opt<std::string> - StopBeforeOpt(StringRef(StopBeforeOptName), - cl::desc("Stop compilation before a specific pass"), - cl::value_desc("pass-name"), cl::init(""), cl::Hidden); - -/// Enable the machine function splitter pass. -static cl::opt<bool> EnableMachineFunctionSplitter( - "enable-split-machine-functions", cl::Hidden, - cl::desc("Split out cold blocks from machine functions based on profile " - "information.")); - -/// Disable the expand reductions pass for testing. -static cl::opt<bool> DisableExpandReductions( - "disable-expand-reductions", cl::init(false), cl::Hidden, - cl::desc("Disable the expand reduction intrinsics pass from running")); - -/// Disable the select optimization pass. -static cl::opt<bool> DisableSelectOptimize( - "disable-select-optimize", cl::init(true), cl::Hidden, - cl::desc("Disable the select-optimization pass from running")); - -/// Enable garbage-collecting empty basic blocks. -static cl::opt<bool> EnableGCEmptyBlocks( - "enable-gc-empty-basic-blocks", cl::init(false), cl::Hidden, - cl::desc("Enable garbage-collecting empty basic blocks")); - -static cl::opt<bool> - SplitStaticData("split-static-data", cl::Hidden, cl::init(false), - cl::desc("Split static data sections into hot and cold " - "sections using profile information")); - -/// Enable matching and inference when using propeller. -static cl::opt<bool> BasicBlockSectionMatchInfer( - "basic-block-section-match-infer", - cl::desc( - "Enable matching and inference when generating basic block sections"), - cl::init(false)); - /// Allow standard passes to be disabled by command line options. This supports /// simple binary flags that either suppress the pass or do nothing. /// i.e. -disable-mypass=false has no effect. @@ -318,47 +123,48 @@ static IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID, /// on where in the pipeline that pass is added. static IdentifyingPassPtr overridePass(AnalysisID StandardID, IdentifyingPassPtr TargetID) { + const CodeGenOptions &Opts = CodeGenOptions::Global; if (StandardID == &PostRASchedulerID) - return applyDisable(TargetID, DisablePostRASched); + return applyDisable(TargetID, Opts.disable_post_ra); if (StandardID == &BranchFolderPassID) - return applyDisable(TargetID, DisableBranchFold); + return applyDisable(TargetID, Opts.disable_branch_fold); if (StandardID == &TailDuplicateLegacyID) - return applyDisable(TargetID, DisableTailDuplicate); + return applyDisable(TargetID, Opts.disable_tail_duplicate); if (StandardID == &EarlyTailDuplicateLegacyID) - return applyDisable(TargetID, DisableEarlyTailDup); + return applyDisable(TargetID, Opts.disable_early_taildup); if (StandardID == &MachineBlockPlacementID) - return applyDisable(TargetID, DisableBlockPlacement); + return applyDisable(TargetID, Opts.disable_block_placement); if (StandardID == &StackSlotColoringID) - return applyDisable(TargetID, DisableSSC); + return applyDisable(TargetID, Opts.disable_ssc); if (StandardID == &DeadMachineInstructionElimID) - return applyDisable(TargetID, DisableMachineDCE); + return applyDisable(TargetID, Opts.disable_machine_dce); if (StandardID == &EarlyIfConverterLegacyID) - return applyDisable(TargetID, DisableEarlyIfConversion); + return applyDisable(TargetID, Opts.disable_early_ifcvt); if (StandardID == &EarlyMachineLICMID) - return applyDisable(TargetID, DisableMachineLICM); + return applyDisable(TargetID, Opts.disable_machine_licm); if (StandardID == &MachineCSELegacyID) - return applyDisable(TargetID, DisableMachineCSE); + return applyDisable(TargetID, Opts.disable_machine_cse); if (StandardID == &MachineLICMID) - return applyDisable(TargetID, DisablePostRAMachineLICM); + return applyDisable(TargetID, Opts.disable_postra_machine_licm); if (StandardID == &MachineSinkingLegacyID) - return applyDisable(TargetID, DisableMachineSink); + return applyDisable(TargetID, Opts.disable_machine_sink); if (StandardID == &PostRAMachineSinkingID) - return applyDisable(TargetID, DisablePostRAMachineSink); + return applyDisable(TargetID, Opts.disable_postra_machine_sink); if (StandardID == &MachineCopyPropagationID) - return applyDisable(TargetID, DisableCopyProp); + return applyDisable(TargetID, Opts.disable_copyprop); return TargetID; } @@ -366,8 +172,9 @@ static IdentifyingPassPtr overridePass(AnalysisID StandardID, // Find the FSProfile file name. The internal option takes the precedence // before getting from TargetMachine. static std::string getFSProfileFile(const TargetMachine *TM) { - if (!FSProfileFile.empty()) - return FSProfileFile.getValue(); + const CodeGenOptions &Opts = CodeGenOptions::Global; + if (!Opts.fs_profile_file.empty()) + return Opts.fs_profile_file.str(); const std::optional<PGOOptions> &PGOOpt = TM->getPGOOption(); if (PGOOpt == std::nullopt || PGOOpt->Action != PGOOptions::SampleUse) return std::string(); @@ -377,8 +184,9 @@ static std::string getFSProfileFile(const TargetMachine *TM) { // Find the Profile remapping file name. The internal option takes the // precedence before getting from TargetMachine. static std::string getFSRemappingFile(const TargetMachine *TM) { - if (!FSRemappingFile.empty()) - return FSRemappingFile.getValue(); + const CodeGenOptions &Opts = CodeGenOptions::Global; + if (!Opts.fs_remapping_file.empty()) + return Opts.fs_remapping_file.str(); const std::optional<PGOOptions> &PGOOpt = TM->getPGOOption(); if (PGOOpt == std::nullopt || PGOOpt->Action != PGOOptions::SampleUse) return std::string(); @@ -469,21 +277,22 @@ getPassNameAndInstanceNum(StringRef PassName) { } void TargetPassConfig::setStartStopPasses() { + const CodeGenOptions &Opts = CodeGenOptions::Global; StringRef StartBeforeName; std::tie(StartBeforeName, StartBeforeInstanceNum) = - getPassNameAndInstanceNum(StartBeforeOpt); + getPassNameAndInstanceNum(Opts.start_before); StringRef StartAfterName; std::tie(StartAfterName, StartAfterInstanceNum) = - getPassNameAndInstanceNum(StartAfterOpt); + getPassNameAndInstanceNum(Opts.start_after); StringRef StopBeforeName; - std::tie(StopBeforeName, StopBeforeInstanceNum) - = getPassNameAndInstanceNum(StopBeforeOpt); + std::tie(StopBeforeName, StopBeforeInstanceNum) = + getPassNameAndInstanceNum(Opts.stop_before); StringRef StopAfterName; - std::tie(StopAfterName, StopAfterInstanceNum) - = getPassNameAndInstanceNum(StopAfterOpt); + std::tie(StopAfterName, StopAfterInstanceNum) = + getPassNameAndInstanceNum(Opts.stop_after); StartBefore = getPassIDFromName(StartBeforeName); StartAfter = getPassIDFromName(StartAfterName); @@ -498,44 +307,46 @@ void TargetPassConfig::setStartStopPasses() { Started = (StartAfter == nullptr) && (StartBefore == nullptr); } +static cl::boolOrDefault toBoolOrDefault(BoolOrDefault B) { + if (B == BoolOrDefault::Default) + return cl::boolOrDefault::BOU_UNSET; + return B == BoolOrDefault::True ? cl::boolOrDefault::BOU_TRUE + : cl::boolOrDefault::BOU_FALSE; +} + CGPassBuilderOption llvm::getCGPassBuilderOption() { + const CodeGenOptions &Opts = CodeGenOptions::Global; CGPassBuilderOption Opt; - -#define SET_OPTION_IF_PRESENT(Option) \ - if (Option.getNumOccurrences()) \ - Opt.Option = Option; - - SET_OPTION_IF_PRESENT(EnableGlobalISelAbort) - SET_OPTION_IF_PRESENT(EnableIPRA) - -#define SET_OPTION(Option) Opt.Option = Option; - - SET_OPTION(EnableFastISelOption) - SET_OPTION(EnableGlobalISelOption) - SET_OPTION(VerifyMachineCode) - SET_OPTION(DisableAtExitBasedGlobalDtorLowering) - SET_OPTION(DisableExpandReductions) - SET_OPTION(PrintAfterISel) - SET_OPTION(FSProfileFile) - SET_OPTION(EnableGCEmptyBlocks) - SET_OPTION(EnableBlockPlacementStats) - SET_OPTION(EnableGlobalMergeFunc) - SET_OPTION(EnableImplicitNullChecks) - SET_OPTION(EnableMachineOutliner) - SET_OPTION(MISchedPostRA) - SET_OPTION(DisableLSR) - SET_OPTION(DisableConstantHoisting) - SET_OPTION(DisableCGP) - SET_OPTION(DisablePartialLibcallInlining) - SET_OPTION(DisableSelectOptimize) - SET_OPTION(PrintISelInput) - SET_OPTION(PrintRegUsage) - SET_OPTION(DebugifyAndStripAll) - SET_OPTION(DebugifyCheckAndStripAll) - SET_OPTION(DisableRAFSProfileLoader) - SET_OPTION(DisableCFIFixup) - SET_OPTION(EnableMachineFunctionSplitter) - + Opt.EnableGlobalISelAbort = Opts.global_isel_abort; + if (Opts.enable_ipra != BoolOrDefault::Default) + Opt.EnableIPRA = Opts.enable_ipra == BoolOrDefault::True; + Opt.EnableFastISelOption = toBoolOrDefault(Opts.fast_isel); + Opt.EnableGlobalISelOption = toBoolOrDefault(Opts.global_isel); + Opt.VerifyMachineCode = toBoolOrDefault(Opts.verify_machineinstrs); + Opt.DisableAtExitBasedGlobalDtorLowering = + Opts.disable_atexit_based_global_dtor_lowering; + Opt.DisableExpandReductions = Opts.disable_expand_reductions; + Opt.PrintAfterISel = Opts.print_after_isel; + Opt.FSProfileFile = Opts.fs_profile_file.str(); + Opt.EnableGCEmptyBlocks = Opts.enable_gc_empty_basic_blocks; + Opt.EnableBlockPlacementStats = Opts.enable_block_placement_stats; + Opt.EnableGlobalMergeFunc = Opts.enable_global_merge_func; + Opt.EnableImplicitNullChecks = Opts.enable_implicit_null_checks; + Opt.EnableMachineOutliner = EnableMachineOutliner; + Opt.MISchedPostRA = Opts.misched_postra; + Opt.DisableLSR = Opts.disable_lsr; + Opt.DisableConstantHoisting = Opts.disable_constant_hoisting; + Opt.DisableCGP = Opts.disable_cgp; + Opt.DisablePartialLibcallInlining = Opts.disable_partial_libcall_inlining; + Opt.DisableSelectOptimize = Opts.disable_select_optimize; + Opt.PrintISelInput = Opts.print_isel_input; + Opt.PrintRegUsage = Opts.print_regusage; + Opt.DebugifyAndStripAll = toBoolOrDefault(Opts.debugify_and_strip_all_safe); + Opt.DebugifyCheckAndStripAll = + toBoolOrDefault(Opts.debugify_check_and_strip_all_safe); + Opt.DisableRAFSProfileLoader = Opts.disable_ra_fsprofile_loader; + Opt.DisableCFIFixup = Opts.disable_cfi_fixup; + Opt.EnableMachineFunctionSplitter = Opts.enable_split_machine_functions; return Opt; } @@ -544,24 +355,25 @@ void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC, // Register a callback for disabling passes. PIC.registerShouldRunOptionalPassCallback([](StringRef P, IRUnitRef) { + const CodeGenOptions &Opts = CodeGenOptions::Global; #define DISABLE_PASS(Option, Name) \ if (Option && P.contains(#Name)) \ return false; - DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass) - DISABLE_PASS(DisableBranchFold, BranchFolderPass) - DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass) - DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterLegacyPass) - DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass) - DISABLE_PASS(DisableMachineCSE, MachineCSELegacyPass) - DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass) - DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass) - DISABLE_PASS(DisableMachineSink, MachineSinkingPass) - DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass) - DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass) - DISABLE_PASS(DisablePostRASched, PostRASchedulerPass) - DISABLE_PASS(DisableSSC, StackSlotColoringPass) - DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass) + DISABLE_PASS(Opts.disable_block_placement, MachineBlockPlacementPass) + DISABLE_PASS(Opts.disable_branch_fold, BranchFolderPass) + DISABLE_PASS(Opts.disable_copyprop, MachineCopyPropagationPass) + DISABLE_PASS(Opts.disable_early_ifcvt, EarlyIfConverterLegacyPass) + DISABLE_PASS(Opts.disable_early_taildup, EarlyTailDuplicatePass) + DISABLE_PASS(Opts.disable_machine_cse, MachineCSELegacyPass) + DISABLE_PASS(Opts.disable_machine_dce, DeadMachineInstructionElimPass) + DISABLE_PASS(Opts.disable_machine_licm, EarlyMachineLICMPass) + DISABLE_PASS(Opts.disable_machine_sink, MachineSinkingPass) + DISABLE_PASS(Opts.disable_postra_machine_licm, MachineLICMPass) + DISABLE_PASS(Opts.disable_postra_machine_sink, PostRAMachineSinkingPass) + DISABLE_PASS(Opts.disable_post_ra, PostRASchedulerPass) + DISABLE_PASS(Opts.disable_ssc, StackSlotColoringPass) + DISABLE_PASS(Opts.disable_tail_duplicate, TailDuplicatePass) return true; }); @@ -569,14 +381,15 @@ void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC, Expected<TargetPassConfig::StartStopInfo> TargetPassConfig::getStartStopInfo(PassInstrumentationCallbacks &PIC) { + const CodeGenOptions &Opts = CodeGenOptions::Global; auto [StartBefore, StartBeforeInstanceNum] = - getPassNameAndInstanceNum(StartBeforeOpt); + getPassNameAndInstanceNum(Opts.start_before); auto [StartAfter, StartAfterInstanceNum] = - getPassNameAndInstanceNum(StartAfterOpt); + getPassNameAndInstanceNum(Opts.start_after); auto [StopBefore, StopBeforeInstanceNum] = - getPassNameAndInstanceNum(StopBeforeOpt); + getPassNameAndInstanceNum(Opts.stop_before); auto [StopAfter, StopAfterInstanceNum] = - getPassNameAndInstanceNum(StopAfterOpt); + getPassNameAndInstanceNum(Opts.stop_after); if (!StartBefore.empty() && !StartAfter.empty()) return make_error<StringError>( @@ -605,6 +418,7 @@ TargetPassConfig::getStartStopInfo(PassInstrumentationCallbacks &PIC) { // registers all common codegen passes. TargetPassConfig::TargetPassConfig(TargetMachine &TM, PassManagerBase &PM) : ImmutablePass(ID), PM(&PM), TM(&TM) { + const CodeGenOptions &Opts = CodeGenOptions::Global; Impl = new PassConfigImpl(); PassRegistry &PR = *PassRegistry::getPassRegistry(); @@ -618,8 +432,8 @@ TargetPassConfig::TargetPassConfig(TargetMachine &TM, PassManagerBase &PM) initializeBasicAAWrapperPassPass(PR); initializeAAResultsWrapperPassPass(PR); - if (EnableIPRA.getNumOccurrences()) { - TM.Options.EnableIPRA = EnableIPRA; + if (Opts.enable_ipra != BoolOrDefault::Default) { + TM.Options.EnableIPRA = Opts.enable_ipra == BoolOrDefault::True; } else { // If not explicitly specified, use target default. TM.Options.EnableIPRA |= TM.useIPRA(); @@ -628,8 +442,8 @@ TargetPassConfig::TargetPassConfig(TargetMachine &TM, PassManagerBase &PM) if (TM.Options.EnableIPRA) setRequiresCodeGenSCCOrder(); - if (EnableGlobalISelAbort.getNumOccurrences()) - TM.Options.GlobalISelAbort = EnableGlobalISelAbort; + if (Opts.global_isel_abort) + TM.Options.GlobalISelAbort = *Opts.global_isel_abort; setStartStopPasses(); } @@ -666,25 +480,28 @@ TargetPassConfig::TargetPassConfig() } bool TargetPassConfig::willCompleteCodeGenPipeline() { - return StopBeforeOpt.empty() && StopAfterOpt.empty(); + const CodeGenOptions &Opts = CodeGenOptions::Global; + return Opts.stop_before.empty() && Opts.stop_after.empty(); } bool TargetPassConfig::hasLimitedCodeGenPipeline() { - return !StartBeforeOpt.empty() || !StartAfterOpt.empty() || + const CodeGenOptions &Opts = CodeGenOptions::Global; + return !Opts.start_before.empty() || !Opts.start_after.empty() || !willCompleteCodeGenPipeline(); } std::string TargetPassConfig::getLimitedCodeGenPipelineReason() { + const CodeGenOptions &Opts = CodeGenOptions::Global; if (!hasLimitedCodeGenPipeline()) return std::string(); std::string Res; - static cl::opt<std::string> *PassNames[] = {&StartAfterOpt, &StartBeforeOpt, - &StopAfterOpt, &StopBeforeOpt}; + StringRef PassNames[] = {Opts.start_after, Opts.start_before, Opts.stop_after, + Opts.stop_before}; static const char *OptNames[] = {StartAfterOptName, StartBeforeOptName, StopAfterOptName, StopBeforeOptName}; bool IsFirst = true; for (int Idx = 0; Idx < 4; ++Idx) - if (!PassNames[Idx]->empty()) { + if (!PassNames[Idx].empty()) { if (!IsFirst) Res += " and "; IsFirst = false; @@ -797,14 +614,15 @@ void TargetPassConfig::printAndVerify(const std::string &Banner) { } void TargetPassConfig::addPrintPass(const std::string &Banner) { - if (PrintAfterISel) + if (CodeGenOptions::Global.print_after_isel) PM->add(createMachineFunctionPrinterPass(dbgs(), Banner)); } void TargetPassConfig::addVerifyPass(const std::string &Banner) { - bool Verify = VerifyMachineCode == cl::boolOrDefault::BOU_TRUE; + const CodeGenOptions &Opts = CodeGenOptions::Global; + bool Verify = valueOr(Opts.verify_machineinstrs, false); #ifdef EXPENSIVE_CHECKS - if (VerifyMachineCode == cl::boolOrDefault::BOU_UNSET) + if (Opts.verify_machineinstrs == BoolOrDefault::Default) Verify = TM->isMachineVerifierClean(); #endif if (Verify) @@ -824,18 +642,20 @@ void TargetPassConfig::addCheckDebugPass() { } void TargetPassConfig::addMachinePrePasses(bool AllowDebugify) { + const CodeGenOptions &Opts = CodeGenOptions::Global; if (AllowDebugify && DebugifyIsSafe && - (DebugifyAndStripAll == cl::boolOrDefault::BOU_TRUE || - DebugifyCheckAndStripAll == cl::boolOrDefault::BOU_TRUE)) + (valueOr(Opts.debugify_and_strip_all_safe, false) || + valueOr(Opts.debugify_check_and_strip_all_safe, false))) addDebugifyPass(); } void TargetPassConfig::addMachinePostPasses(const std::string &Banner) { + const CodeGenOptions &Opts = CodeGenOptions::Global; if (DebugifyIsSafe) { - if (DebugifyCheckAndStripAll == cl::boolOrDefault::BOU_TRUE) { + if (valueOr(Opts.debugify_check_and_strip_all_safe, false)) { addCheckDebugPass(); addStripDebugPass(); - } else if (DebugifyAndStripAll == cl::boolOrDefault::BOU_TRUE) + } else if (valueOr(Opts.debugify_and_strip_all_safe, false)) addStripDebugPass(); } addVerifyPass(Banner); @@ -844,6 +664,7 @@ void TargetPassConfig::addMachinePostPasses(const std::string &Banner) { /// Add common target configurable passes that perform LLVM IR to IR transforms /// following machine independent optimization. void TargetPassConfig::addIRPasses() { + const CodeGenOptions &Opts = CodeGenOptions::Global; // Before running any passes, run the verifier to determine if the input // coming from the front-end and/or optimizer is valid. if (!DisableVerify) @@ -859,7 +680,7 @@ void TargetPassConfig::addIRPasses() { addPass(createBasicAAWrapperPass()); // Run loop strength reduction before anything else. - if (!DisableLSR) { + if (!Opts.disable_lsr) { addPass(createCanonicalizeFreezeInLoopsPass()); addPass(createLoopStrengthReducePass()); if (EnableLoopTermFold) @@ -875,20 +696,22 @@ void TargetPassConfig::addIRPasses() { // For MachO, lower @llvm.global_dtors into @llvm.global_ctors with // __cxa_atexit() calls to avoid emitting the deprecated __mod_term_func. if (TM->getTargetTriple().isOSBinFormatMachO() && - !DisableAtExitBasedGlobalDtorLowering) + !Opts.disable_atexit_based_global_dtor_lowering) addPass(createLowerGlobalDtorsLegacyPass()); // Make sure that no unreachable blocks are instruction selected. addPass(createUnreachableBlockEliminationPass()); // Prepare expensive constants for SelectionDAG. - if (getOptLevel() != CodeGenOptLevel::None && !DisableConstantHoisting) + if (getOptLevel() != CodeGenOptLevel::None && !Opts.disable_constant_hoisting) addPass(createConstantHoistingPass()); - if (getOptLevel() != CodeGenOptLevel::None && !DisableReplaceWithVecLib) + if (getOptLevel() != CodeGenOptLevel::None && + !Opts.disable_replace_with_vec_lib) addPass(createReplaceWithVeclibLegacyPass()); - if (getOptLevel() != CodeGenOptLevel::None && !DisablePartialLibcallInlining) + if (getOptLevel() != CodeGenOptLevel::None && + !Opts.disable_partial_libcall_inlining) addPass(createPartiallyInlineLibCallsPass()); // Instrument function entry after all inlining. @@ -901,14 +724,14 @@ void TargetPassConfig::addIRPasses() { // Expand reduction intrinsics into shuffle sequences if the target wants to. // Allow disabling it for testing purposes. - if (!DisableExpandReductions) + if (!Opts.disable_expand_reductions) addPass(createExpandReductionsPass()); // Convert conditional moves to conditional jumps when profitable. - if (getOptLevel() != CodeGenOptLevel::None && !DisableSelectOptimize) + if (getOptLevel() != CodeGenOptLevel::None && !Opts.disable_select_optimize) addPass(createSelectOptimizePass()); - if (EnableGlobalMergeFunc) + if (Opts.enable_global_merge_func) addPass(createGlobalMergeFuncPass()); if (TM->getTargetTriple().isOSWindows()) @@ -966,7 +789,8 @@ void TargetPassConfig::addPassesToHandleExceptions() { /// Add pass to prepare the LLVM IR for code generation. This should be done /// before exception handling preparation passes. void TargetPassConfig::addCodeGenPrepare() { - if (getOptLevel() != CodeGenOptLevel::None && !DisableCGP) + if (getOptLevel() != CodeGenOptLevel::None && + !CodeGenOptions::Global.disable_cgp) addPass(createCodeGenPrepareLegacyPass()); } @@ -986,7 +810,7 @@ void TargetPassConfig::addISelPrepare() { addPass(createSafeStackPass()); addPass(createStackProtectorPass()); - if (PrintISelInput) + if (CodeGenOptions::Global.print_isel_input) addPass(createPrintFunctionPass( dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n")); @@ -997,18 +821,18 @@ void TargetPassConfig::addISelPrepare() { } bool TargetPassConfig::addCoreISelPasses() { + const CodeGenOptions &Opts = CodeGenOptions::Global; // Enable FastISel with -fast-isel, but allow that to be overridden. - TM->setO0WantsFastISel(EnableFastISelOption != cl::boolOrDefault::BOU_FALSE); + TM->setO0WantsFastISel(valueOr(Opts.fast_isel, true)); // Determine an instruction selector. enum class SelectorType { SelectionDAG, FastISel, GlobalISel }; SelectorType Selector; - if (EnableFastISelOption == cl::boolOrDefault::BOU_TRUE) + if (valueOr(Opts.fast_isel, false)) Selector = SelectorType::FastISel; - else if (EnableGlobalISelOption == cl::boolOrDefault::BOU_TRUE || - (TM->Options.EnableGlobalISel && - EnableGlobalISelOption != cl::boolOrDefault::BOU_FALSE)) + else if (valueOr(Opts.global_isel, false) || + (TM->Options.EnableGlobalISel && valueOr(Opts.global_isel, true))) Selector = SelectorType::GlobalISel; else if (TM->getOptLevel() == CodeGenOptLevel::None && TM->getO0WantsFastISel()) @@ -1097,7 +921,7 @@ bool TargetPassConfig::addISelPasses() { addPass(createExpandIRInstsPass(getOptLevel())); addIRPasses(); - if (TriggerCrash) + if (CodeGenOptions::Global.codegen_pipeline_trigger_crash) addPass(new TriggerCrashFunctionLegacyPass()); addCodeGenPrepare(); @@ -1133,6 +957,7 @@ static cl::opt<RegisterRegAlloc::FunctionPassCtor, false, /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection /// before/after any target-independent pass. But it's currently overkill. void TargetPassConfig::addMachinePasses() { + const CodeGenOptions &Opts = CodeGenOptions::Global; AddingMachinePasses = true; // Add passes that optimize machine instructions in SSA form. @@ -1161,7 +986,7 @@ void TargetPassConfig::addMachinePasses() { addPass(createMIRAddFSDiscriminatorsPass( sampleprof::FSDiscriminatorPass::Pass1)); const std::string ProfileFile = getFSProfileFile(TM); - if (!ProfileFile.empty() && !DisableRAFSProfileLoader) + if (!ProfileFile.empty() && !Opts.disable_ra_fsprofile_loader) addPass(createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM), sampleprof::FSDiscriminatorPass::Pass1, nullptr)); @@ -1202,7 +1027,7 @@ void TargetPassConfig::addMachinePasses() { // Run pre-sched2 passes. addPreSched2(); - if (EnableImplicitNullChecks) + if (Opts.enable_implicit_null_checks) addPass(&ImplicitNullChecksID); // Second pass scheduler. @@ -1210,7 +1035,7 @@ void TargetPassConfig::addMachinePasses() { // point. if (getOptLevel() != CodeGenOptLevel::None && !TM->targetSchedulesPostRAScheduling()) { - if (MISchedPostRA) + if (Opts.misched_postra) addPass(&PostMachineSchedulerID); else addPass(&PostRASchedulerID); @@ -1253,7 +1078,7 @@ void TargetPassConfig::addMachinePasses() { addPass(createMachineOutlinerPass(EnableMachineOutliner)); } - if (EnableGCEmptyBlocks) + if (Opts.enable_gc_empty_basic_blocks) addPass(llvm::createGCEmptyBasicBlocksLegacyPass()); if (EnableFSDiscriminator) @@ -1261,7 +1086,7 @@ void TargetPassConfig::addMachinePasses() { sampleprof::FSDiscriminatorPass::PassLast)); if (TM->Options.EnableMachineFunctionSplitter || - EnableMachineFunctionSplitter || SplitStaticData || + Opts.enable_split_machine_functions || Opts.split_static_data || TM->Options.EnableStaticDataPartitioning) { const std::string ProfileFile = getFSProfileFile(TM); if (!ProfileFile.empty()) { @@ -1285,10 +1110,10 @@ void TargetPassConfig::addMachinePasses() { // basic-block-sections optimizations (`=all`, or `=list=` with function // included in the list profile) will get that optimization instead. if (TM->Options.EnableMachineFunctionSplitter || - EnableMachineFunctionSplitter) + Opts.enable_split_machine_functions) addPass(createMachineFunctionSplitterPass()); - if (SplitStaticData || TM->Options.EnableStaticDataPartitioning) { + if (Opts.split_static_data || TM->Options.EnableStaticDataPartitioning) { // The static data splitter pass is a machine function pass. and // static data annotator pass is a module-wide pass. See the file comment // in StaticDataAnnotator.cpp for the motivation. @@ -1299,12 +1124,12 @@ void TargetPassConfig::addMachinePasses() { // address map (or both). if (TM->getBBSectionsType() != llvm::BasicBlockSection::None || TM->Options.BBAddrMap) { - if (shouldEmitBBHash() || BasicBlockSectionMatchInfer) + if (shouldEmitBBHash() || Opts.basic_block_section_match_infer) addPass(llvm::createMachineBlockHashInfoPass()); if (TM->getBBSectionsType() == llvm::BasicBlockSection::List) { addPass(llvm::createBasicBlockSectionsProfileReaderWrapperPass( TM->getBBSectionsFuncListBuf())); - if (BasicBlockSectionMatchInfer) + if (Opts.basic_block_section_match_infer) addPass(llvm::createBasicBlockMatchingAndInferencePass()); else { addPass(llvm::createBasicBlockPathCloningPass()); @@ -1316,7 +1141,7 @@ void TargetPassConfig::addMachinePasses() { addPostBBSections(); - if (!DisableCFIFixup && TM->Options.EnableCFIFixup) + if (!Opts.disable_cfi_fixup && TM->Options.EnableCFIFixup) addPass(createCFIFixupLegacy()); PM->add(createStackFrameLayoutAnalysisPass()); @@ -1575,18 +1400,19 @@ bool TargetPassConfig::addGCPasses() { /// Add standard basic block placement passes. void TargetPassConfig::addBlockPlacement() { + const CodeGenOptions &Opts = CodeGenOptions::Global; if (EnableFSDiscriminator) { addPass(createMIRAddFSDiscriminatorsPass( sampleprof::FSDiscriminatorPass::Pass2)); const std::string ProfileFile = getFSProfileFile(TM); - if (!ProfileFile.empty() && !DisableLayoutFSProfileLoader) + if (!ProfileFile.empty() && !Opts.disable_layout_fsprofile_loader) addPass(createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM), sampleprof::FSDiscriminatorPass::Pass2, nullptr)); } if (addPass(&MachineBlockPlacementID)) { // Run a separate pass to collect block placement statistics. - if (EnableBlockPlacementStats) + if (Opts.enable_block_placement_stats) addPass(&MachineBlockPlacementStatsID); } } diff --git a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn index cc1463cbe9e3ae..dfcb12d75a4657 100644 --- a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn @@ -1,3 +1,10 @@ +import("//llvm/utils/TableGen/tablegen.gni") + +tablegen("CodeGenOptions") { + visibility = [ ":CodeGen" ] + args = [ "-gen-opt-parser-defs" ] +} + static_library("CodeGen") { output_name = "LLVMCodeGen" public_deps = [ @@ -5,6 +12,7 @@ static_library("CodeGen") { "//llvm/include/llvm/Config:llvm-config", ] deps = [ + ":CodeGenOptions", "//llvm/include/llvm/CodeGen:GenVT", "//llvm/lib/Analysis", "//llvm/lib/Bitcode/Reader", @@ -13,6 +21,7 @@ static_library("CodeGen") { "//llvm/lib/CodeGenTypes", "//llvm/lib/IR", "//llvm/lib/MC", + "//llvm/lib/Option", "//llvm/lib/ProfileData", "//llvm/lib/Support", "//llvm/lib/Target", @@ -42,6 +51,7 @@ static_library("CodeGen") { "CallingConvLower.cpp", "CodeGen.cpp", "CodeGenCommonISel.cpp", + "CodeGenOptions.cpp", "CodeGenPrepare.cpp", "CodeGenTargetMachineImpl.cpp", "CommandFlags.cpp", diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel index df9cbbf9a29ae1..826ac64b62006a 100644 --- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel @@ -2454,6 +2454,15 @@ cc_library( ], ) +gentbl_cc_library( + name = "CodeGenOptionsTableGen", + strip_include_prefix = "lib/CodeGen", + tbl_outs = {"lib/CodeGen/CodeGenOptions.inc": ["-gen-opt-parser-defs"]}, + tblgen = ":llvm-min-tblgen", + td_file = "lib/CodeGen/CodeGenOptions.td", + deps = [":OptParserTdFiles"], +) + cc_library( name = "CodeGen", srcs = glob( @@ -2485,6 +2494,7 @@ cc_library( ":BitWriter", ":CFGuard", ":CGData", + ":CodeGenOptionsTableGen", ":CodeGenTypes", ":Core", ":DebugInfoCodeView", @@ -2497,6 +2507,7 @@ cc_library( ":MCParser", ":ObjCARC", ":Object", + ":Option", ":ProfileData", ":Remarks", ":Scalar", _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
