This revision was automatically updated to reflect the committed changes.
Closed by commit rGef33d6cbfc2d: [XRay] Add initial support for loongarch64 
(authored by SixWeining, committed by Ami-zhang).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140727/new/

https://reviews.llvm.org/D140727

Files:
  clang/lib/Driver/XRayArgs.cpp
  compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
  compiler-rt/lib/xray/CMakeLists.txt
  compiler-rt/lib/xray/xray_interface.cpp
  compiler-rt/lib/xray/xray_loongarch64.cpp
  compiler-rt/lib/xray/xray_trampoline_loongarch64.S
  compiler-rt/lib/xray/xray_tsc.h
  compiler-rt/test/xray/TestCases/Posix/c-test.cpp
  compiler-rt/test/xray/TestCases/Posix/fdr-thread-order.cpp
  llvm/lib/CodeGen/XRayInstrumentation.cpp
  llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
  llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h
  llvm/lib/Target/LoongArch/LoongArchSubtarget.h
  llvm/lib/XRay/InstrumentationMap.cpp
  llvm/test/CodeGen/LoongArch/xray-attribute-instrumentation.ll

Index: llvm/test/CodeGen/LoongArch/xray-attribute-instrumentation.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/LoongArch/xray-attribute-instrumentation.ll
@@ -0,0 +1,56 @@
+; RUN: llc --mtriple=loongarch64 %s -o - | FileCheck %s
+; RUN: llc --mtriple=loongarch64 -filetype=obj %s -o %t
+; RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC
+
+define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" {
+; CHECK-LABEL: foo:
+; CHECK-LABEL: .Lfunc_begin0:
+; CHECK:       .p2align 2
+; CHECK-LABEL: .Lxray_sled_begin0:
+; CHECK-NEXT:  b .Lxray_sled_end0
+; CHECK-COUNT-11:  nop
+; CHECK-LABEL: .Lxray_sled_end0:
+  ret i32 0
+; CHECK-LABEL: .Lxray_sled_begin1:
+; CHECK-NEXT:  b .Lxray_sled_end1
+; CHECK-COUNT-11:  nop
+; CHECK-NEXT: .Lxray_sled_end1:
+; CHECK-NEXT:  ret
+; CHECK-NEXT: .Lfunc_end0:
+}
+
+; CHECK-LABEL: .section xray_instr_map
+; CHECK-NEXT: .Lxray_sleds_start0:
+; CHECK-NEXT: [[TMP:.Ltmp[0-9]+]]:
+; CHECK-NEXT: .dword .Lxray_sled_begin0-[[TMP]]
+; CHECK-NEXT: .dword .Lfunc_begin0-([[TMP]]+8)
+; CHECK-NEXT: .byte 0x00
+; CHECK-NEXT: .byte 0x01
+; CHECK-NEXT: .byte 0x02
+; CHECK-NEXT: .space 13
+; CHECK-NEXT: [[TMP:.Ltmp[0-9]+]]:
+; CHECK-NEXT: .dword .Lxray_sled_begin1-[[TMP]]
+; CHECK-NEXT: .dword .Lfunc_begin0-([[TMP]]+8)
+; CHECK-NEXT: .byte 0x01
+; CHECK-NEXT: .byte 0x01
+; CHECK-NEXT: .byte 0x02
+; CHECK-NEXT: .space 13
+; CHECK-NEXT: .Lxray_sleds_end0:
+
+; CHECK-LABEL:  .section xray_fn_idx
+; CHECK:      [[IDX:.Lxray_fn_idx[0-9]+]]:
+; CHECK:      .dword .Lxray_sleds_start0-[[IDX]]
+; CHECK-NEXT: .dword 2
+
+; RELOC:      Section ([[#]]) .relaxray_instr_map {
+; RELOC-NEXT:   0x0 R_LARCH_64_PCREL .text 0x0
+; RELOC-NEXT:   0x8 R_LARCH_64_PCREL .text 0x0
+; RELOC-NEXT:   0x20 R_LARCH_64_PCREL .text 0x34
+; RELOC-NEXT:   0x28 R_LARCH_64_PCREL .text 0x0
+; RELOC-NEXT: }
+; RELOC-NEXT: Section ([[#]]) .relaxray_fn_idx {
+; RELOC-NEXT:   0x0 R_LARCH_64_PCREL xray_instr_map 0x0
+; RELOC-NEXT: }
+; RELOC-NEXT: Section ([[#]]) .rela.eh_frame {
+; RELOC-NEXT:   0x1C R_LARCH_32_PCREL .text 0x0
+; RELOC-NEXT: }
Index: llvm/lib/XRay/InstrumentationMap.cpp
===================================================================
--- llvm/lib/XRay/InstrumentationMap.cpp
+++ llvm/lib/XRay/InstrumentationMap.cpp
@@ -60,6 +60,7 @@
   // Find the section named "xray_instr_map".
   if ((!ObjFile.getBinary()->isELF() && !ObjFile.getBinary()->isMachO()) ||
       !(ObjFile.getBinary()->getArch() == Triple::x86_64 ||
+        ObjFile.getBinary()->getArch() == Triple::loongarch64 ||
         ObjFile.getBinary()->getArch() == Triple::ppc64le ||
         ObjFile.getBinary()->getArch() == Triple::arm ||
         ObjFile.getBinary()->getArch() == Triple::aarch64))
Index: llvm/lib/Target/LoongArch/LoongArchSubtarget.h
===================================================================
--- llvm/lib/Target/LoongArch/LoongArchSubtarget.h
+++ llvm/lib/Target/LoongArch/LoongArchSubtarget.h
@@ -96,6 +96,7 @@
   MVT getGRLenVT() const { return GRLenVT; }
   unsigned getGRLen() const { return GRLen; }
   LoongArchABI::ABI getTargetABI() const { return TargetABI; }
+  bool isXRaySupported() const override { return is64Bit(); }
 };
 } // end namespace llvm
 
Index: llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h
===================================================================
--- llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h
+++ llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h
@@ -42,6 +42,9 @@
                              const char *ExtraCode, raw_ostream &OS) override;
 
   void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI);
+  void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI);
+  void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI);
+  void emitSled(const MachineInstr &MI, SledKind Kind);
 
   // tblgen'erated function.
   bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
Index: llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
+++ llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
@@ -17,6 +17,8 @@
 #include "MCTargetDesc/LoongArchInstPrinter.h"
 #include "TargetInfo/LoongArchTargetInfo.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstBuilder.h"
 #include "llvm/MC/TargetRegistry.h"
 
 using namespace llvm;
@@ -39,6 +41,12 @@
   case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
     LowerPATCHABLE_FUNCTION_ENTER(*MI);
     return;
+  case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
+    LowerPATCHABLE_FUNCTION_EXIT(*MI);
+    return;
+  case TargetOpcode::PATCHABLE_TAIL_CALL:
+    LowerPATCHABLE_TAIL_CALL(*MI);
+    return;
   }
 
   MCInst TmpInst;
@@ -129,11 +137,46 @@
     return;
   }
 
-  // TODO: Emit sled here once we get support for XRay.
+  emitSled(MI, SledKind::FUNCTION_ENTER);
+}
+
+void LoongArchAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI) {
+  emitSled(MI, SledKind::FUNCTION_EXIT);
+}
+
+void LoongArchAsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI) {
+  emitSled(MI, SledKind::TAIL_CALL);
+}
+
+void LoongArchAsmPrinter::emitSled(const MachineInstr &MI, SledKind Kind) {
+  // For loongarch64 we want to emit the following pattern:
+  //
+  // .Lxray_sled_beginN:
+  //   B .Lxray_sled_endN
+  //   11 NOPs (44 bytes)
+  // .Lxray_sled_endN:
+  //
+  // We need the extra bytes because at runtime they may be used for the
+  // actual pattern defined at compiler-rt/lib/xray/xray_loongarch64.cpp.
+  // The count here should be adjusted accordingly if the implementation
+  // changes.
+  const int8_t NoopsInSledCount = 11;
+  OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo());
+  MCSymbol *BeginOfSled = OutContext.createTempSymbol("xray_sled_begin");
+  MCSymbol *EndOfSled = OutContext.createTempSymbol("xray_sled_end");
+  OutStreamer->emitLabel(BeginOfSled);
+  EmitToStreamer(*OutStreamer,
+                 MCInstBuilder(LoongArch::B)
+                     .addExpr(MCSymbolRefExpr::create(EndOfSled, OutContext)));
+  emitNops(NoopsInSledCount);
+  OutStreamer->emitLabel(EndOfSled);
+  recordSled(BeginOfSled, MI, Kind, 2);
 }
 
 bool LoongArchAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   AsmPrinter::runOnMachineFunction(MF);
+  // Emit the XRay table for this function.
+  emitXRayTable();
   return true;
 }
 
Index: llvm/lib/CodeGen/XRayInstrumentation.cpp
===================================================================
--- llvm/lib/CodeGen/XRayInstrumentation.cpp
+++ llvm/lib/CodeGen/XRayInstrumentation.cpp
@@ -226,6 +226,7 @@
     case Triple::ArchType::thumb:
     case Triple::ArchType::aarch64:
     case Triple::ArchType::hexagon:
+    case Triple::ArchType::loongarch64:
     case Triple::ArchType::mips:
     case Triple::ArchType::mipsel:
     case Triple::ArchType::mips64:
Index: compiler-rt/test/xray/TestCases/Posix/fdr-thread-order.cpp
===================================================================
--- compiler-rt/test/xray/TestCases/Posix/fdr-thread-order.cpp
+++ compiler-rt/test/xray/TestCases/Posix/fdr-thread-order.cpp
@@ -8,7 +8,7 @@
 // RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t.exe %t/* | \
 // RUN:   FileCheck %s --check-prefix TRACE
 
-// REQUIRES: target={{(aarch64|x86_64)-.*}}
+// REQUIRES: target={{(aarch64|loongarch64|x86_64)-.*}}
 // REQUIRES: built-in-llvm-tree
 
 #include "xray/xray_log_interface.h"
Index: compiler-rt/test/xray/TestCases/Posix/c-test.cpp
===================================================================
--- compiler-rt/test/xray/TestCases/Posix/c-test.cpp
+++ compiler-rt/test/xray/TestCases/Posix/c-test.cpp
@@ -4,7 +4,7 @@
 // RUN:     2>&1 | FileCheck %s
 // RUN: rm -f xray-log.c-test.*
 //
-// REQUIRES: target={{(aarch64|x86_64)-.*}}
+// REQUIRES: target={{(aarch64|loongarch64|x86_64)-.*}}
 // REQUIRES: built-in-llvm-tree
 __attribute__((xray_always_instrument)) void always() {}
 
Index: compiler-rt/lib/xray/xray_tsc.h
===================================================================
--- compiler-rt/lib/xray/xray_tsc.h
+++ compiler-rt/lib/xray/xray_tsc.h
@@ -43,7 +43,7 @@
 #elif defined(__powerpc64__)
 #include "xray_powerpc64.inc"
 #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) ||         \
-    defined(__hexagon__)
+    defined(__hexagon__) || defined(__loongarch_lp64)
 // Emulated TSC.
 // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does
 //   not have a constant frequency like TSC on x86(_64), it may go faster
Index: compiler-rt/lib/xray/xray_trampoline_loongarch64.S
===================================================================
--- /dev/null
+++ compiler-rt/lib/xray/xray_trampoline_loongarch64.S
@@ -0,0 +1,124 @@
+//===-- xray_trampoline_loongarch64.s ---------------------------*- ASM -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// This implements the loongarch-specific assembler for the trampolines.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../sanitizer_common/sanitizer_asm.h"
+
+#define FROM_0_TO_7 0,1,2,3,4,5,6,7
+#define FROM_7_TO_0 7,6,5,4,3,2,1,0
+
+.macro SAVE_ARG_REGISTERS
+  .irp i,FROM_7_TO_0
+    st.d  $a\i, $sp, (8 * 8 + 8 * \i)
+  .endr
+  .irp i,FROM_7_TO_0
+    fst.d $f\i, $sp, (8 * \i)
+  .endr
+.endm
+
+.macro RESTORE_ARG_REGISTERS
+  .irp i,FROM_0_TO_7
+    fld.d $f\i, $sp, (8 * \i)
+  .endr
+  .irp i,FROM_0_TO_7
+    ld.d  $a\i, $sp, (8 * 8 + 8 * \i)
+  .endr
+.endm
+
+.macro SAVE_RET_REGISTERS
+  st.d    $a1, $sp, 24
+  st.d    $a0, $sp, 16
+  fst.d   $f1, $sp, 8
+  fst.d   $f0, $sp, 0
+.endm
+
+.macro RESTORE_RET_REGISTERS
+  fld.d   $f0, $sp, 0
+  fld.d   $f1, $sp, 8
+  ld.d    $a0, $sp, 16
+  ld.d    $a1, $sp, 24
+.endm
+
+  .text
+  .file "xray_trampoline_loongarch64.S"
+  .globl ASM_SYMBOL(__xray_FunctionEntry)
+  ASM_HIDDEN(__xray_FunctionEntry)
+  .p2align 2
+  ASM_TYPE_FUNCTION(__xray_FunctionEntry)
+ASM_SYMBOL(__xray_FunctionEntry):
+  .cfi_startproc
+  // Save argument registers before doing any actual work.
+  .cfi_def_cfa_offset 136
+  addi.d  $sp, $sp, -136
+  st.d    $ra, $sp, 128
+  .cfi_offset 1, -8
+  SAVE_ARG_REGISTERS
+
+  la.got  $t2, ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)
+  ld.d    $t2, $t2, 0
+
+  beqz    $t2, FunctionEntry_restore
+
+  // a1=0 means that we are tracing an entry event.
+  move    $a1, $zero
+  // Function ID is in t1 (the first parameter).
+  move    $a0, $t1
+  jirl    $ra, $t2, 0
+
+FunctionEntry_restore:
+  // Restore argument registers.
+  RESTORE_ARG_REGISTERS
+  ld.d    $ra, $sp, 128
+  addi.d  $sp, $sp, 136
+  ret
+FunctionEntry_end:
+  ASM_SIZE(__xray_FunctionEntry)
+  .cfi_endproc
+
+  .text
+  .globl ASM_SYMBOL(__xray_FunctionExit)
+  ASM_HIDDEN(__xray_FunctionExit)
+  .p2align 2
+  ASM_TYPE_FUNCTION(__xray_FunctionExit)
+ASM_SYMBOL(__xray_FunctionExit):
+  .cfi_startproc
+  // Save return registers before doing any actual work.
+  .cfi_def_cfa_offset 48
+  addi.d  $sp, $sp, -48
+  st.d    $ra, $sp, 40
+  .cfi_offset 1, -8
+  st.d    $fp, $sp, 32
+  SAVE_RET_REGISTERS
+
+  la.got  $t2, ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)
+  ld.d    $t2, $t2, 0
+
+  beqz    $t2, FunctionExit_restore
+
+  // a1=1 means that we are tracing an exit event.
+  li.w    $a1, 1
+  // Function ID is in t1 (the first parameter).
+  move    $a0, $t1
+  jirl    $ra, $t2, 0
+
+FunctionExit_restore:
+  // Restore return registers.
+  RESTORE_RET_REGISTERS
+  ld.d    $fp, $sp, 32
+  ld.d    $ra, $sp, 40
+  addi.d  $sp, $sp, 48
+  ret
+
+FunctionExit_end:
+  ASM_SIZE(__xray_FunctionExit)
+  .cfi_endproc
Index: compiler-rt/lib/xray/xray_loongarch64.cpp
===================================================================
--- /dev/null
+++ compiler-rt/lib/xray/xray_loongarch64.cpp
@@ -0,0 +1,160 @@
+//===-------- xray_loongarch64.cpp ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// Implementation of loongarch-specific routines.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_common.h"
+#include "xray_defs.h"
+#include "xray_interface_internal.h"
+#include <atomic>
+
+namespace __xray {
+
+enum RegNum : uint32_t {
+  RN_RA = 1,
+  RN_SP = 3,
+  RN_T0 = 12,
+  RN_T1 = 13,
+};
+
+// Encode instructions in the 2RIx format, where the primary formats here
+// are 2RI12-type and 2RI16-type.
+static inline uint32_t
+encodeInstruction2RIx(uint32_t Opcode, uint32_t Rd, uint32_t Rj,
+                      uint32_t Imm) XRAY_NEVER_INSTRUMENT {
+  return Opcode | (Imm << 10) | (Rj << 5) | Rd;
+}
+
+// Encode instructions in 1RI20 format, e.g. lu12i.w/lu32i.d.
+static inline uint32_t
+encodeInstruction1RI20(uint32_t Opcode, uint32_t Rd,
+                       uint32_t Imm) XRAY_NEVER_INSTRUMENT {
+  return Opcode | (Imm << 5) | Rd;
+}
+
+static inline bool patchSled(const bool Enable, const uint32_t FuncId,
+                             const XRaySledEntry &Sled,
+                             void (*TracingHook)()) XRAY_NEVER_INSTRUMENT {
+  // When |Enable| == true,
+  // We replace the following compile-time stub (sled):
+  //
+  // .Lxray_sled_beginN:
+  //	B .Lxray_sled_endN
+  //	11 NOPs (44 bytes)
+  // .Lxray_sled_endN:
+  //
+  // With the following runtime patch:
+  //
+  // xray_sled_n:
+  //   addi.d  sp, sp, -16                       ; create the stack frame
+  //   st.d    ra, sp, 8                         ; save the return address
+  //   lu12i.w t0, %abs_hi20(__xray_FunctionEntry/Exit)
+  //   ori     t0, t0, %abs_lo12(__xray_FunctionEntry/Exit)
+  //   lu32i.d t0, %abs64_lo20(__xray_FunctionEntry/Exit)
+  //   lu52i.d t0, t0, %abs64_hi12(__xray_FunctionEntry/Exit)
+  //   lu12i.w t1, %abs_hi20(function_id)
+  //   ori     t1, t1, %abs_lo12(function_id)    ; pass the function id
+  //   jirl    ra, t0, 0                         ; call the tracing hook
+  //   ld.d    ra, sp, 8                         ; restore the return address
+  //   addi.d  sp, sp, 16                        ; de-allocate the stack frame
+  //
+  // Replacement of the first 4-byte instruction should be the last and atomic
+  // operation, so that the user code which reaches the sled concurrently
+  // either jumps over the whole sled, or executes the whole sled when the
+  // latter is ready.
+  //
+  // When |Enable|==false, we set the first instruction in the sled back to
+  //   B #48
+
+  uint32_t *Address = reinterpret_cast<uint32_t *>(Sled.address());
+  if (Enable) {
+    uint32_t LoTracingHookAddr = reinterpret_cast<int64_t>(TracingHook) & 0xfff;
+    uint32_t HiTracingHookAddr =
+        (reinterpret_cast<int64_t>(TracingHook) >> 12) & 0xfffff;
+    uint32_t HigherTracingHookAddr =
+        (reinterpret_cast<int64_t>(TracingHook) >> 32) & 0xfffff;
+    uint32_t HighestTracingHookAddr =
+        (reinterpret_cast<int64_t>(TracingHook) >> 52) & 0xfff;
+    uint32_t LoFunctionID = FuncId & 0xfff;
+    uint32_t HiFunctionID = (FuncId >> 12) & 0xfffff;
+    Address[1] = encodeInstruction2RIx(0x29c00000, RegNum::RN_RA, RegNum::RN_SP,
+                                       0x8); // st.d ra, sp, 8
+    Address[2] = encodeInstruction1RI20(
+        0x14000000, RegNum::RN_T0,
+        HiTracingHookAddr); // lu12i.w t0, HiTracingHookAddr
+    Address[3] = encodeInstruction2RIx(
+        0x03800000, RegNum::RN_T0, RegNum::RN_T0,
+        LoTracingHookAddr); // ori t0, t0, LoTracingHookAddr
+    Address[4] = encodeInstruction1RI20(
+        0x16000000, RegNum::RN_T0,
+        HigherTracingHookAddr); // lu32i.d t0, HigherTracingHookAddr
+    Address[5] = encodeInstruction2RIx(
+        0x03000000, RegNum::RN_T0, RegNum::RN_T0,
+        HighestTracingHookAddr); // lu52i.d t0, t0, HighestTracingHookAddr
+    Address[6] =
+        encodeInstruction1RI20(0x14000000, RegNum::RN_T1,
+                               HiFunctionID); // lu12i.w t1, HiFunctionID
+    Address[7] =
+        encodeInstruction2RIx(0x03800000, RegNum::RN_T1, RegNum::RN_T1,
+                              LoFunctionID); // ori t1, t1, LoFunctionID
+    Address[8] = encodeInstruction2RIx(0x4c000000, RegNum::RN_RA, RegNum::RN_T0,
+                                       0); // jirl ra, t0, 0
+    Address[9] = encodeInstruction2RIx(0x28c00000, RegNum::RN_RA, RegNum::RN_SP,
+                                       0x8); // ld.d ra, sp, 8
+    Address[10] = encodeInstruction2RIx(
+        0x02c00000, RegNum::RN_SP, RegNum::RN_SP, 0x10); // addi.d sp, sp, 16
+    uint32_t CreateStackSpace = encodeInstruction2RIx(
+        0x02c00000, RegNum::RN_SP, RegNum::RN_SP, 0xff0); // addi.d sp, sp, -16
+    std::atomic_store_explicit(
+        reinterpret_cast<std::atomic<uint32_t> *>(Address), CreateStackSpace,
+        std::memory_order_release);
+  } else {
+    std::atomic_store_explicit(
+        reinterpret_cast<std::atomic<uint32_t> *>(Address),
+        uint32_t(0x50003000), std::memory_order_release); // b #48
+  }
+  return true;
+}
+
+bool patchFunctionEntry(const bool Enable, const uint32_t FuncId,
+                        const XRaySledEntry &Sled,
+                        void (*Trampoline)()) XRAY_NEVER_INSTRUMENT {
+  return patchSled(Enable, FuncId, Sled, Trampoline);
+}
+
+bool patchFunctionExit(const bool Enable, const uint32_t FuncId,
+                       const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
+}
+
+bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
+                           const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  // TODO: In the future we'd need to distinguish between non-tail exits and
+  // tail exits for better information preservation.
+  return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
+}
+
+bool patchCustomEvent(const bool Enable, const uint32_t FuncId,
+                      const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  // FIXME: Implement in loongarch?
+  return false;
+}
+
+bool patchTypedEvent(const bool Enable, const uint32_t FuncId,
+                     const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  // FIXME: Implement in loongarch?
+  return false;
+}
+} // namespace __xray
+
+extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT {
+  // TODO: This will have to be implemented in the trampoline assembly file.
+}
Index: compiler-rt/lib/xray/xray_interface.cpp
===================================================================
--- compiler-rt/lib/xray/xray_interface.cpp
+++ compiler-rt/lib/xray/xray_interface.cpp
@@ -46,6 +46,8 @@
 static const int16_t cSledLength = 32;
 #elif defined(__arm__)
 static const int16_t cSledLength = 28;
+#elif SANITIZER_LOONGARCH64
+static const int16_t cSledLength = 48;
 #elif SANITIZER_MIPS32
 static const int16_t cSledLength = 48;
 #elif SANITIZER_MIPS64
Index: compiler-rt/lib/xray/CMakeLists.txt
===================================================================
--- compiler-rt/lib/xray/CMakeLists.txt
+++ compiler-rt/lib/xray/CMakeLists.txt
@@ -47,6 +47,11 @@
   xray_trampoline_AArch64.S
   )
 
+set(loongarch64_SOURCES
+  xray_loongarch64.cpp
+  xray_trampoline_loongarch64.S
+  )
+
 set(mips_SOURCES
   xray_mips.cpp
   xray_trampoline_mips.S
@@ -130,6 +135,7 @@
   ${arm_SOURCES}
   ${armhf_SOURCES}
   ${hexagon_SOURCES}
+  ${loongarch64_SOURCES}
   ${mips_SOURCES}
   ${mipsel_SOURCES}
   ${mips64_SOURCES}
Index: compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
===================================================================
--- compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -80,7 +80,7 @@
 set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM64})
 else()
 set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64}
-		powerpc64le ${HEXAGON})
+		powerpc64le ${HEXAGON} ${LOONGARCH64})
 endif()
 set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64})
 
Index: clang/lib/Driver/XRayArgs.cpp
===================================================================
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -48,6 +48,7 @@
     case llvm::Triple::aarch64:
     case llvm::Triple::hexagon:
     case llvm::Triple::ppc64le:
+    case llvm::Triple::loongarch64:
     case llvm::Triple::mips:
     case llvm::Triple::mipsel:
     case llvm::Triple::mips64:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to