I’ve been trying to implement XRay custom events for RISCV. (I know that XRay is currently unsupported for RISCV, but I have developed a functional implementation of XRay-Basic logging for RISCV.)
I’ve developed an implementation for the trampoline and sleds, and updated RISCVAsmPrinter to emit a sled, following a similar approach to X86 (keeping in mind differences in ISA and calling conventions.)
However, I now run into illegal operand errors when trying to compile code for my RISCV sleds with custom events. Here’s what I think is happening:
• The compiler constructs a MachineSDNode corresponding to the custom event call (__xray_customevent) as defined in SelectionDAGBuilder.cpp
• More specifically, we construct a node with TargetOpcode as PATCHABLE_EVENT_CALL and with the correct arguments. This section of code includes a fixme for adding support to other platforms, mentioning that it currently only supports X86. Furthermore, the comment seemed to indicate this was because of the assumption that the intrinsic behaves as if it has a specific calling convention.
• I wasn’t too sure as to how this was enforced, and thought I’d ask about this. I tried blindly allowing riscv64 past the check as well to see if that would work, but I get an error at DAG.setRoot.
Essentially, LowerOperation() ends up getting called and I see the unimplemented operand assert. I have added a case in RISCVTargetLowering: EmitInstrWithCustomInserter() to handle PATCHABLE_EVENT_CALL, but this function isn’t being called for now.
I added print statements to try and figure out what opcode was being called in LowerOperation, which resulted in an Opcode of 65496. To figure out what was going wrong, I added print statements to the selectionDAGBuilder cpp file.
It was clear what was happening here - running the call to generate a Machine node (getMachineNode llvm-project/SelectionDAGBuilder.cpp at main · llvm/llvm-project · GitHub) generates a machine node MN with Opcode 65496 and MachineOpcode 39 (which corresponds to PATCHABLE_EVENT_CALL.)
From my understanding of the process, I think LowerOperation is called by the legalizer before instruction selection, so this would normally be an operation run on SDNodes (which are later converted to MachineSDNodes.) However, custom events seem to directly involve the insertion of MachineSDNodes – so how does the X86 backend manage to recognize that these custom event nodes are already MachineSDNodes and avoid processing them with the regular SDNodes generated from IR? I checked the commit history for custom events, and there didn’t seem to be any changes to add such support.