[llvm] [GISel][RISCV]Implement indirect parameter passing for large scalars (PR #95429)

Gábor Spaits via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 14 02:10:54 PDT 2024


================
@@ -790,6 +804,36 @@ bool CallLowering::handleAssignments(ValueHandler &Handler,
       CCValAssign &VA = ArgLocs[j + Idx];
       const ISD::ArgFlagsTy Flags = Args[i].Flags[Part];
 
+      // We found an indirect parameter passing and we are at the first part of
+      // the value being passed. In this case copy the incoming pointer into a
+      // virtual register so later we can load it.
+      if (VA.getLocInfo() == CCValAssign::Indirect && Flags.isSplit()) {
----------------
spaits wrote:

Only the first part is processed, when we have indirect passing. I wrote about it in the previous comment.

This is how things happen:
1. `RISCVCallLowering::lowerFormalArguments` is called.
2. The arguments are prepared, ArgInfor array is constructed in a loop.
3. `CallLowering::determineAssignments` is called.
4. In `CallLowering::determineAssignments` we decide how many registers would be needed to store the value being passed.
5. Then we create as many  `CCValAssign`s as many register would be needed.
6. We run the calling convention function on all of them (CallLowering.cpp:681 the loop). This loop marks the first register with setSplit and the last with setSplitEnd
7. In the calling convention function, we recognize that we need indirect passing(The RISCV::CC_RISCV knows when we need that. This code is also used by SelDAG). It sets the `CCValAssign` to be an indirect assignment.
8. After this we get back to handle assignment, where in the `CCState` we have the informations to handle the assignments.
9. And this is where my PR comes in and handles the assignments.

This is my understanding.

https://github.com/llvm/llvm-project/pull/95429


More information about the llvm-commits mailing list