Skip to content

Commit 1c5b150

Browse files
authored
CodeGen: Move libcall lowering configuration to subtarget (#168621)
Previously libcall lowering decisions were made directly in the TargetLowering constructor. Pull these into the subtarget to facilitate turning LibcallLoweringInfo into a separate analysis in the future.
1 parent 5999cc8 commit 1c5b150

17 files changed

+239
-205
lines changed

llvm/include/llvm/CodeGen/LibcallLoweringInfo.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
namespace llvm {
1515

16+
class TargetSubtargetInfo;
17+
1618
class LibcallLoweringInfo {
1719
private:
1820
const RTLIB::RuntimeLibcallsInfo &RTLCI;
@@ -21,7 +23,12 @@ class LibcallLoweringInfo {
2123
RTLIB::Unsupported};
2224

2325
public:
24-
LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI);
26+
LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI,
27+
const TargetSubtargetInfo &Subtarget);
28+
29+
const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const {
30+
return RTLCI;
31+
}
2532

2633
/// Get the libcall routine name for the specified libcall.
2734
// FIXME: This should be removed. Only LibcallImpl should have a name.

llvm/include/llvm/CodeGen/TargetSubtargetInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class InstrItineraryData;
3838
struct InstrStage;
3939
class InstructionSelector;
4040
class LegalizerInfo;
41+
class LibcallLoweringInfo;
4142
class MachineInstr;
4243
struct MachineSchedPolicy;
4344
struct MCReadAdvanceEntry;
@@ -139,6 +140,12 @@ class LLVM_ABI TargetSubtargetInfo : public MCSubtargetInfo {
139140
return nullptr;
140141
}
141142

143+
/// Configure the LibcallLoweringInfo for this subtarget. The libcalls will be
144+
/// pre-configured with defaults based on RuntimeLibcallsInfo. This may be
145+
/// used to override those decisions, such as disambiguating alternative
146+
/// implementations.
147+
virtual void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const {}
148+
142149
/// Resolve a SchedClass at runtime, where SchedClass identifies an
143150
/// MCSchedClassDesc with the isVariant property. This may return the ID of
144151
/// another variant SchedClass, but repeated invocation must quickly terminate

llvm/lib/CodeGen/LibcallLoweringInfo.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/CodeGen/LibcallLoweringInfo.h"
10+
#include "llvm/CodeGen/TargetSubtargetInfo.h"
1011

1112
using namespace llvm;
1213

1314
LibcallLoweringInfo::LibcallLoweringInfo(
14-
const RTLIB::RuntimeLibcallsInfo &RTLCI)
15+
const RTLIB::RuntimeLibcallsInfo &RTLCI,
16+
const TargetSubtargetInfo &Subtarget)
1517
: RTLCI(RTLCI) {
1618
// TODO: This should be generated with lowering predicates, and assert the
1719
// call is available.
@@ -23,4 +25,6 @@ LibcallLoweringInfo::LibcallLoweringInfo(
2325
LibcallImpls[LC] = Impl;
2426
}
2527
}
28+
29+
Subtarget.initLibcallLoweringInfo(*this);
2630
}

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm,
755755
RuntimeLibcallInfo(TM.getTargetTriple(), TM.Options.ExceptionModel,
756756
TM.Options.FloatABIType, TM.Options.EABIVersion,
757757
TM.Options.MCOptions.getABIName(), TM.Options.VecLib),
758-
Libcalls(RuntimeLibcallInfo) {
758+
Libcalls(RuntimeLibcallInfo, STI) {
759759
initActions();
760760

761761
// Perform these initializations only once.

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -518,74 +518,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
518518

519519
const Triple &TT = TM.getTargetTriple();
520520

521-
if (TT.isOSBinFormatMachO()) {
522-
// Uses VFP for Thumb libfuncs if available.
523-
if (Subtarget->isThumb() && Subtarget->hasVFP2Base() &&
524-
Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) {
525-
// clang-format off
526-
static const struct {
527-
const RTLIB::Libcall Op;
528-
const RTLIB::LibcallImpl Impl;
529-
} LibraryCalls[] = {
530-
// Single-precision floating-point arithmetic.
531-
{ RTLIB::ADD_F32, RTLIB::impl___addsf3vfp },
532-
{ RTLIB::SUB_F32, RTLIB::impl___subsf3vfp },
533-
{ RTLIB::MUL_F32, RTLIB::impl___mulsf3vfp },
534-
{ RTLIB::DIV_F32, RTLIB::impl___divsf3vfp },
535-
536-
// Double-precision floating-point arithmetic.
537-
{ RTLIB::ADD_F64, RTLIB::impl___adddf3vfp },
538-
{ RTLIB::SUB_F64, RTLIB::impl___subdf3vfp },
539-
{ RTLIB::MUL_F64, RTLIB::impl___muldf3vfp },
540-
{ RTLIB::DIV_F64, RTLIB::impl___divdf3vfp },
541-
542-
// Single-precision comparisons.
543-
{ RTLIB::OEQ_F32, RTLIB::impl___eqsf2vfp },
544-
{ RTLIB::UNE_F32, RTLIB::impl___nesf2vfp },
545-
{ RTLIB::OLT_F32, RTLIB::impl___ltsf2vfp },
546-
{ RTLIB::OLE_F32, RTLIB::impl___lesf2vfp },
547-
{ RTLIB::OGE_F32, RTLIB::impl___gesf2vfp },
548-
{ RTLIB::OGT_F32, RTLIB::impl___gtsf2vfp },
549-
{ RTLIB::UO_F32, RTLIB::impl___unordsf2vfp },
550-
551-
// Double-precision comparisons.
552-
{ RTLIB::OEQ_F64, RTLIB::impl___eqdf2vfp },
553-
{ RTLIB::UNE_F64, RTLIB::impl___nedf2vfp },
554-
{ RTLIB::OLT_F64, RTLIB::impl___ltdf2vfp },
555-
{ RTLIB::OLE_F64, RTLIB::impl___ledf2vfp },
556-
{ RTLIB::OGE_F64, RTLIB::impl___gedf2vfp },
557-
{ RTLIB::OGT_F64, RTLIB::impl___gtdf2vfp },
558-
{ RTLIB::UO_F64, RTLIB::impl___unorddf2vfp },
559-
560-
// Floating-point to integer conversions.
561-
// i64 conversions are done via library routines even when generating VFP
562-
// instructions, so use the same ones.
563-
{ RTLIB::FPTOSINT_F64_I32, RTLIB::impl___fixdfsivfp },
564-
{ RTLIB::FPTOUINT_F64_I32, RTLIB::impl___fixunsdfsivfp },
565-
{ RTLIB::FPTOSINT_F32_I32, RTLIB::impl___fixsfsivfp },
566-
{ RTLIB::FPTOUINT_F32_I32, RTLIB::impl___fixunssfsivfp },
567-
568-
// Conversions between floating types.
569-
{ RTLIB::FPROUND_F64_F32, RTLIB::impl___truncdfsf2vfp },
570-
{ RTLIB::FPEXT_F32_F64, RTLIB::impl___extendsfdf2vfp },
571-
572-
// Integer to floating-point conversions.
573-
// i64 conversions are done via library routines even when generating VFP
574-
// instructions, so use the same ones.
575-
// FIXME: There appears to be some naming inconsistency in ARM libgcc:
576-
// e.g., __floatunsidf vs. __floatunssidfvfp.
577-
{ RTLIB::SINTTOFP_I32_F64, RTLIB::impl___floatsidfvfp },
578-
{ RTLIB::UINTTOFP_I32_F64, RTLIB::impl___floatunssidfvfp },
579-
{ RTLIB::SINTTOFP_I32_F32, RTLIB::impl___floatsisfvfp },
580-
{ RTLIB::UINTTOFP_I32_F32, RTLIB::impl___floatunssisfvfp },
581-
};
582-
// clang-format on
583-
584-
for (const auto &LC : LibraryCalls)
585-
setLibcallImpl(LC.Op, LC.Impl);
586-
}
587-
}
588-
589521
if (Subtarget->isThumb1Only())
590522
addRegisterClass(MVT::i32, &ARM::tGPRRegClass);
591523
else

llvm/lib/Target/ARM/ARMSubtarget.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,76 @@ const RegisterBankInfo *ARMSubtarget::getRegBankInfo() const {
129129
return RegBankInfo.get();
130130
}
131131

132+
void ARMSubtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const {
133+
const Triple &TT = getTargetTriple();
134+
if (TT.isOSBinFormatMachO()) {
135+
// Uses VFP for Thumb libfuncs if available.
136+
if (isThumb() && hasVFP2Base() && hasARMOps() && !useSoftFloat()) {
137+
// clang-format off
138+
static const struct {
139+
const RTLIB::Libcall Op;
140+
const RTLIB::LibcallImpl Impl;
141+
} LibraryCalls[] = {
142+
// Single-precision floating-point arithmetic.
143+
{ RTLIB::ADD_F32, RTLIB::impl___addsf3vfp },
144+
{ RTLIB::SUB_F32, RTLIB::impl___subsf3vfp },
145+
{ RTLIB::MUL_F32, RTLIB::impl___mulsf3vfp },
146+
{ RTLIB::DIV_F32, RTLIB::impl___divsf3vfp },
147+
148+
// Double-precision floating-point arithmetic.
149+
{ RTLIB::ADD_F64, RTLIB::impl___adddf3vfp },
150+
{ RTLIB::SUB_F64, RTLIB::impl___subdf3vfp },
151+
{ RTLIB::MUL_F64, RTLIB::impl___muldf3vfp },
152+
{ RTLIB::DIV_F64, RTLIB::impl___divdf3vfp },
153+
154+
// Single-precision comparisons.
155+
{ RTLIB::OEQ_F32, RTLIB::impl___eqsf2vfp },
156+
{ RTLIB::UNE_F32, RTLIB::impl___nesf2vfp },
157+
{ RTLIB::OLT_F32, RTLIB::impl___ltsf2vfp },
158+
{ RTLIB::OLE_F32, RTLIB::impl___lesf2vfp },
159+
{ RTLIB::OGE_F32, RTLIB::impl___gesf2vfp },
160+
{ RTLIB::OGT_F32, RTLIB::impl___gtsf2vfp },
161+
{ RTLIB::UO_F32, RTLIB::impl___unordsf2vfp },
162+
163+
// Double-precision comparisons.
164+
{ RTLIB::OEQ_F64, RTLIB::impl___eqdf2vfp },
165+
{ RTLIB::UNE_F64, RTLIB::impl___nedf2vfp },
166+
{ RTLIB::OLT_F64, RTLIB::impl___ltdf2vfp },
167+
{ RTLIB::OLE_F64, RTLIB::impl___ledf2vfp },
168+
{ RTLIB::OGE_F64, RTLIB::impl___gedf2vfp },
169+
{ RTLIB::OGT_F64, RTLIB::impl___gtdf2vfp },
170+
{ RTLIB::UO_F64, RTLIB::impl___unorddf2vfp },
171+
172+
// Floating-point to integer conversions.
173+
// i64 conversions are done via library routines even when generating VFP
174+
// instructions, so use the same ones.
175+
{ RTLIB::FPTOSINT_F64_I32, RTLIB::impl___fixdfsivfp },
176+
{ RTLIB::FPTOUINT_F64_I32, RTLIB::impl___fixunsdfsivfp },
177+
{ RTLIB::FPTOSINT_F32_I32, RTLIB::impl___fixsfsivfp },
178+
{ RTLIB::FPTOUINT_F32_I32, RTLIB::impl___fixunssfsivfp },
179+
180+
// Conversions between floating types.
181+
{ RTLIB::FPROUND_F64_F32, RTLIB::impl___truncdfsf2vfp },
182+
{ RTLIB::FPEXT_F32_F64, RTLIB::impl___extendsfdf2vfp },
183+
184+
// Integer to floating-point conversions.
185+
// i64 conversions are done via library routines even when generating VFP
186+
// instructions, so use the same ones.
187+
// FIXME: There appears to be some naming inconsistency in ARM libgcc:
188+
// e.g., __floatunsidf vs. __floatunssidfvfp.
189+
{ RTLIB::SINTTOFP_I32_F64, RTLIB::impl___floatsidfvfp },
190+
{ RTLIB::UINTTOFP_I32_F64, RTLIB::impl___floatunssidfvfp },
191+
{ RTLIB::SINTTOFP_I32_F32, RTLIB::impl___floatsisfvfp },
192+
{ RTLIB::UINTTOFP_I32_F32, RTLIB::impl___floatunssisfvfp },
193+
};
194+
// clang-format on
195+
196+
for (const auto &LC : LibraryCalls)
197+
Info.setLibcallImpl(LC.Op, LC.Impl);
198+
}
199+
}
200+
}
201+
132202
bool ARMSubtarget::isXRaySupported() const {
133203
// We don't currently suppport Thumb, but Windows requires Thumb.
134204
return hasV6Ops() && hasARMOps() && !isTargetWindows();

llvm/lib/Target/ARM/ARMSubtarget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
258258
InstructionSelector *getInstructionSelector() const override;
259259
const LegalizerInfo *getLegalizerInfo() const override;
260260
const RegisterBankInfo *getRegBankInfo() const override;
261+
void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override;
261262

262263
private:
263264
ARMSelectionDAGInfo TSInfo;

llvm/lib/Target/MSP430/MSP430ISelLowering.cpp

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -148,68 +148,6 @@ MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM,
148148
setOperationAction(ISD::VACOPY, MVT::Other, Expand);
149149
setOperationAction(ISD::JumpTable, MVT::i16, Custom);
150150

151-
if (STI.hasHWMult16()) {
152-
const struct {
153-
const RTLIB::Libcall Op;
154-
const RTLIB::LibcallImpl Impl;
155-
} LibraryCalls[] = {
156-
// Integer Multiply - EABI Table 9
157-
{RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw},
158-
{RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw},
159-
{RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw},
160-
// TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc
161-
// TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc
162-
};
163-
for (const auto &LC : LibraryCalls) {
164-
setLibcallImpl(LC.Op, LC.Impl);
165-
}
166-
} else if (STI.hasHWMult32()) {
167-
const struct {
168-
const RTLIB::Libcall Op;
169-
const RTLIB::LibcallImpl Impl;
170-
} LibraryCalls[] = {
171-
// Integer Multiply - EABI Table 9
172-
{RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw},
173-
{RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw32},
174-
{RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw32},
175-
// TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc
176-
// TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc
177-
};
178-
for (const auto &LC : LibraryCalls) {
179-
setLibcallImpl(LC.Op, LC.Impl);
180-
}
181-
} else if (STI.hasHWMultF5()) {
182-
const struct {
183-
const RTLIB::Libcall Op;
184-
const RTLIB::LibcallImpl Impl;
185-
} LibraryCalls[] = {
186-
// Integer Multiply - EABI Table 9
187-
{RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_f5hw},
188-
{RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_f5hw},
189-
{RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_f5hw},
190-
// TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc
191-
// TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc
192-
};
193-
for (const auto &LC : LibraryCalls) {
194-
setLibcallImpl(LC.Op, LC.Impl);
195-
}
196-
} else { // NoHWMult
197-
const struct {
198-
const RTLIB::Libcall Op;
199-
const RTLIB::LibcallImpl Impl;
200-
} LibraryCalls[] = {
201-
// Integer Multiply - EABI Table 9
202-
{RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi},
203-
{RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl},
204-
{RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll},
205-
// The __mspabi_mpysl* functions are NOT implemented in libgcc
206-
// The __mspabi_mpyul* functions are NOT implemented in libgcc
207-
};
208-
for (const auto &LC : LibraryCalls) {
209-
setLibcallImpl(LC.Op, LC.Impl);
210-
}
211-
}
212-
213151
setMinFunctionAlignment(Align(2));
214152
setPrefFunctionAlignment(Align(2));
215153
setMaxAtomicSizeInBitsSupported(0);

llvm/lib/Target/MSP430/MSP430Subtarget.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,67 @@ MSP430Subtarget::~MSP430Subtarget() = default;
6868
const SelectionDAGTargetInfo *MSP430Subtarget::getSelectionDAGInfo() const {
6969
return TSInfo.get();
7070
}
71+
72+
void MSP430Subtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const {
73+
if (hasHWMult16()) {
74+
const struct {
75+
const RTLIB::Libcall Op;
76+
const RTLIB::LibcallImpl Impl;
77+
} LibraryCalls[] = {
78+
// Integer Multiply - EABI Table 9
79+
{RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw},
80+
{RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw},
81+
{RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw},
82+
// TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc
83+
// TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc
84+
};
85+
for (const auto &LC : LibraryCalls) {
86+
Info.setLibcallImpl(LC.Op, LC.Impl);
87+
}
88+
} else if (hasHWMult32()) {
89+
const struct {
90+
const RTLIB::Libcall Op;
91+
const RTLIB::LibcallImpl Impl;
92+
} LibraryCalls[] = {
93+
// Integer Multiply - EABI Table 9
94+
{RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw},
95+
{RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw32},
96+
{RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw32},
97+
// TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc
98+
// TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc
99+
};
100+
for (const auto &LC : LibraryCalls) {
101+
Info.setLibcallImpl(LC.Op, LC.Impl);
102+
}
103+
} else if (hasHWMultF5()) {
104+
const struct {
105+
const RTLIB::Libcall Op;
106+
const RTLIB::LibcallImpl Impl;
107+
} LibraryCalls[] = {
108+
// Integer Multiply - EABI Table 9
109+
{RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_f5hw},
110+
{RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_f5hw},
111+
{RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_f5hw},
112+
// TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc
113+
// TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc
114+
};
115+
for (const auto &LC : LibraryCalls) {
116+
Info.setLibcallImpl(LC.Op, LC.Impl);
117+
}
118+
} else { // NoHWMult
119+
const struct {
120+
const RTLIB::Libcall Op;
121+
const RTLIB::LibcallImpl Impl;
122+
} LibraryCalls[] = {
123+
// Integer Multiply - EABI Table 9
124+
{RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi},
125+
{RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl},
126+
{RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll},
127+
// The __mspabi_mpysl* functions are NOT implemented in libgcc
128+
// The __mspabi_mpyul* functions are NOT implemented in libgcc
129+
};
130+
for (const auto &LC : LibraryCalls) {
131+
Info.setLibcallImpl(LC.Op, LC.Impl);
132+
}
133+
}
134+
}

llvm/lib/Target/MSP430/MSP430Subtarget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo {
7474
}
7575

7676
const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
77+
78+
void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override;
7779
};
7880
} // End llvm namespace
7981

0 commit comments

Comments
 (0)