From 2bdfcf0cac148ada8d3ec36f551c45efb604ac49 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 4 May 2021 17:32:09 -0400 Subject: [PATCH] GlobalISel: Move AArch64 AssignFnVarArg to base class We can handle the distinction easily enough in the generic code, and this makes it easier to abstract the selection of type/location from the code to insert code. --- .../include/llvm/CodeGen/GlobalISel/CallLowering.h | 39 +++++++++++++++++----- .../Target/AArch64/GISel/AArch64CallLowering.cpp | 10 +++--- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h index 3e3b8e9..3643b08 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -144,9 +144,17 @@ public: /// class abstracts the differences. struct ValueHandler { ValueHandler(bool IsIncoming, MachineIRBuilder &MIRBuilder, - MachineRegisterInfo &MRI, CCAssignFn *AssignFn) - : MIRBuilder(MIRBuilder), MRI(MRI), AssignFn(AssignFn), - IsIncomingArgumentHandler(IsIncoming) {} + MachineRegisterInfo &MRI, CCAssignFn *AssignFn_, + CCAssignFn *AssignFnVarArg_ = nullptr) + : MIRBuilder(MIRBuilder), MRI(MRI), AssignFn(AssignFn_), + AssignFnVarArg(AssignFnVarArg_), + IsIncomingArgumentHandler(IsIncoming) { + + // Some targets change the handler depending on whether the call is + // varargs or not. If + if (!AssignFnVarArg) + AssignFnVarArg = AssignFn; + } virtual ~ValueHandler() = default; @@ -226,13 +234,26 @@ public: virtual bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, const ArgInfo &Info, ISD::ArgFlagsTy Flags, CCState &State) { - return AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State); + return getAssignFn(State.isVarArg())(ValNo, ValVT, LocVT, LocInfo, Flags, + State); } MachineIRBuilder &MIRBuilder; MachineRegisterInfo &MRI; + + /// Assignment function to use for a general call. CCAssignFn *AssignFn; + /// Assignment function to use for a variadic call. This is usually the same + /// as AssignFn. + CCAssignFn *AssignFnVarArg; + + /// Select the appropriate assignment function depending on whether this is + /// a variadic call. + CCAssignFn *getAssignFn(bool IsVarArg) const { + return IsVarArg ? AssignFnVarArg : AssignFn; + } + private: bool IsIncomingArgumentHandler; virtual void anchor(); @@ -240,8 +261,9 @@ public: struct IncomingValueHandler : public ValueHandler { IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, - CCAssignFn *AssignFn) - : ValueHandler(true, MIRBuilder, MRI, AssignFn) {} + CCAssignFn *AssignFn_, + CCAssignFn *AssignFnVarArg_ = nullptr) + : ValueHandler(true, MIRBuilder, MRI, AssignFn_, AssignFnVarArg_) {} /// Insert G_ASSERT_ZEXT/G_ASSERT_SEXT or other hint instruction based on \p /// VA, returning the new register if a hint was inserted. @@ -254,8 +276,9 @@ public: struct OutgoingValueHandler : public ValueHandler { OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, - CCAssignFn *AssignFn) - : ValueHandler(false, MIRBuilder, MRI, AssignFn) {} + CCAssignFn *AssignFn, + CCAssignFn *AssignFnVarArg = nullptr) + : ValueHandler(false, MIRBuilder, MRI, AssignFn, AssignFnVarArg) {} }; protected: diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp index 3d856cf..f2dd336 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -138,7 +138,8 @@ struct IncomingArgHandler : public CallLowering::IncomingValueHandler { const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags, CCState &State) override { applyStackPassedSmallTypeDAGHack(OrigVT, ValVT, LocVT); - return AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State); + return getAssignFn(State.isVarArg())(ValNo, ValVT, LocVT, LocInfo, Flags, + State); } /// How the physical register gets marked varies between formal @@ -187,9 +188,9 @@ struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler { MachineInstrBuilder MIB, CCAssignFn *AssignFn, CCAssignFn *AssignFnVarArg, bool IsReturn, bool IsTailCall = false, int FPDiff = 0) - : OutgoingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB), - AssignFnVarArg(AssignFnVarArg), IsReturn(IsReturn), - IsTailCall(IsTailCall), FPDiff(FPDiff), StackSize(0), SPReg(0), + : OutgoingValueHandler(MIRBuilder, MRI, AssignFn, AssignFnVarArg), + MIB(MIB), IsReturn(IsReturn), IsTailCall(IsTailCall), FPDiff(FPDiff), + StackSize(0), SPReg(0), Subtarget(MIRBuilder.getMF().getSubtarget()) {} Register getStackAddress(uint64_t Size, int64_t Offset, @@ -296,7 +297,6 @@ struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler { } MachineInstrBuilder MIB; - CCAssignFn *AssignFnVarArg; /// Track if this is used for a return instead of function argument /// passing. We apply a hack to i1/i8/i16 stack passed values, but do not use -- 2.7.4