llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-driver Author: Anton Bikineev (AntonBikineev) <details> <summary>Changes</summary> This patch enables machine function splitting for Mach-O targets on x86 and AArch64. 1. Driver: Allow -fsplit-machine-functions for Mach-O triples. 2. ObjectFile: Implement getSectionForMachineBasicBlock for Mach-O to place cold blocks into the __TEXT,__text_cold section. 3. AArch64: Relax isFunctionSafeToSplit for Mach-O targets as they typically do not use a red zone and branch relaxation is handled by the linker. Added backend test to verify the implementation. Driver test was omitted due to environment issues with llvm-profdata. --- Full diff: https://github.com/llvm/llvm-project/pull/179449.diff 6 Files Affected: - (modified) clang/include/clang/Options/Options.td (+1-1) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+3-2) - (modified) llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h (+5) - (modified) llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (+15) - (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.cpp (+2-1) - (added) llvm/test/CodeGen/AArch64/split-machine-functions-macho.ll (+31) ``````````diff diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 5ecb516c2cf68..2137d5c22065e 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -4704,7 +4704,7 @@ defm split_machine_functions: BoolFOption<"split-machine-functions", CodeGenOpts<"SplitMachineFunctions">, DefaultFalse, PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">, NegFlag<SetFalse, [], [ClangOption], "Disable">, - BothFlags<[], [ClangOption], " late function splitting using profile information (x86 and aarch64 ELF)">>; + BothFlags<[], [ClangOption], " late function splitting using profile information (x86 and aarch64 ELF/Mach-O)">>; defm partition_static_data_sections: BoolFOption<"partition-static-data-sections", CodeGenOpts<"PartitionStaticDataSections">, DefaultFalse, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0293b04217673..d0348f96a7ff2 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6237,8 +6237,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *A = Args.getLastArg(options::OPT_fsplit_machine_functions, options::OPT_fno_split_machine_functions)) { if (!A->getOption().matches(options::OPT_fno_split_machine_functions)) { - // This codegen pass is only available on x86 and AArch64 ELF targets. - if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF()) + // This codegen pass is only available on x86 and AArch64 ELF and Mach-O targets. + if ((Triple.isX86() || Triple.isAArch64()) && + (Triple.isOSBinFormatELF() || Triple.isOSBinFormatMachO())) A->render(Args, CmdArgs); else D.Diag(diag::err_drv_unsupported_opt_for_target) diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 9f271dd502b24..9a0dbc2d90360 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -178,6 +178,11 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { const TargetMachine &TM) const override; MCSection *getSectionForCommandLines() const override; + + MCSection * + getSectionForMachineBasicBlock(const Function &F, + const MachineBasicBlock &MBB, + const TargetMachine &TM) const override; }; class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index fac0a17d4c0da..f6651a977a3fb 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1493,6 +1493,21 @@ MCSection *TargetLoweringObjectFileMachO::getSectionForCommandLines() const { SectionKind::getReadOnly()); } +MCSection *TargetLoweringObjectFileMachO::getSectionForMachineBasicBlock( + const Function &F, const MachineBasicBlock &MBB, + const TargetMachine &TM) const { + assert(MBB.isBeginSection() && "Basic block does not start a section!"); + + if (MBB.getSectionID() == MBBSectionID::ColdSectionID) { + return getContext().getMachOSection("__TEXT", "__text_cold", + MachO::S_REGULAR | + MachO::S_ATTR_PURE_INSTRUCTIONS, + SectionKind::getText()); + } + + return TargetLoweringObjectFile::getSectionForMachineBasicBlock(F, MBB, TM); +} + const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, MachineModuleInfo *MMI, MCStreamer &Streamer) const { diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 1775e3de8c8c5..ff952d2c4c99c 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -11105,7 +11105,8 @@ bool AArch64InstrInfo::isFunctionSafeToSplit(const MachineFunction &MF) const { // a red zone. This is because relaxing a cross-section branch may require // incrementing the stack pointer to spill a register, which would overwrite // the red zone. - if (MF.getInfo<AArch64FunctionInfo>()->hasRedZone().value_or(true)) + if (MF.getInfo<AArch64FunctionInfo>()->hasRedZone().value_or( + !MF.getSubtarget<AArch64Subtarget>().isTargetMachO())) return false; return TargetInstrInfo::isFunctionSafeToSplit(MF); diff --git a/llvm/test/CodeGen/AArch64/split-machine-functions-macho.ll b/llvm/test/CodeGen/AArch64/split-machine-functions-macho.ll new file mode 100644 index 0000000000000..0dcea60f158cf --- /dev/null +++ b/llvm/test/CodeGen/AArch64/split-machine-functions-macho.ll @@ -0,0 +1,31 @@ +; RUN: llc < %s -mtriple=arm64-apple-macos -split-machine-functions | FileCheck %s + +define void @foo(i1 %cond) !prof !0 { +entry: + br i1 %cond, label %hot, label %cold, !prof !1 +hot: + call void @bar() + ret void +cold: + call void @baz() + ret void +} + +declare void @bar() +declare void @baz() + +!0 = !{!"function_entry_count", i64 1000} +!1 = !{!"branch_weights", i32 1000, i32 0} + +; CHECK: .section __TEXT,__text,regular,pure_instructions +; CHECK: _foo: +; CHECK: tbz w0, #0, [[TRAMPOLINE:LBB0_[0-9]+]] +; CHECK: bl _bar +; CHECK: ret +; CHECK: [[TRAMPOLINE]]: +; CHECK: b foo.cold + +; CHECK: .section __TEXT,__text_cold,regular,pure_instructions +; CHECK: foo.cold: +; CHECK: bl _baz +; CHECK: ret `````````` </details> https://github.com/llvm/llvm-project/pull/179449 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
