[llvm] 65a2f6a - [Hexagon] Create an intrinsic to profile using a custom handler
Jyotsna Verma via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 28 08:34:29 PDT 2022
Author: Jyotsna Verma
Date: 2022-03-28T10:31:41-05:00
New Revision: 65a2f6ad9c652536d7c394cad2ac83d306e6b587
URL: https://github.com/llvm/llvm-project/commit/65a2f6ad9c652536d7c394cad2ac83d306e6b587
DIFF: https://github.com/llvm/llvm-project/commit/65a2f6ad9c652536d7c394cad2ac83d306e6b587.diff
LOG: [Hexagon] Create an intrinsic to profile using a custom handler
The intrinsic is lowered into a hexagon pseudo instruction which
after register allocation is expanded into A2_tfrsi and J2_call.
Added:
llvm/test/CodeGen/Hexagon/instrprof-custom.ll
Modified:
llvm/include/llvm/IR/IntrinsicsHexagon.td
llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
llvm/lib/Target/Hexagon/HexagonPatterns.td
llvm/lib/Target/Hexagon/HexagonPseudo.td
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/IntrinsicsHexagon.td b/llvm/include/llvm/IR/IntrinsicsHexagon.td
index 212262c287063..e15d974676dc0 100644
--- a/llvm/include/llvm/IR/IntrinsicsHexagon.td
+++ b/llvm/include/llvm/IR/IntrinsicsHexagon.td
@@ -404,4 +404,15 @@ def int_hexagon_V6_vmaskedstorenq_128B: Hexagon_custom_vms_Intrinsic_128B;
def int_hexagon_V6_vmaskedstorentq_128B: Hexagon_custom_vms_Intrinsic_128B;
def int_hexagon_V6_vmaskedstorentnq_128B: Hexagon_custom_vms_Intrinsic_128B;
+
+// Intrinsic for instrumentation based profiling using a custom handler. The
+// name of the handler is passed as the first operand to the intrinsic. The
+// handler can take only one int32 input which is passed as the second
+// operand to the intrinsic.
+def int_hexagon_instrprof_custom
+ : Hexagon_NonGCC_Intrinsic<[],
+ [llvm_ptr_ty, llvm_i32_ty],
+ [IntrInaccessibleMemOnly]>;
+
+
include "llvm/IR/IntrinsicsHexagonDep.td"
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index b40b63d011f34..c5fe88edf9760 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -1072,6 +1072,43 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
};
switch (Opc) {
+ case Hexagon::PS_call_instrprof_custom: {
+ auto Op0 = MI.getOperand(0);
+ assert(Op0.isGlobal() &&
+ "First operand must be a global containing handler name.");
+ const GlobalValue *NameVar = Op0.getGlobal();
+ const GlobalVariable *GV = dyn_cast<GlobalVariable>(NameVar);
+ auto *Arr = cast<ConstantDataArray>(GV->getInitializer());
+ StringRef NameStr = Arr->isCString() ? Arr->getAsCString() : Arr->getAsString();
+
+ MachineOperand &Op1 = MI.getOperand(1);
+ // Set R0 with the imm value to be passed to the custom profiling handler.
+ BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrsi), Hexagon::R0)
+ .addImm(Op1.getImm());
+ // The call to the custom handler is being treated as a special one as the
+ // callee is responsible for saving and restoring all the registers
+ // (including caller saved registers) it needs to modify. This is
+ // done to reduce the impact of instrumentation on the code being
+ // instrumented/profiled.
+ // NOTE: R14, R15 and R28 are reserved for PLT handling. These registers
+ // are in the Def list of the Hexagon::PS_call_instrprof_custom and
+ // therefore will be handled appropriately duing register allocation.
+
+ // TODO: It may be a good idea to add a separate pseudo instruction for
+ // static relocation which doesn't need to reserve r14, r15 and r28.
+
+ auto MIB = BuildMI(MBB, MI, DL, get(Hexagon::J2_call))
+ .addUse(Hexagon::R0, RegState::Implicit|RegState::InternalRead)
+ .addDef(Hexagon::R29, RegState::ImplicitDefine)
+ .addDef(Hexagon::R30, RegState::ImplicitDefine)
+ .addDef(Hexagon::R14, RegState::ImplicitDefine)
+ .addDef(Hexagon::R15, RegState::ImplicitDefine)
+ .addDef(Hexagon::R28, RegState::ImplicitDefine);
+ const char *cstr = MF.createExternalSymbolName(NameStr);
+ MIB.addExternalSymbol(cstr);
+ MBB.erase(MI);
+ return true;
+ }
case TargetOpcode::COPY: {
MachineOperand &MD = MI.getOperand(0);
MachineOperand &MS = MI.getOperand(1);
diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index 3abbd896c5192..80fbf33d83b70 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -3273,3 +3273,9 @@ let AddedComplexity = 100 in {
def: Pat<(i1 (seteq (int_hexagon_S4_stored_locked I32:$Rs, I64:$Rt), 0)),
(C2_not (S4_stored_locked I32:$Rs, I64:$Rt))>;
}
+
+def: Pat<(int_hexagon_instrprof_custom (HexagonAtPcrel tglobaladdr:$addr), u32_0ImmPred:$I),
+ (PS_call_instrprof_custom tglobaladdr:$addr, imm:$I)>;
+
+def: Pat<(int_hexagon_instrprof_custom (HexagonCONST32 tglobaladdr:$addr), u32_0ImmPred:$I),
+ (PS_call_instrprof_custom tglobaladdr:$addr, imm:$I)>;
diff --git a/llvm/lib/Target/Hexagon/HexagonPseudo.td b/llvm/lib/Target/Hexagon/HexagonPseudo.td
index afd63d6d4aa7c..7c45568f7734c 100644
--- a/llvm/lib/Target/Hexagon/HexagonPseudo.td
+++ b/llvm/lib/Target/Hexagon/HexagonPseudo.td
@@ -182,6 +182,28 @@ let isCodeGenOnly = 1, isCall = 1, hasSideEffects = 1,
Defs = [PC, R31, R6, R7, P0] in
def PS_call_stk : T_Call<"">;
+// This pseudo instruction is used to replace int_hexagon_instrprof_custom intrinsic
+// with a call to custom handler passed as the first argument to the intrinsic.
+
+// Pleae Note:
+// 1) The call to the custom handler is being treated as a special one as the
+// callee is responsible for saving and restoring all the registers it needs
+// to modify. This includes caller saved registers as well as r0-r5 argument
+// registers. This is done to reduce the impact of instrumentation on the
+// code being instrumented/profiled.
+// 2) R14, R15 and R28 are reserved for PLT handling and therefore are
+// part of the def list.
+// 3) R0 is used to pass the unique id associated with an instrumentation site
+// to the handler.
+// 4) All the other registers (R29, R30, R31, PC) get modified by the call
+// instruction.
+
+// TODO: It may be a good idea to add a separate pseudo instruction for
+// static relocation which doesn't need to reserve r14, r15 and r28.
+
+let hasSideEffects = 1, isCall = 1, Defs = [R0, R14, R15, R28, R29, R30, R31, PC] in
+def PS_call_instrprof_custom : Pseudo<(outs), (ins s32_0Imm:$dst, u32_0Imm:$Ii), "">;
+
// Call, no return.
let isCall = 1, hasSideEffects = 1, cofMax1 = 1, isCodeGenOnly = 1 in
def PS_callr_nr: InstHexagon<(outs), (ins IntRegs:$Rs),
diff --git a/llvm/test/CodeGen/Hexagon/instrprof-custom.ll b/llvm/test/CodeGen/Hexagon/instrprof-custom.ll
new file mode 100644
index 0000000000000..e3c729842d544
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/instrprof-custom.ll
@@ -0,0 +1,20 @@
+; RUN: llc -march=hexagon -relocation-model=pic < %s | FileCheck %s
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; CHECK-LABEL: test1:
+; CHECK: {{call my_instrprof_handler|r0 = #999}}
+; CHECK-NEXT: {{call my_instrprof_handler|r0 = #999}}
+
+ at handler_name = internal constant [21 x i8] c"my_instrprof_handler\00"
+
+define dllexport void @test1() local_unnamed_addr #0 {
+entry:
+ tail call void @llvm.hexagon.instrprof.custom(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @handler_name, i32 0, i32 0), i32 999)
+ ret void
+}
+
+; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
+declare void @llvm.hexagon.instrprof.custom(i8*, i32) #1
+
+attributes #0 = { "target-features"="+hvxv68,+hvx-length128b,+hvx-qfloat,-hvx-ieee-fp,+hmxv68" }
+attributes #1 = { inaccessiblememonly nofree nosync nounwind willreturn }
More information about the llvm-commits
mailing list