Skip to content

Commit 49b0899

Browse files
committed
GlobalISel: Use LibcallLoweringInfo analysis in legalizer
This is mostly boilerplate to move various freestanding utility functions into LegalizerHelper. LibcallLoweringInfo is currently optional, mostly because threading it through assorted other uses of LegalizerHelper is more difficult. I had a lot of trouble getting this to work in the legacy pass manager with setRequiresCodeGenSCCOrder, and am not happy with the result. A sub-pass manager is introduced and this is invalidated, so we're re-computing this unnecessarily.
1 parent 21d2d43 commit 49b0899

File tree

8 files changed

+183
-165
lines changed

8 files changed

+183
-165
lines changed

llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class LegalizerInfo;
3333
class MachineIRBuilder;
3434
class MachineInstr;
3535
class GISelChangeObserver;
36+
class LibcallLoweringInfo;
3637
class LostDebugLocObserver;
3738

3839
class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
7071

7172
bool runOnMachineFunction(MachineFunction &MF) override;
7273

73-
static MFResult
74-
legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
75-
ArrayRef<GISelChangeObserver *> AuxObservers,
76-
LostDebugLocObserver &LocObserver,
77-
MachineIRBuilder &MIRBuilder, GISelValueTracking *VT);
74+
static MFResult legalizeMachineFunction(
75+
MachineFunction &MF, const LegalizerInfo &LI,
76+
ArrayRef<GISelChangeObserver *> AuxObservers,
77+
LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
78+
const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
7879
};
7980
} // End namespace llvm.
8081

llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ class LegalizerHelper {
5959
MachineRegisterInfo &MRI;
6060
const LegalizerInfo &LI;
6161
const TargetLowering &TLI;
62-
GISelValueTracking *VT;
62+
63+
// FIXME: Should probably make Libcalls mandatory
64+
const LibcallLoweringInfo *Libcalls = nullptr;
65+
GISelValueTracking *VT = nullptr;
6366

6467
public:
6568
enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
7881
/// Expose LegalizerInfo so the clients can re-use.
7982
const LegalizerInfo &getLegalizerInfo() const { return LI; }
8083
const TargetLowering &getTargetLowering() const { return TLI; }
84+
const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
8185
GISelValueTracking *getValueTracking() const { return VT; }
8286

8387
LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
84-
MachineIRBuilder &B);
88+
MachineIRBuilder &B,
89+
const LibcallLoweringInfo *Libcalls = nullptr);
8590
LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
8691
GISelChangeObserver &Observer, MachineIRBuilder &B,
92+
const LibcallLoweringInfo *Libcalls = nullptr,
8793
GISelValueTracking *VT = nullptr);
8894

8995
/// Replace \p MI by a sequence of legal instructions that can implement the
@@ -178,6 +184,37 @@ class LegalizerHelper {
178184
/// def by inserting a G_BITCAST from \p CastTy
179185
LLVM_ABI void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
180186

187+
// Useful for libcalls where all operands have the same type.
188+
LLVM_ABI LegalizeResult
189+
simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
190+
Type *OpType, LostDebugLocObserver &LocObserver) const;
191+
192+
LLVM_ABI LegalizeResult conversionLibcall(MachineInstr &MI, Type *ToType,
193+
Type *FromType,
194+
LostDebugLocObserver &LocObserver,
195+
bool IsSigned = false) const;
196+
197+
/// Helper function that creates a libcall to the given \p Name using the
198+
/// given calling convention \p CC.
199+
LLVM_ABI LegalizeResult createLibcall(const char *Name,
200+
const CallLowering::ArgInfo &Result,
201+
ArrayRef<CallLowering::ArgInfo> Args,
202+
CallingConv::ID CC,
203+
LostDebugLocObserver &LocObserver,
204+
MachineInstr *MI = nullptr) const;
205+
206+
/// Helper function that creates the given libcall.
207+
LLVM_ABI LegalizeResult createLibcall(RTLIB::Libcall Libcall,
208+
const CallLowering::ArgInfo &Result,
209+
ArrayRef<CallLowering::ArgInfo> Args,
210+
LostDebugLocObserver &LocObserver,
211+
MachineInstr *MI = nullptr) const;
212+
213+
/// Create a libcall to memcpy et al.
214+
LLVM_ABI LegalizeResult
215+
createMemLibcall(MachineRegisterInfo &MRI, MachineInstr &MI,
216+
LostDebugLocObserver &LocObserver) const;
217+
181218
private:
182219
LegalizeResult
183220
widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
@@ -278,17 +315,13 @@ class LegalizerHelper {
278315
bool IsVolatile);
279316

280317
// Implements floating-point environment read/write via library function call.
281-
LegalizeResult createGetStateLibcall(MachineIRBuilder &MIRBuilder,
282-
MachineInstr &MI,
318+
LegalizeResult createGetStateLibcall(MachineInstr &MI,
283319
LostDebugLocObserver &LocObserver);
284-
LegalizeResult createSetStateLibcall(MachineIRBuilder &MIRBuilder,
285-
MachineInstr &MI,
320+
LegalizeResult createSetStateLibcall(MachineInstr &MI,
286321
LostDebugLocObserver &LocObserver);
287-
LegalizeResult createResetStateLibcall(MachineIRBuilder &MIRBuilder,
288-
MachineInstr &MI,
322+
LegalizeResult createResetStateLibcall(MachineInstr &MI,
289323
LostDebugLocObserver &LocObserver);
290-
LegalizeResult createFCMPLibcall(MachineIRBuilder &MIRBuilder,
291-
MachineInstr &MI,
324+
LegalizeResult createFCMPLibcall(MachineInstr &MI,
292325
LostDebugLocObserver &LocObserver);
293326

294327
MachineInstrBuilder
@@ -539,26 +572,6 @@ class LegalizerHelper {
539572
LLVM_ABI LegalizeResult lowerVAArg(MachineInstr &MI);
540573
};
541574

542-
/// Helper function that creates a libcall to the given \p Name using the given
543-
/// calling convention \p CC.
544-
LLVM_ABI LegalizerHelper::LegalizeResult
545-
createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
546-
const CallLowering::ArgInfo &Result,
547-
ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC,
548-
LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
549-
550-
/// Helper function that creates the given libcall.
551-
LLVM_ABI LegalizerHelper::LegalizeResult
552-
createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
553-
const CallLowering::ArgInfo &Result,
554-
ArrayRef<CallLowering::ArgInfo> Args,
555-
LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
556-
557-
/// Create a libcall to memcpy et al.
558-
LLVM_ABI LegalizerHelper::LegalizeResult
559-
createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
560-
MachineInstr &MI, LostDebugLocObserver &LocObserver);
561-
562575
} // End namespace llvm.
563576

564577
#endif

llvm/lib/CodeGen/GlobalISel/Legalizer.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ char Legalizer::ID = 0;
7373
INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
7474
"Legalize the Machine IR a function's Machine IR", false,
7575
false)
76+
INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
7677
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
7778
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
7879
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
@@ -83,6 +84,7 @@ INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
8384
Legalizer::Legalizer() : MachineFunctionPass(ID) { }
8485

8586
void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
87+
AU.addRequired<LibcallLoweringInfoWrapper>();
8688
AU.addRequired<TargetPassConfig>();
8789
AU.addRequired<GISelCSEAnalysisWrapperPass>();
8890
AU.addPreserved<GISelCSEAnalysisWrapperPass>();
@@ -172,12 +174,11 @@ class LegalizerWorkListManager : public GISelChangeObserver {
172174
};
173175
} // namespace
174176

175-
Legalizer::MFResult
176-
Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
177-
ArrayRef<GISelChangeObserver *> AuxObservers,
178-
LostDebugLocObserver &LocObserver,
179-
MachineIRBuilder &MIRBuilder,
180-
GISelValueTracking *VT) {
177+
Legalizer::MFResult Legalizer::legalizeMachineFunction(
178+
MachineFunction &MF, const LegalizerInfo &LI,
179+
ArrayRef<GISelChangeObserver *> AuxObservers,
180+
LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
181+
const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT) {
181182
MIRBuilder.setMF(MF);
182183
MachineRegisterInfo &MRI = MF.getRegInfo();
183184

@@ -216,7 +217,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
216217
// Now install the observer as the delegate to MF.
217218
// This will keep all the observers notified about new insertions/deletions.
218219
RAIIMFObsDelInstaller Installer(MF, WrapperObserver);
219-
LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, VT);
220+
LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, Libcalls, VT);
220221
LegalizationArtifactCombiner ArtCombiner(MIRBuilder, MRI, LI, VT);
221222
bool Changed = false;
222223
SmallVector<MachineInstr *, 128> RetryList;
@@ -339,13 +340,18 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
339340
if (VerifyDebugLocs > DebugLocVerifyLevel::None)
340341
AuxObservers.push_back(&LocObserver);
341342

343+
const TargetSubtargetInfo &Subtarget = MF.getSubtarget();
344+
345+
const LibcallLoweringInfo &Libcalls =
346+
getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(Subtarget);
347+
342348
// This allows Known Bits Analysis in the legalizer.
343349
GISelValueTracking *VT =
344350
&getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
345351

346-
const LegalizerInfo &LI = *MF.getSubtarget().getLegalizerInfo();
352+
const LegalizerInfo &LI = *Subtarget.getLegalizerInfo();
347353
MFResult Result = legalizeMachineFunction(MF, LI, AuxObservers, LocObserver,
348-
*MIRBuilder, VT);
354+
*MIRBuilder, &Libcalls, VT);
349355

350356
if (Result.FailedOn) {
351357
reportGISelFailure(MF, MORE, "gisel-legalize",

0 commit comments

Comments
 (0)