[clang] [compiler-rt] [llvm] [XRay][RISCV] RISCV support for XRay (PR #117368)
Craig Topper via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 4 11:44:53 PST 2024
================
@@ -453,11 +475,71 @@ bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
SetupMachineFunction(MF);
emitFunctionBody();
+ // Emit the XRay table
+ emitXRayTable();
+
if (EmittedOptionArch)
RTS.emitDirectiveOptionPop();
return false;
}
+void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr *MI) {
+ emitSled(MI, SledKind::FUNCTION_ENTER);
+}
+
+void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr *MI) {
+ emitSled(MI, SledKind::FUNCTION_EXIT);
+}
+
+void RISCVAsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr *MI) {
+ emitSled(MI, SledKind::TAIL_CALL);
+}
+
+void RISCVAsmPrinter::emitSled(const MachineInstr *MI, SledKind Kind) {
+ // We want to emit the jump instruction and the nops constituting the sled.
+ // The format is as follows:
+ // .Lxray_sled_N
+ // ALIGN
+ // J .tmpN
+ // 25 or 33 C.NOP instructions
+ // .tmpN
+
+ // The following variable holds the count of the number of NOPs to be patched
+ // in for XRay instrumentation during compilation.
+ // Note that RV64 and RV32 each has a sled of 68 and 52 bytes, respectively.
+ // Assuming we're using JAL to jump to .tmpN, then we only need
+ // (68 - 4)/2 = 32 NOPs for RV64 and (52 - 4)/2 = 24 for RV32. However, there
+ // is a chance that we'll use C.JAL instead, so an additional NOP is needed.
+ const uint8_t NoopsInSledCount =
+ MI->getParent()->getParent()->getSubtarget<RISCVSubtarget>().is64Bit()
+ ? 33
+ : 25;
+
+ OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo());
+ auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
+ OutStreamer->emitLabel(CurSled);
+ auto Target = OutContext.createTempSymbol();
+
+ const MCExpr *TargetExpr = MCSymbolRefExpr::create(
+ Target, MCSymbolRefExpr::VariantKind::VK_None, OutContext);
+
+ // Emit "J bytes" instruction, which jumps over the nop sled to the actual
+ // start of function.
+ EmitToStreamer(
+ *OutStreamer,
+ MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addExpr(TargetExpr));
+
+ // Emit NOP instructions
+ for (int8_t I = 0; I < NoopsInSledCount; ++I)
----------------
topperc wrote:
If compressed instructions aren't enabled this emits too many bytes doesn't it?
https://github.com/llvm/llvm-project/pull/117368
More information about the cfe-commits
mailing list