Skip to content

Conversation

@xdoardo
Copy link
Collaborator

@xdoardo xdoardo commented Jun 12, 2025

Should close #177. This PR also adds the same mechanism for arguments that can be subjected to the same optimisation.

@xdoardo xdoardo force-pushed the cheriot-ret-two-caps-struct-in-regs branch 4 times, most recently from 9e0b1cf to c297697 Compare June 13, 2025 09:01
@xdoardo xdoardo requested a review from resistor June 13, 2025 09:16
@xdoardo xdoardo force-pushed the cheriot-ret-two-caps-struct-in-regs branch from c297697 to c6163f7 Compare June 13, 2025 15:22
@xdoardo xdoardo changed the title [CHERIoT] Pass two-cap-sized return values and arguments in registers [CHERIoT] Pass two-cap return values and arguments in registers Jun 13, 2025
@xdoardo xdoardo changed the title [CHERIoT] Pass two-cap return values and arguments in registers [CHERIoT] Pass two-caps return values and arguments in registers Jun 13, 2025
@xdoardo xdoardo force-pushed the cheriot-ret-two-caps-struct-in-regs branch 2 times, most recently from d2d2889 to f7259fb Compare June 13, 2025 19:23

if (auto *RT = Ty->getAs<RecordType>()) {
unsigned MaxCapRegs = IsCheriot ? 2 : 1;
return Size == MaxCapRegs * getTarget().getCHERICapabilityWidth() &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be <= rather than ==?


bool IsCapability = Ty->isCHERICapabilityType(getContext()) ||
IsSingleCapRecord;
(ForcePassInCapRegs && Size == CapabilityWidth);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be just ForcePassInCapRegs if you change == to <= in shouldPassStructDirectInCapRegisters

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per chat discussion, if we can't simplify the logic, perhaps we can rename the variables to make the logic simpler?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the relevant bit of the discussion: the final goal is that of having IsCapability true iff. the type is itself a capability or a struct made of a single capability, the case where the struct is composed of >= 2 capabilities should not entail IsCapability == true.

Latest commit renames IsCapability to IsSingleCapability!


bool IsCapability = Ty->isCHERICapabilityType(getContext()) ||
IsSingleCapRecord;
(ForcePassInCapRegs && Size == CapabilityWidth);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

@xdoardo xdoardo force-pushed the cheriot-ret-two-caps-struct-in-regs branch 2 times, most recently from c890fbc to 0a08dd7 Compare June 16, 2025 09:00
@xdoardo
Copy link
Collaborator Author

xdoardo commented Jun 16, 2025

The previous code was not taking into account the case for Size == CapWidth in CHERIoT. I updated the code in a way that seems easier to me: shouldPass.. is now a (renamed) function that simply returns the number of cap registers needed to pass a value directly, in the case that it satisfies the conditions imposed by the ABI.

@xdoardo xdoardo force-pushed the cheriot-ret-two-caps-struct-in-regs branch from 0a08dd7 to ab0982e Compare June 16, 2025 09:37
Copy link
Collaborator

@resistor resistor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is way better than before!


/// CHERI(oT)-specific: Figure out how many registers are needed to pass a
/// value of the given type and size directly in register(s). The value of
/// `-1` means that the value should be passed indirectly.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't 0 be the sentinel?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I set it to -1 because I am not completely sure about the semantics of zero-sized types and, perhaps, there might be a situation where we want to know that the value "fits in 0 registers", if that makes any sense.

@xdoardo xdoardo merged commit 5bda199 into CHERIoT-Platform:cheriot Jun 16, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CodeGen optimisation: return structs of two pointers in a0 and a1

2 participants