diff options
author | Fangrui Song <i@maskray.me> | 2024-07-05 19:40:33 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2024-07-05 19:40:33 -0700 |
commit | 1b6cc26cc28cedc15e36fbae80fa25a450b242dc (patch) | |
tree | fb06280ec75e270355062e61db5f33d8b30d4817 | |
parent | b75453bc07dabe8e0dc0efb0766a4238e3df6712 (diff) | |
download | llvm-users/MaskRay/spr/-fno-plt-infer-nonlazybind-at-o0.zip llvm-users/MaskRay/spr/-fno-plt-infer-nonlazybind-at-o0.tar.gz llvm-users/MaskRay/spr/-fno-plt-infer-nonlazybind-at-o0.tar.bz2 |
[𝘀𝗽𝗿] initial versionusers/MaskRay/spr/-fno-plt-infer-nonlazybind-at-o0
Created using spr 1.3.5-bogner
-rw-r--r-- | llvm/include/llvm/Transforms/IPO/InferFunctionAttrs.h | 4 | ||||
-rw-r--r-- | llvm/lib/Passes/PassBuilder.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Passes/PassBuilderPipelines.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Passes/PassRegistry.def | 5 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp | 16 | ||||
-rw-r--r-- | llvm/test/Other/new-pass-manager.ll | 1 | ||||
-rw-r--r-- | llvm/test/Other/new-pm-O0-defaults.ll | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/InferFunctionAttrs/nonlazybind.ll | 57 |
8 files changed, 88 insertions, 3 deletions
diff --git a/llvm/include/llvm/Transforms/IPO/InferFunctionAttrs.h b/llvm/include/llvm/Transforms/IPO/InferFunctionAttrs.h index 8addf49..b0ec158 100644 --- a/llvm/include/llvm/Transforms/IPO/InferFunctionAttrs.h +++ b/llvm/include/llvm/Transforms/IPO/InferFunctionAttrs.h @@ -23,7 +23,11 @@ class Module; /// A pass which infers function attributes from the names and signatures of /// function declarations in a module. struct InferFunctionAttrsPass : PassInfoMixin<InferFunctionAttrsPass> { + InferFunctionAttrsPass(bool O0 = false) : O0(O0) {} PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); + +private: + bool O0; }; } diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 17cc156..c618165 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1145,6 +1145,10 @@ Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) { return Result; } +Expected<bool> parseInferFunctionAttrsOptions(StringRef Params) { + return PassBuilder::parseSinglePassOption(Params, "O0", "InferFunctionAttrs"); +} + Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) { SmallVector<std::string, 1> PreservedGVs; while (!Params.empty()) { diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index 4fd5ee1..b9f9769 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -2080,6 +2080,8 @@ ModulePassManager PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level, if (PGOOpt && PGOOpt->DebugInfoForProfiling) MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); + MPM.addPass(InferFunctionAttrsPass(/*O0=*/true)); + invokePipelineEarlySimplificationEPCallbacks(MPM, Level); // Build a minimal pipeline based on the semantics required by LLVM, diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 3b92823..c411d6d 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -68,7 +68,6 @@ MODULE_PASS("hipstdpar-interpose-alloc", HipStdParAllocationInterpositionPass()) MODULE_PASS("hipstdpar-select-accelerator-code", HipStdParAcceleratorCodeSelectionPass()) MODULE_PASS("hotcoldsplit", HotColdSplittingPass()) -MODULE_PASS("inferattrs", InferFunctionAttrsPass()) MODULE_PASS("inliner-ml-advisor-release", ModuleInlinerWrapperPass(getInlineParams(), true, {}, InliningAdvisorMode::Release, 0)) @@ -177,6 +176,10 @@ MODULE_PASS_WITH_PARAMS( [](HWAddressSanitizerOptions Opts) { return HWAddressSanitizerPass(Opts); }, parseHWASanPassOptions, "kernel;recover") MODULE_PASS_WITH_PARAMS( + "inferattrs", "InferFunctionAttrsPass", + [](bool O0) { return InferFunctionAttrsPass(O0); }, + parseInferFunctionAttrsOptions, "O0") +MODULE_PASS_WITH_PARAMS( "internalize", "InternalizePass", [](SmallVector<std::string, 0> PreservedGVs) { if (PreservedGVs.empty()) diff --git a/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp b/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp index 18d5911..6f26934 100644 --- a/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp @@ -17,8 +17,20 @@ using namespace llvm; #define DEBUG_TYPE "inferattrs" static bool inferAllPrototypeAttributes( - Module &M, function_ref<TargetLibraryInfo &(Function &)> GetTLI) { + Module &M, bool O0, function_ref<TargetLibraryInfo &(Function &)> GetTLI) { bool Changed = false; + // Infer nonlazybind if "RtLibUseGOT" (-fno-plt) is set. This is performed + // even at -O0. + if (M.getRtLibUseGOT()) { + for (Function &F : M.functions()) { + if (F.isDeclaration() && !F.hasFnAttribute(Attribute::NonLazyBind)) { + F.addFnAttr(Attribute::NonLazyBind); + Changed = true; + } + } + } + if (O0) + return Changed; for (Function &F : M.functions()) // We only infer things using the prototype and the name; we don't need @@ -43,7 +55,7 @@ PreservedAnalyses InferFunctionAttrsPass::run(Module &M, return FAM.getResult<TargetLibraryAnalysis>(F); }; - if (!inferAllPrototypeAttributes(M, GetTLI)) + if (!inferAllPrototypeAttributes(M, O0, GetTLI)) // If we didn't infer anything, preserve all analyses. return PreservedAnalyses::all(); diff --git a/llvm/test/Other/new-pass-manager.ll b/llvm/test/Other/new-pass-manager.ll index f0fe708..60040d7 100644 --- a/llvm/test/Other/new-pass-manager.ll +++ b/llvm/test/Other/new-pass-manager.ll @@ -292,6 +292,7 @@ ; RUN: | FileCheck %s --check-prefix=CHECK-O0 --check-prefix=%llvmcheckext ; CHECK-O0: Running analysis: InnerAnalysisManagerProxy<{{.*}}> ; CHECK-O0-NEXT: Running pass: EntryExitInstrumenterPass +; CHECK-O0-NEXT: Running pass: InferFunctionAttrsPass ; CHECK-O0-NEXT: Running pass: AlwaysInlinerPass ; CHECK-O0-NEXT: Running analysis: ProfileSummaryAnalysis ; CHECK-EXT-NEXT: Running pass: {{.*}}Bye diff --git a/llvm/test/Other/new-pm-O0-defaults.ll b/llvm/test/Other/new-pm-O0-defaults.ll index e8131ac..3505061 100644 --- a/llvm/test/Other/new-pm-O0-defaults.ll +++ b/llvm/test/Other/new-pm-O0-defaults.ll @@ -32,10 +32,12 @@ ; CHECK-DIS: Running analysis: InnerAnalysisManagerProxy ; CHECK-DIS-NEXT: Running pass: EntryExitInstrumenterPass ; CHECK-DIS-NEXT: Running pass: AddDiscriminatorsPass +; CHECK-DIS-NEXT: Running pass: InferFunctionAttrsPass ; CHECK-DIS-NEXT: Running pass: AlwaysInlinerPass ; CHECK-DIS-NEXT: Running analysis: ProfileSummaryAnalysis ; CHECK-DEFAULT: Running analysis: InnerAnalysisManagerProxy ; CHECK-DEFAULT-NEXT: Running pass: EntryExitInstrumenterPass +; CHECK-DEFAULT-NEXT: Running pass: InferFunctionAttrsPass ; CHECK-DEFAULT-NEXT: Running pass: AlwaysInlinerPass ; CHECK-DEFAULT-NEXT: Running analysis: ProfileSummaryAnalysis ; CHECK-MATRIX: Running pass: LowerMatrixIntrinsicsPass diff --git a/llvm/test/Transforms/InferFunctionAttrs/nonlazybind.ll b/llvm/test/Transforms/InferFunctionAttrs/nonlazybind.ll new file mode 100644 index 0000000..4a401ab --- /dev/null +++ b/llvm/test/Transforms/InferFunctionAttrs/nonlazybind.ll @@ -0,0 +1,57 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5 +; RUN: opt < %s -S -passes='inferattrs<O0>' | FileCheck %s --check-prefix=O0 +; RUN: opt < %s -S -passes='inferattrs' | FileCheck %s --check-prefix=CHECK + +%struct.A = type { i8 } + +@a = dso_local global %struct.A zeroinitializer, align 1 +@__dso_handle = external hidden global i8 +@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I_, ptr null }] + +declare void @external() +declare void @external_optnone() noinline optnone +declare void @_ZN1AD1Ev(ptr noundef nonnull align 1 dereferenceable(1)) unnamed_addr +declare i32 @__cxa_atexit(ptr, ptr, ptr) + +;. +; O0: @a = dso_local global %struct.A zeroinitializer, align 1 +; O0: @__dso_handle = external hidden global i8 +; O0: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I_, ptr null }] +;. +; CHECK: @a = dso_local global %struct.A zeroinitializer, align 1 +; CHECK: @__dso_handle = external hidden global i8 +; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I_, ptr null }] +;. +define internal void @_GLOBAL__sub_I_() section ".text.startup" { +; O0-LABEL: define internal void @_GLOBAL__sub_I_() section ".text.startup" { +; O0-NEXT: call void @external() +; O0-NEXT: call void @external_optnone() +; O0-NEXT: [[TMP0:%.*]] = tail call i32 @__cxa_atexit(ptr nonnull @_ZN1AD1Ev, ptr nonnull @a, ptr nonnull @__dso_handle) +; O0-NEXT: ret void +; +; CHECK-LABEL: define internal void @_GLOBAL__sub_I_() section ".text.startup" { +; CHECK-NEXT: call void @external() +; CHECK-NEXT: call void @external_optnone() +; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @__cxa_atexit(ptr nonnull @_ZN1AD1Ev, ptr nonnull @a, ptr nonnull @__dso_handle) +; CHECK-NEXT: ret void +; + call void @external() + call void @external_optnone() + %x = tail call i32 @__cxa_atexit(ptr nonnull @_ZN1AD1Ev, ptr nonnull @a, ptr nonnull @__dso_handle) + ret void +} + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"RtLibUseGOT", i32 1} +;. +; O0: attributes #[[ATTR0:[0-9]+]] = { nonlazybind } +; O0: attributes #[[ATTR1:[0-9]+]] = { noinline nonlazybind optnone } +;. +; CHECK: attributes #[[ATTR0:[0-9]+]] = { nonlazybind } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { noinline nonlazybind optnone } +; CHECK: attributes #[[ATTR2:[0-9]+]] = { nofree nonlazybind } +;. +; O0: [[META0:![0-9]+]] = !{i32 7, !"RtLibUseGOT", i32 1} +;. +; CHECK: [[META0:![0-9]+]] = !{i32 7, !"RtLibUseGOT", i32 1} +;. |