Skip to content

Commit 30acec2

Browse files
committed
[LOH] Remove hints when outlining
1 parent 8957e64 commit 30acec2

File tree

6 files changed

+110
-7
lines changed

6 files changed

+110
-7
lines changed

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,6 +2184,12 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
21842184
MachineBasicBlock::iterator &MIT,
21852185
unsigned Flags) const;
21862186

2187+
/// Remove all Linker Optimization Hints associated with instructions in
2188+
// \p MIs and \return the number of hints removed.
2189+
virtual size_t clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) const {
2190+
return 0;
2191+
}
2192+
21872193
/// Optional target hook that returns true if \p MBB is safe to outline from,
21882194
/// and returns any target-specific information in \p Flags.
21892195
virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,

llvm/lib/CodeGen/MachineOutliner.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ STATISTIC(StableHashAttempts,
104104
"Count of hashing attempts made for outlined functions");
105105
STATISTIC(StableHashDropped,
106106
"Count of unsuccessful hashing attempts for outlined functions");
107+
STATISTIC(NumRemovedLOHs, "Total number of Linker Optimization Hints removed");
107108

108109
// Set to true if the user wants the outliner to run on linkonceodr linkage
109110
// functions. This is false by default because the linker can dedupe linkonceodr
@@ -1075,6 +1076,23 @@ bool MachineOutliner::outline(
10751076
<< " B) > threshold (" << OutlinerBenefitThreshold
10761077
<< " B)\n");
10771078

1079+
// Remove all Linker Optimization Hints from the candidates since we did not
1080+
// check if the set of hints are the same for each of them.
1081+
// TODO: The intersection of the LOHs from all candidates should be legal in
1082+
// the outlined function.
1083+
SmallPtrSet<MachineInstr *, 2> MIs;
1084+
std::optional<size_t> MinRemovedLOHs;
1085+
for (Candidate &C : OF->Candidates) {
1086+
const TargetInstrInfo &TII = *C.getMF()->getSubtarget().getInstrInfo();
1087+
for (MachineInstr &MI : C)
1088+
MIs.insert(&MI);
1089+
size_t NumRemoved = TII.clearLOHs(MIs);
1090+
MIs.clear();
1091+
MinRemovedLOHs =
1092+
std::min(MinRemovedLOHs.value_or(NumRemoved), NumRemoved);
1093+
}
1094+
NumRemovedLOHs += MinRemovedLOHs.value_or(0);
1095+
10781096
// It's beneficial. Create the function and outline its sequence's
10791097
// occurrences.
10801098
OF->MF = createOutlinedFunction(M, *OF, Mapper, OutlinedFunctionNum);

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9641,14 +9641,20 @@ AArch64InstrInfo::getOutlinableRanges(MachineBasicBlock &MBB,
96419641
return Ranges;
96429642
}
96439643

9644+
size_t
9645+
AArch64InstrInfo::clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) const {
9646+
if (MIs.empty())
9647+
return 0;
9648+
auto *MI = *MIs.begin();
9649+
auto *FuncInfo = MI->getMF()->getInfo<AArch64FunctionInfo>();
9650+
return FuncInfo->clearLOHs(MIs);
9651+
}
9652+
96449653
outliner::InstrType
96459654
AArch64InstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI,
96469655
MachineBasicBlock::iterator &MIT,
96479656
unsigned Flags) const {
96489657
MachineInstr &MI = *MIT;
9649-
MachineBasicBlock *MBB = MI.getParent();
9650-
MachineFunction *MF = MBB->getParent();
9651-
AArch64FunctionInfo *FuncInfo = MF->getInfo<AArch64FunctionInfo>();
96529658

96539659
// Don't outline anything used for return address signing. The outlined
96549660
// function will get signed later if needed
@@ -9676,10 +9682,6 @@ AArch64InstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI,
96769682
return outliner::InstrType::Illegal;
96779683
}
96789684

9679-
// Don't outline LOHs.
9680-
if (FuncInfo->getLOHRelated().count(&MI))
9681-
return outliner::InstrType::Illegal;
9682-
96839685
// We can only outline these if we will tail call the outlined function, or
96849686
// fix up the CFI offsets. Currently, CFI instructions are outlined only if
96859687
// in a tail call.

llvm/lib/Target/AArch64/AArch64InstrInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
493493
outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI,
494494
MachineBasicBlock::iterator &MIT,
495495
unsigned Flags) const override;
496+
size_t clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) const override;
496497
SmallVector<
497498
std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
498499
getOutlinableRanges(MachineBasicBlock &MBB, unsigned &Flags) const override;

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,19 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
504504
LOHRelated.insert_range(Args);
505505
}
506506

507+
size_t clearLOHs(const SmallPtrSetImpl<MachineInstr *> &MIs) {
508+
size_t InitialSize = LOHContainerSet.size();
509+
erase_if(LOHContainerSet, [&](const auto &D) {
510+
return any_of(D.getArgs(), [&](auto *Arg) { return MIs.contains(Arg); });
511+
});
512+
// In theory there could be an LOH with one label in MIs and another label
513+
// outside MIs, however we don't know if the label outside MIs is used in
514+
// any other LOHs, so we can't remove them from LOHRelated. In that case, we
515+
// might produce a few extra labels, but it won't break anything.
516+
LOHRelated.remove_if([&](auto *MI) { return MIs.contains(MI); });
517+
return InitialSize - LOHContainerSet.size();
518+
};
519+
507520
SmallVectorImpl<ForwardedRegister> &getForwardedMustTailRegParms() {
508521
return ForwardedMustTailRegParms;
509522
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-darwin < %s | FileCheck %s --implicit-check-not=.loh --check-prefixes=CHECK,LOH
2+
; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-darwin -enable-machine-outliner < %s | FileCheck %s --implicit-check-not=.loh --check-prefixes=CHECK,OUTLINE
3+
4+
@A = global i32 0, align 4
5+
@B = global i32 0, align 4
6+
7+
declare void @foo();
8+
declare void @bar(ptr %a);
9+
declare void @goo(ptr %a);
10+
11+
; CHECK-LABEL: _a0:
12+
define i32 @a0(i32 %a) {
13+
%addr = getelementptr inbounds i32, ptr @A, i32 0
14+
%res = load i32, ptr %addr, align 4
15+
; LOH: [[L0:Lloh.+]]:
16+
; LOH-NEXT: adrp x19, _A@PAGE
17+
; LOH-NEXT: [[L1:Lloh.+]]:
18+
; LOH-NEXT: add x19, x19, _A@PAGEOFF
19+
call void @foo()
20+
; OUTLINE: bl _OUTLINED_FUNCTION_0
21+
; OUTLINE-NEXT: mov x0, x19
22+
; OUTLINE-NEXT: bl _bar
23+
call void @bar(ptr %addr)
24+
%addr2 = getelementptr inbounds i32, ptr @B, i32 4
25+
store i32 0, ptr %addr2, align 4
26+
; CHECK: [[L2:Lloh.+]]:
27+
; CHECK-NEXT: adrp x8, _B@PAGE
28+
; CHECK-NEXT: [[L3:Lloh.+]]:
29+
; CHECK-NEXT: add x8, x8, _B@PAGEOFF
30+
; CHECK-NEXT: mov w0, w20
31+
; CHECK-NEXT: [[L4:Lloh.+]]:
32+
; CHECK-NEXT: str wzr, [x8, #16]
33+
ret i32 %res
34+
; LOH-DAG: .loh AdrpAdd [[L0]], [[L1]]
35+
; CHECK-DAG: .loh AdrpAddStr [[L2]], [[L3]], [[L4]]
36+
; CHECK: .cfi_endproc
37+
}
38+
39+
; CHECK-LABEL: _a1:
40+
define i32 @a1(i32 %a) {
41+
%addr = getelementptr inbounds i32, ptr @A, i32 0
42+
%res = load i32, ptr %addr, align 4
43+
; LOH: [[L5:Lloh.+]]:
44+
; LOH-NEXT: adrp x19, _A@PAGE
45+
; LOH-NEXT: [[L6:Lloh.+]]:
46+
; LOH-NEXT: add x19, x19, _A@PAGEOFF
47+
call void @foo()
48+
; OUTLINE: bl _OUTLINED_FUNCTION_0
49+
; OUTLINE-NEXT: mov x0, x19
50+
; OUTLINE-NEXT: bl _goo
51+
call void @goo(ptr %addr)
52+
ret i32 %res
53+
; LOH: .loh AdrpAdd [[L5]], [[L6]]
54+
; CHECK: .cfi_endproc
55+
}
56+
57+
; Note: it is not safe to add LOHs to this function as outlined functions do not
58+
; follow calling convention and thus x19 could be live across the call.
59+
; OUTLINE: _OUTLINED_FUNCTION_0:
60+
; OUTLINE: adrp x19, _A@PAGE
61+
; OUTLINE: add x19, x19, _A@PAGEOFF
62+
; OUTLINE: ldr w20, [x19]
63+
; OUTLINE: b _foo

0 commit comments

Comments
 (0)