[llvm-dev] Options for custom CCState, CCAssignFn, and GlobalISel
Daniel Sanders via llvm-dev
llvm-dev at lists.llvm.org
Thu Jan 4 09:10:07 PST 2018
I haven't dug into the GlobalISel calling convention code much but I can comment on the MipsCCState.
> On 3 Jan 2018, at 14:00, Alex Bradbury via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> This question came about through reviewing work from Leslie Zhai on GlobalISel
> support for RISC-V, which also motivated me to revisit code which I've always
> felt was a bit clunky.
> Calling convention lowering in LLVM is typically handled by functions
> conforming to the CCAssignFn typedef:
> typedef bool CCAssignFn(unsigned ValNo, MVT ValVT,
> MVT LocVT, CCValAssign::LocInfo LocInfo,
> ISD::ArgFlagsTy ArgFlags, CCState &State);
> Notably, these functions are called after type legalisation so an argument/ret
> has been split to legal value types. In some cases you want more information
> than is available through this function interface, which leads to a number of
> backends creating their own CCState subclass:
> * MipsCCState: adds bool vectors OriginalArgWasF128, OriginalArgWasFloat,
> OriginalArgWasFloatVector, OriginalRetWasFloatVector, CallOperandIsFixed. Also
> a SpeciallCallingConv field. Provides its own implementation of
> AnalyzeFormalArguments etc that fill these vectors.
CallOperandIsFixed was needed because the CCIf* classes could tell whether the argument list was variable or not, but couldn't tell whether a particular argument was part of the variable portion of the argument list. At the time, it struck me as odd that this information wasn't part of ArgFlagsTy but I didn't want to add it there because it appeared to be full and I didn't want to make everyone have a 65-bit ArgFlagsTy just because of a Mips quirk. I see Reid Kleckner changed this object last year and found that it wasn't actually full so maybe we should move OutputArg::IsFixed into ArgFlagsTy now.
I think SpeciallCallingConv ought to be eliminated and Mips16's calling convention be given it's own CallingConv def instead. If I remember rightly, I left it there because I didn't want to change Mips16 at the time.
I'll comment on the OriginalArg* family below.
> * HexagonCCState: adds a single extra field - NumNamedVarArgParams.
> * PPCCCState: adds an OriginalArgWasPPCF128 bool vector. Arguably reduces
> boilerplate vs MipsCCState by just having PPCISelLowering call
> PPCCCState::PreAnalyzeCallOperands directly.
> * SystemZCCState: has bool vectors ArgIsFixed and ArgIsShortVector, works
> similarly to MipsCCState or PPCCCState.
> The above works, but it isn't directly usable in the current GlobalISel
> implementation. Very sensibly, GISel tries to both reuse existing calling
> convention implementations and to reduce duplicated code as much as possible.
> To this end, CallLowering::handleAssignments will create a CCState and use
> ValueHandler::assignArg to call a function of type CCAssignFn type.
> I see a couple of options:
> 1) Creating a new virtual method in GISel CallLowering that creates and
> initialises a CCState or custom subclass. Use that to support target-specific
> 2) Try to remove the need for custom CCState altogether. In
> <https://reviews.llvm.org/D38894>, Shiva Chen adds an OrigVT field to
> ISD::ArgFlagsTy which seems much cleaner. It's not immediately obvious to me
> if the in-tree users that currently track Type rather than EVT could always
> make do with an EVT instead. [Input welcome!].
Unfortunately, this solution wouldn't work for Mips since the 'Original*' vectors provide information from the frontend before the type was lowered to a VT. For example, OriginalArgWasF128[I] can be true when the VT before legalization was not f128. One of these cases is a structure containing a 128-bit float which the frontend lowers to i128. The other is an i128 containing a softfloat representation of a 128-bit float. If I remember correctly, the need for the latter is caused by a gcc bug that became a de-facto part of the ABI by going unnoticed for ~10 years until we tried to link clang-compiled and gcc-compiled objects together and found it didn't work.
> * Do any out-of-tree backends have custom calling convention code that
> requires more information than original arg type and whether the argument is
> fixed or not? In the RISC-V calling convention implementation I'd be happiest
> if the calling convention function had access to SubtargetInfo and the
> DataLayout, but can probably do without.
> Does anyone have views on this, or insight into planned future developments of
> calling convention handling in GlobalISel?
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
More information about the llvm-dev