xen0n created this revision.
xen0n added reviewers: SixWeining, wangleiat, gonglingqin, MaskRay, xry111.
Herald added subscribers: luismarques, s.egerton, PkmX, simoncook, hiraditya, 
arichardson.
Herald added a reviewer: aaron.ballman.
Herald added a project: All.
xen0n requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, pcwang-thead.
Herald added projects: clang, LLVM.

Similar to D98610 <https://reviews.llvm.org/D98610> for RISCV.

This is going to be required by the upcoming Linux/LoongArch
[[ support for dynamic ftrace | https://git.kernel.org/linus/4733f09d88074 ]].


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141785

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/fpatchable-function-entry.c
  clang/test/Sema/patchable-function-entry-attr.cpp
  llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
  llvm/lib/Target/LoongArch/LoongArchInstrInfo.h
  llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
  llvm/test/CodeGen/LoongArch/patchable-function-entry.ll

Index: llvm/test/CodeGen/LoongArch/patchable-function-entry.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/LoongArch/patchable-function-entry.ll
@@ -0,0 +1,62 @@
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefixes=CHECK,LA32
+; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefixes=CHECK,LA64
+
+define void @f0() "patchable-function-entry"="0" {
+; CHECK-LABEL: f0:
+; CHECK-NEXT:  .Lfunc_begin0:
+; CHECK-NOT:     nop
+; CHECK:         ret
+; CHECK-NOT:   .section __patchable_function_entries
+  ret void
+}
+
+define void @f1() "patchable-function-entry"="1" {
+; CHECK-LABEL: f1:
+; CHECK-NEXT: .Lfunc_begin1:
+; CHECK:         nop
+; CHECK-NEXT:    ret
+; CHECK:       .section __patchable_function_entries,"awo",@progbits,f1{{$}}
+; LA32:        .p2align 2
+; LA32-NEXT:   .word .Lfunc_begin1
+; LA64:        .p2align 3
+; LA64-NEXT:   .dword .Lfunc_begin1
+  ret void
+}
+
+$f5 = comdat any
+define void @f5() "patchable-function-entry"="5" comdat {
+; CHECK-LABEL:   f5:
+; CHECK-NEXT:    .Lfunc_begin2:
+; CHECK-COUNT-5:   nop
+; CHECK-NEXT:      ret
+; CHECK:         .section __patchable_function_entries,"aGwo",@progbits,f5,comdat,f5{{$}}
+; LA32:          .p2align 2
+; LA32-NEXT:     .word .Lfunc_begin2
+; LA64:          .p2align 3
+; LA64-NEXT:     .dword .Lfunc_begin2
+  ret void
+}
+
+;; -fpatchable-function-entry=3,2
+;; "patchable-function-prefix" emits data before the function entry label.
+define void @f3_2() "patchable-function-entry"="1" "patchable-function-prefix"="2" {
+; CHECK-LABEL:   .type f3_2,@function
+; CHECK-NEXT:    .Ltmp0: # @f3_2
+; CHECK-COUNT-2:   nop
+; CHECK-NEXT:    f3_2:
+; CHECK:         # %bb.0:
+; CHECK-NEXT:      nop
+; LA32-NEXT:       addi.w $sp, $sp, -16
+; LA64-NEXT:       addi.d $sp, $sp, -16
+;; .size does not include the prefix.
+; CHECK:      .Lfunc_end3:
+; CHECK-NEXT: .size f3_2, .Lfunc_end3-f3_2
+; CHECK:      .section __patchable_function_entries,"awo",@progbits,f3_2{{$}}
+; LA32:       .p2align 2
+; LA32-NEXT:  .word .Ltmp0
+; LA64:       .p2align 3
+; LA64-NEXT:  .dword .Ltmp0
+  %frame = alloca i8, i32 16
+  ret void
+}
Index: llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
===================================================================
--- llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
+++ llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
@@ -138,5 +138,22 @@
     if (lowerLoongArchMachineOperandToMCOperand(MO, MCOp, AP))
       OutMI.addOperand(MCOp);
   }
+
+  switch (OutMI.getOpcode()) {
+  case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
+    const Function &F = MI->getParent()->getParent()->getFunction();
+    if (F.hasFnAttribute("patchable-function-entry")) {
+      unsigned Num;
+      if (F.getFnAttribute("patchable-function-entry")
+              .getValueAsString()
+              .getAsInteger(10, Num))
+        return false;
+      AP.emitNops(Num);
+      return true;
+    }
+    break;
+  }
+  }
+
   return false;
 }
Index: llvm/lib/Target/LoongArch/LoongArchInstrInfo.h
===================================================================
--- llvm/lib/Target/LoongArch/LoongArchInstrInfo.h
+++ llvm/lib/Target/LoongArch/LoongArchInstrInfo.h
@@ -27,6 +27,8 @@
 public:
   explicit LoongArchInstrInfo(LoongArchSubtarget &STI);
 
+  MCInst getNop() const override;
+
   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
                    const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg,
                    bool KillSrc) const override;
Index: llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
===================================================================
--- llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
+++ llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
@@ -17,6 +17,7 @@
 #include "MCTargetDesc/LoongArchMCTargetDesc.h"
 #include "MCTargetDesc/LoongArchMatInt.h"
 #include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/MC/MCInstBuilder.h"
 
 using namespace llvm;
 
@@ -28,6 +29,13 @@
                             LoongArch::ADJCALLSTACKUP),
       STI(STI) {}
 
+MCInst LoongArchInstrInfo::getNop() const {
+  return MCInstBuilder(LoongArch::ANDI)
+      .addReg(LoongArch::R0)
+      .addReg(LoongArch::R0)
+      .addImm(0);
+}
+
 void LoongArchInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                                      MachineBasicBlock::iterator MBBI,
                                      const DebugLoc &DL, MCRegister DstReg,
Index: clang/test/Sema/patchable-function-entry-attr.cpp
===================================================================
--- clang/test/Sema/patchable-function-entry-attr.cpp
+++ clang/test/Sema/patchable-function-entry-attr.cpp
@@ -2,6 +2,8 @@
 // RUN: %clang_cc1 -triple aarch64_be -fsyntax-only -verify=silence %s
 // RUN: %clang_cc1 -triple i386 -fsyntax-only -verify=silence %s
 // RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify=silence %s
+// RUN: %clang_cc1 -triple loongarch32 -fsyntax-only -verify=silence %s
+// RUN: %clang_cc1 -triple loongarch64 -fsyntax-only -verify=silence %s
 // RUN: %clang_cc1 -triple riscv32 -fsyntax-only -verify=silence %s
 // RUN: %clang_cc1 -triple riscv64 -fsyntax-only -verify=silence %s
 // RUN: %clang_cc1 -triple ppc64le -fsyntax-only -verify %s
Index: clang/test/Driver/fpatchable-function-entry.c
===================================================================
--- clang/test/Driver/fpatchable-function-entry.c
+++ clang/test/Driver/fpatchable-function-entry.c
@@ -2,6 +2,8 @@
 // RUN: %clang -target x86_64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s
 // RUN: %clang -target aarch64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s
 // RUN: %clang -target aarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
+// RUN: %clang -target loongarch32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
+// RUN: %clang -target loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
 // RUN: %clang -target riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
 // RUN: %clang -target riscv64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
 // CHECK: "-fpatchable-function-entry=1"
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -6203,7 +6203,8 @@
   if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ)) {
     StringRef S0 = A->getValue(), S = S0;
     unsigned Size, Offset = 0;
-    if (!Triple.isAArch64() && !Triple.isRISCV() && !Triple.isX86())
+    if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() &&
+        !Triple.isX86())
       D.Diag(diag::err_drv_unsupported_opt_for_target)
           << A->getAsString(Args) << TripleStr;
     else if (S.consumeInteger(10, Size) ||
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -5315,7 +5315,7 @@
 ``M`` defaults to 0 if omitted.
 
 This attribute is only supported on
-aarch64/aarch64-be/riscv32/riscv64/i386/x86-64 targets.
+aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64 targets.
 }];
 }
 
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -792,7 +792,8 @@
 def PatchableFunctionEntry
     : InheritableAttr,
       TargetSpecificAttr<TargetArch<
-          ["aarch64", "aarch64_be", "riscv32", "riscv64", "x86", "x86_64"]>> {
+          ["aarch64", "aarch64_be", "loongarch32", "loongarch64", "riscv32",
+           "riscv64", "x86", "x86_64"]>> {
   let Spellings = [GCC<"patchable_function_entry">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;
   let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>];
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to