[llvm] [MachineOutliner] Remove LOHs from outlined candidates (PR #143617)
Ellis Hoag via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 12 16:27:07 PDT 2025
https://github.com/ellishg updated https://github.com/llvm/llvm-project/pull/143617
>From 30acec2164a34bbb9a8d6cf12ffd52efe480dbc4 Mon Sep 17 00:00:00 2001
From: Ellis Hoag <ellishoag at meta.com>
Date: Tue, 10 Jun 2025 10:34:35 -0700
Subject: [PATCH 1/4] [LOH] Remove hints when outlining
---
llvm/include/llvm/CodeGen/TargetInstrInfo.h | 6 ++
llvm/lib/CodeGen/MachineOutliner.cpp | 18 ++++++
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 16 ++---
llvm/lib/Target/AArch64/AArch64InstrInfo.h | 1 +
.../AArch64/AArch64MachineFunctionInfo.h | 13 ++++
.../CodeGen/AArch64/machine-outliner-loh.ll | 63 +++++++++++++++++++
6 files changed, 110 insertions(+), 7 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/machine-outliner-loh.ll
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index b5b83c7ff1164..3aec8791b7957 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -2184,6 +2184,12 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
MachineBasicBlock::iterator &MIT,
unsigned Flags) const;
+ /// Remove all Linker Optimization Hints associated with instructions in
+ // \p MIs and \return the number of hints removed.
+ virtual size_t clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) const {
+ return 0;
+ }
+
/// Optional target hook that returns true if \p MBB is safe to outline from,
/// and returns any target-specific information in \p Flags.
virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index e48612369a5db..02a08e4d50818 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -104,6 +104,7 @@ STATISTIC(StableHashAttempts,
"Count of hashing attempts made for outlined functions");
STATISTIC(StableHashDropped,
"Count of unsuccessful hashing attempts for outlined functions");
+STATISTIC(NumRemovedLOHs, "Total number of Linker Optimization Hints removed");
// Set to true if the user wants the outliner to run on linkonceodr linkage
// functions. This is false by default because the linker can dedupe linkonceodr
@@ -1075,6 +1076,23 @@ bool MachineOutliner::outline(
<< " B) > threshold (" << OutlinerBenefitThreshold
<< " B)\n");
+ // Remove all Linker Optimization Hints from the candidates since we did not
+ // check if the set of hints are the same for each of them.
+ // TODO: The intersection of the LOHs from all candidates should be legal in
+ // the outlined function.
+ SmallPtrSet<MachineInstr *, 2> MIs;
+ std::optional<size_t> MinRemovedLOHs;
+ for (Candidate &C : OF->Candidates) {
+ const TargetInstrInfo &TII = *C.getMF()->getSubtarget().getInstrInfo();
+ for (MachineInstr &MI : C)
+ MIs.insert(&MI);
+ size_t NumRemoved = TII.clearLOHs(MIs);
+ MIs.clear();
+ MinRemovedLOHs =
+ std::min(MinRemovedLOHs.value_or(NumRemoved), NumRemoved);
+ }
+ NumRemovedLOHs += MinRemovedLOHs.value_or(0);
+
// It's beneficial. Create the function and outline its sequence's
// occurrences.
OF->MF = createOutlinedFunction(M, *OF, Mapper, OutlinedFunctionNum);
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 951cb93ea8f8c..ea04bd4cf2428 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -9641,14 +9641,20 @@ AArch64InstrInfo::getOutlinableRanges(MachineBasicBlock &MBB,
return Ranges;
}
+size_t
+AArch64InstrInfo::clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) const {
+ if (MIs.empty())
+ return 0;
+ auto *MI = *MIs.begin();
+ auto *FuncInfo = MI->getMF()->getInfo<AArch64FunctionInfo>();
+ return FuncInfo->clearLOHs(MIs);
+}
+
outliner::InstrType
AArch64InstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI,
MachineBasicBlock::iterator &MIT,
unsigned Flags) const {
MachineInstr &MI = *MIT;
- MachineBasicBlock *MBB = MI.getParent();
- MachineFunction *MF = MBB->getParent();
- AArch64FunctionInfo *FuncInfo = MF->getInfo<AArch64FunctionInfo>();
// Don't outline anything used for return address signing. The outlined
// function will get signed later if needed
@@ -9676,10 +9682,6 @@ AArch64InstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI,
return outliner::InstrType::Illegal;
}
- // Don't outline LOHs.
- if (FuncInfo->getLOHRelated().count(&MI))
- return outliner::InstrType::Illegal;
-
// We can only outline these if we will tail call the outlined function, or
// fix up the CFI offsets. Currently, CFI instructions are outlined only if
// in a tail call.
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index 7c255da333e4b..45817e85e3826 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -493,6 +493,7 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI,
MachineBasicBlock::iterator &MIT,
unsigned Flags) const override;
+ size_t clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) const override;
SmallVector<
std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
getOutlinableRanges(MachineBasicBlock &MBB, unsigned &Flags) const override;
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
index 361d5ec3f2b22..0c0217cf4fa3f 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
@@ -504,6 +504,19 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
LOHRelated.insert_range(Args);
}
+ size_t clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) {
+ size_t InitialSize = LOHContainerSet.size();
+ erase_if(LOHContainerSet, [&](const auto &D) {
+ return any_of(D.getArgs(), [&](auto *Arg) { return MIs.contains(Arg); });
+ });
+ // In theory there could be an LOH with one label in MIs and another label
+ // outside MIs, however we don't know if the label outside MIs is used in
+ // any other LOHs, so we can't remove them from LOHRelated. In that case, we
+ // might produce a few extra labels, but it won't break anything.
+ LOHRelated.remove_if([&](auto *MI) { return MIs.contains(MI); });
+ return InitialSize - LOHContainerSet.size();
+ };
+
SmallVectorImpl<ForwardedRegister> &getForwardedMustTailRegParms() {
return ForwardedMustTailRegParms;
}
diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-loh.ll b/llvm/test/CodeGen/AArch64/machine-outliner-loh.ll
new file mode 100644
index 0000000000000..66914d70c23f9
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/machine-outliner-loh.ll
@@ -0,0 +1,63 @@
+; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-darwin < %s | FileCheck %s --implicit-check-not=.loh --check-prefixes=CHECK,LOH
+; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-darwin -enable-machine-outliner < %s | FileCheck %s --implicit-check-not=.loh --check-prefixes=CHECK,OUTLINE
+
+ at A = global i32 0, align 4
+ at B = global i32 0, align 4
+
+declare void @foo();
+declare void @bar(ptr %a);
+declare void @goo(ptr %a);
+
+; CHECK-LABEL: _a0:
+define i32 @a0(i32 %a) {
+ %addr = getelementptr inbounds i32, ptr @A, i32 0
+ %res = load i32, ptr %addr, align 4
+ ; LOH: [[L0:Lloh.+]]:
+ ; LOH-NEXT: adrp x19, _A at PAGE
+ ; LOH-NEXT: [[L1:Lloh.+]]:
+ ; LOH-NEXT: add x19, x19, _A at PAGEOFF
+ call void @foo()
+ ; OUTLINE: bl _OUTLINED_FUNCTION_0
+ ; OUTLINE-NEXT: mov x0, x19
+ ; OUTLINE-NEXT: bl _bar
+ call void @bar(ptr %addr)
+ %addr2 = getelementptr inbounds i32, ptr @B, i32 4
+ store i32 0, ptr %addr2, align 4
+ ; CHECK: [[L2:Lloh.+]]:
+ ; CHECK-NEXT: adrp x8, _B at PAGE
+ ; CHECK-NEXT: [[L3:Lloh.+]]:
+ ; CHECK-NEXT: add x8, x8, _B at PAGEOFF
+ ; CHECK-NEXT: mov w0, w20
+ ; CHECK-NEXT: [[L4:Lloh.+]]:
+ ; CHECK-NEXT: str wzr, [x8, #16]
+ ret i32 %res
+ ; LOH-DAG: .loh AdrpAdd [[L0]], [[L1]]
+ ; CHECK-DAG: .loh AdrpAddStr [[L2]], [[L3]], [[L4]]
+ ; CHECK: .cfi_endproc
+}
+
+; CHECK-LABEL: _a1:
+define i32 @a1(i32 %a) {
+ %addr = getelementptr inbounds i32, ptr @A, i32 0
+ %res = load i32, ptr %addr, align 4
+ ; LOH: [[L5:Lloh.+]]:
+ ; LOH-NEXT: adrp x19, _A at PAGE
+ ; LOH-NEXT: [[L6:Lloh.+]]:
+ ; LOH-NEXT: add x19, x19, _A at PAGEOFF
+ call void @foo()
+ ; OUTLINE: bl _OUTLINED_FUNCTION_0
+ ; OUTLINE-NEXT: mov x0, x19
+ ; OUTLINE-NEXT: bl _goo
+ call void @goo(ptr %addr)
+ ret i32 %res
+ ; LOH: .loh AdrpAdd [[L5]], [[L6]]
+ ; CHECK: .cfi_endproc
+}
+
+; Note: it is not safe to add LOHs to this function as outlined functions do not
+; follow calling convention and thus x19 could be live across the call.
+; OUTLINE: _OUTLINED_FUNCTION_0:
+; OUTLINE: adrp x19, _A at PAGE
+; OUTLINE: add x19, x19, _A at PAGEOFF
+; OUTLINE: ldr w20, [x19]
+; OUTLINE: b _foo
>From 09aeee933db51e1176a8f3f36cd781aac1c8d4c6 Mon Sep 17 00:00:00 2001
From: Ellis Hoag <ellishoag at meta.com>
Date: Wed, 11 Jun 2025 10:11:10 -0700
Subject: [PATCH 2/4] rename func
---
llvm/include/llvm/CodeGen/TargetInstrInfo.h | 9 ++++++---
llvm/lib/CodeGen/MachineOutliner.cpp | 2 +-
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 6 +++---
llvm/lib/Target/AArch64/AArch64InstrInfo.h | 3 ++-
llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h | 3 ++-
5 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 3aec8791b7957..d32578540f207 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -2184,9 +2184,12 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
MachineBasicBlock::iterator &MIT,
unsigned Flags) const;
- /// Remove all Linker Optimization Hints associated with instructions in
- // \p MIs and \return the number of hints removed.
- virtual size_t clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) const {
+ /// Remove all Linker Optimization Hints (LOH) associated with instructions in
+ /// \p MIs and \return the number of hints removed. This is useful in
+ /// transformations that cause these hints to be illegal, like in the machine
+ /// outliner.
+ virtual size_t clearLinkerOptimizationHints(
+ const SmallPtrSetImpl<MachineInstr *> &MIs) const {
return 0;
}
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index 02a08e4d50818..9934482673b4a 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -1086,7 +1086,7 @@ bool MachineOutliner::outline(
const TargetInstrInfo &TII = *C.getMF()->getSubtarget().getInstrInfo();
for (MachineInstr &MI : C)
MIs.insert(&MI);
- size_t NumRemoved = TII.clearLOHs(MIs);
+ size_t NumRemoved = TII.clearLinkerOptimizationHints(MIs);
MIs.clear();
MinRemovedLOHs =
std::min(MinRemovedLOHs.value_or(NumRemoved), NumRemoved);
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index ea04bd4cf2428..c3e23a1bdecc8 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -9641,13 +9641,13 @@ AArch64InstrInfo::getOutlinableRanges(MachineBasicBlock &MBB,
return Ranges;
}
-size_t
-AArch64InstrInfo::clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) const {
+size_t AArch64InstrInfo::clearLinkerOptimizationHints(
+ const SmallPtrSetImpl<MachineInstr *> &MIs) const {
if (MIs.empty())
return 0;
auto *MI = *MIs.begin();
auto *FuncInfo = MI->getMF()->getInfo<AArch64FunctionInfo>();
- return FuncInfo->clearLOHs(MIs);
+ return FuncInfo->clearLinkerOptimizationHints(MIs);
}
outliner::InstrType
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index 45817e85e3826..34882c96c4497 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -493,7 +493,8 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI,
MachineBasicBlock::iterator &MIT,
unsigned Flags) const override;
- size_t clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) const override;
+ size_t clearLinkerOptimizationHints(
+ const SmallPtrSetImpl<MachineInstr *> &MIs) const override;
SmallVector<
std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
getOutlinableRanges(MachineBasicBlock &MBB, unsigned &Flags) const override;
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
index 0c0217cf4fa3f..e61f2280865b4 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
@@ -504,7 +504,8 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
LOHRelated.insert_range(Args);
}
- size_t clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) {
+ size_t
+ clearLinkerOptimizationHints(const SmallPtrSetImpl<MachineInstr *> &MIs) {
size_t InitialSize = LOHContainerSet.size();
erase_if(LOHContainerSet, [&](const auto &D) {
return any_of(D.getArgs(), [&](auto *Arg) { return MIs.contains(Arg); });
>From c109081af20934e2bc115ffdc06568eefecb8f87 Mon Sep 17 00:00:00 2001
From: Ellis Hoag <ellishoag at meta.com>
Date: Wed, 11 Jun 2025 14:17:30 -0700
Subject: [PATCH 3/4] add mir test
---
llvm/lib/CodeGen/MachineOutliner.cpp | 9 +---
.../CodeGen/AArch64/machine-outliner-loh.mir | 50 +++++++++++++++++++
2 files changed, 52 insertions(+), 7 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/machine-outliner-loh.mir
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index 9934482673b4a..da73bd376bbe2 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -1076,22 +1076,17 @@ bool MachineOutliner::outline(
<< " B) > threshold (" << OutlinerBenefitThreshold
<< " B)\n");
- // Remove all Linker Optimization Hints from the candidates since we did not
- // check if the set of hints are the same for each of them.
+ // Remove all Linker Optimization Hints from the candidates.
// TODO: The intersection of the LOHs from all candidates should be legal in
// the outlined function.
SmallPtrSet<MachineInstr *, 2> MIs;
- std::optional<size_t> MinRemovedLOHs;
for (Candidate &C : OF->Candidates) {
const TargetInstrInfo &TII = *C.getMF()->getSubtarget().getInstrInfo();
for (MachineInstr &MI : C)
MIs.insert(&MI);
- size_t NumRemoved = TII.clearLinkerOptimizationHints(MIs);
+ NumRemovedLOHs += TII.clearLinkerOptimizationHints(MIs);
MIs.clear();
- MinRemovedLOHs =
- std::min(MinRemovedLOHs.value_or(NumRemoved), NumRemoved);
}
- NumRemovedLOHs += MinRemovedLOHs.value_or(0);
// It's beneficial. Create the function and outline its sequence's
// occurrences.
diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-loh.mir b/llvm/test/CodeGen/AArch64/machine-outliner-loh.mir
new file mode 100644
index 0000000000000..c613e316f828f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/machine-outliner-loh.mir
@@ -0,0 +1,50 @@
+# RUN: llc %s -mtriple=aarch64-apple-ios -run-pass=aarch64-collect-loh -run-pass=machine-outliner -stats -o - 2>%t | FileCheck %s
+# RUN: FileCheck %s --input-file=%t --check-prefix=STATS
+# REQUIRES: asserts
+
+--- |
+ define void @func0() noredzone minsize { ret void }
+
+ @g0 = external global i32
+...
+---
+# CHECK-LABEL: name: func0
+name: func0
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: bb.0:
+ bb.0:
+ ; CHECK: BL @OUTLINED_FUNCTION_0
+ $x10 = ADRP target-flags(aarch64-page) @g0
+ $x11 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0
+ $w0 = ORRWri $wzr, 1
+ $w0 = ORRWri $wzr, 1
+ $w0 = ORRWri $wzr, 1
+ $w0 = ORRWri $wzr, 1
+
+ ; CHECK-LABEL: bb.1:
+ bb.1:
+ ; CHECK: BL @OUTLINED_FUNCTION_0
+ ; MCLOH_AdrpAdd is not generated because $x11 is still live. If we want to
+ ; outline these instructions, we must remove the MCLOH_AdrpAdd from bb.0.
+ $x10 = ADRP target-flags(aarch64-page) @g0
+ $x11 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0
+ $w0 = ORRWri $wzr, 1
+ $w0 = ORRWri $wzr, 1
+ $w0 = ORRWri $wzr, 1
+ $w0 = ORRWri $wzr, 1
+ ; CHECK: $x12 = ADDXri $x11, target-flags(aarch64-pageoff) @g0, 0
+ $x12 = ADDXri $x11, target-flags(aarch64-pageoff) @g0, 0
+
+...
+
+# CHECK-LABEL: name: OUTLINED_FUNCTION_0
+# CHECK: $x10 = ADRP target-flags(aarch64-page) @g0
+# CHECK: $x11 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0
+# CHECK: $w0 = ORRWri $wzr, 1
+# CHECK: $w0 = ORRWri $wzr, 1
+# CHECK: $w0 = ORRWri $wzr, 1
+# CHECK: $w0 = ORRWri $wzr, 1
+
+# STATS: 1 aarch64-collect-loh - Number of simplifiable ADRP + ADD
+# STATS: 1 machine-outliner - Total number of Linker Optimization Hints removed
>From e62480b9d6ef165ae696fd9e148cd9b54df6ccbe Mon Sep 17 00:00:00 2001
From: Ellis Hoag <ellishoag at meta.com>
Date: Thu, 12 Jun 2025 16:26:54 -0700
Subject: [PATCH 4/4] Use TargetMachine
---
llvm/include/llvm/CodeGen/TargetInstrInfo.h | 9 ---------
llvm/include/llvm/Target/TargetMachine.h | 10 ++++++++++
llvm/lib/CodeGen/MachineOutliner.cpp | 8 ++++++--
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 9 ---------
llvm/lib/Target/AArch64/AArch64InstrInfo.h | 2 --
llvm/lib/Target/AArch64/AArch64TargetMachine.cpp | 9 +++++++++
llvm/lib/Target/AArch64/AArch64TargetMachine.h | 3 +++
7 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index d32578540f207..b5b83c7ff1164 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -2184,15 +2184,6 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
MachineBasicBlock::iterator &MIT,
unsigned Flags) const;
- /// Remove all Linker Optimization Hints (LOH) associated with instructions in
- /// \p MIs and \return the number of hints removed. This is useful in
- /// transformations that cause these hints to be illegal, like in the machine
- /// outliner.
- virtual size_t clearLinkerOptimizationHints(
- const SmallPtrSetImpl<MachineInstr *> &MIs) const {
- return 0;
- }
-
/// Optional target hook that returns true if \p MBB is safe to outline from,
/// and returns any target-specific information in \p Flags.
virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index 906926729ed74..a2d5409fdf50b 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -37,6 +37,7 @@ using ModulePassManager = PassManager<Module>;
class Function;
class GlobalValue;
+class MachineInstr;
class MachineModuleInfoWrapperPass;
struct MachineSchedContext;
class Mangler;
@@ -518,6 +519,15 @@ class TargetMachine {
// MachineRegisterInfo callback function
virtual void registerMachineRegisterInfoCallback(MachineFunction &MF) const {}
+
+ /// Remove all Linker Optimization Hints (LOH) associated with instructions in
+ /// \p MIs and \return the number of hints removed. This is useful in
+ /// transformations that cause these hints to be illegal, like in the machine
+ /// outliner.
+ virtual size_t clearLinkerOptimizationHints(
+ const SmallPtrSetImpl<MachineInstr *> &MIs) const {
+ return 0;
+ }
};
} // end namespace llvm
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index da73bd376bbe2..b0bce2c21a470 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -67,6 +67,7 @@
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/IRBuilder.h"
@@ -77,6 +78,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/SuffixTree.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <tuple>
#include <vector>
@@ -427,6 +429,7 @@ struct MachineOutliner : public ModulePass {
static char ID;
MachineModuleInfo *MMI = nullptr;
+ const TargetMachine *TM = nullptr;
/// Set to true if the outliner should consider functions with
/// linkonceodr linkage.
@@ -462,6 +465,7 @@ struct MachineOutliner : public ModulePass {
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<MachineModuleInfoWrapperPass>();
+ AU.addRequired<TargetPassConfig>();
AU.addPreserved<MachineModuleInfoWrapperPass>();
AU.addUsedIfAvailable<ImmutableModuleSummaryIndexWrapperPass>();
AU.setPreservesAll();
@@ -1081,10 +1085,9 @@ bool MachineOutliner::outline(
// the outlined function.
SmallPtrSet<MachineInstr *, 2> MIs;
for (Candidate &C : OF->Candidates) {
- const TargetInstrInfo &TII = *C.getMF()->getSubtarget().getInstrInfo();
for (MachineInstr &MI : C)
MIs.insert(&MI);
- NumRemovedLOHs += TII.clearLinkerOptimizationHints(MIs);
+ NumRemovedLOHs += TM->clearLinkerOptimizationHints(MIs);
MIs.clear();
}
@@ -1399,6 +1402,7 @@ bool MachineOutliner::runOnModule(Module &M) {
initializeOutlinerMode(M);
MMI = &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
+ TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
// Number to append to the current outlined function.
unsigned OutlinedFunctionNum = 0;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index c3e23a1bdecc8..ea57ea8873d40 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -9641,15 +9641,6 @@ AArch64InstrInfo::getOutlinableRanges(MachineBasicBlock &MBB,
return Ranges;
}
-size_t AArch64InstrInfo::clearLinkerOptimizationHints(
- const SmallPtrSetImpl<MachineInstr *> &MIs) const {
- if (MIs.empty())
- return 0;
- auto *MI = *MIs.begin();
- auto *FuncInfo = MI->getMF()->getInfo<AArch64FunctionInfo>();
- return FuncInfo->clearLinkerOptimizationHints(MIs);
-}
-
outliner::InstrType
AArch64InstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI,
MachineBasicBlock::iterator &MIT,
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index 34882c96c4497..7c255da333e4b 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -493,8 +493,6 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI,
MachineBasicBlock::iterator &MIT,
unsigned Flags) const override;
- size_t clearLinkerOptimizationHints(
- const SmallPtrSetImpl<MachineInstr *> &MIs) const override;
SmallVector<
std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
getOutlinableRanges(MachineBasicBlock &MBB, unsigned &Flags) const override;
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index 50f52cca6c8ac..a9c9c450976d4 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -509,6 +509,15 @@ AArch64TargetMachine::createPostMachineScheduler(MachineSchedContext *C) const {
return DAG;
}
+size_t AArch64TargetMachine::clearLinkerOptimizationHints(
+ const SmallPtrSetImpl<MachineInstr *> &MIs) const {
+ if (MIs.empty())
+ return 0;
+ auto *MI = *MIs.begin();
+ auto *FuncInfo = MI->getMF()->getInfo<AArch64FunctionInfo>();
+ return FuncInfo->clearLinkerOptimizationHints(MIs);
+}
+
void AArch64leTargetMachine::anchor() { }
AArch64leTargetMachine::AArch64leTargetMachine(
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.h b/llvm/lib/Target/AArch64/AArch64TargetMachine.h
index f8ba41f215430..b9e522dd6f226 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.h
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.h
@@ -76,6 +76,9 @@ class AArch64TargetMachine : public CodeGenTargetMachineImpl {
ScheduleDAGInstrs *
createPostMachineScheduler(MachineSchedContext *C) const override;
+ size_t clearLinkerOptimizationHints(
+ const SmallPtrSetImpl<MachineInstr *> &MIs) const override;
+
private:
bool isLittle;
};
More information about the llvm-commits
mailing list