Skip to content

Commit 0143d1d

Browse files
committed
[llvm-exegesis] Implement the loop repetition mode for AArch64
Subject says it all: implement the loop iterator decrement and jump function functions, and reserve X19 for the loop counter.
1 parent d67dba5 commit 0143d1d

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
REQUIRES: aarch64-registered-target, asserts
2+
3+
RUN: llvm-exegesis -mcpu=neoverse-v2 --use-dummy-perf-counters --mode=latency --debug-only=print-gen-assembly --opcode-name=ADDVv4i16v -repetition-mode=loop 2>&1 | FileCheck %s
4+
5+
CHECK: 0: {{.*}} str x19, [sp, #-16]!
6+
CHECK-NEXT: 4: {{.*}} movi d[[REG:[0-9]+]], #0000000000000000
7+
CHECK-NEXT: 8: {{.*}} mov x19, #10000
8+
CHECK-NEXT: c: {{.*}} nop
9+
CHECK-NEXT: 10: {{.*}} nop
10+
CHECK-NEXT: 14: {{.*}} nop
11+
CHECK-NEXT: 18: {{.*}} nop
12+
CHECK-NEXT: 1c: {{.*}} nop
13+
CHECK-NEXT: 20: {{.*}} addv h[[REG]], v[[REG]].4h
14+
CHECK-NEXT: 24: {{.*}} subs x19, x19, #1
15+
CHECK-NEXT: 28: {{.*}} b.ne #-8
16+
CHECK-NEXT: 2c: {{.*}} ldr x19, [sp], #16
17+
CHECK-NEXT: 30: {{.*}} ret

llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "../Target.h"
99
#include "AArch64.h"
1010
#include "AArch64RegisterInfo.h"
11+
#include "llvm/CodeGen/MachineInstrBuilder.h"
1112

1213
#if defined(__aarch64__) && defined(__linux__)
1314
#include <sys/prctl.h> // For PR_PAC_* constants
@@ -109,6 +110,10 @@ static MCInst loadFPImmediate(MCRegister Reg, unsigned RegBitWidth,
109110

110111
namespace {
111112

113+
// Use X19 as the loop counter register since it's a callee-saved register
114+
// that's available for temporary use.
115+
constexpr const MCPhysReg kDefaultLoopCounterReg = AArch64::X19;
116+
112117
class ExegesisAArch64Target : public ExegesisTarget {
113118
public:
114119
ExegesisAArch64Target()
@@ -141,6 +146,31 @@ class ExegesisAArch64Target : public ExegesisTarget {
141146
errs() << "setRegTo is not implemented, results will be unreliable\n";
142147
return {};
143148
}
149+
MCRegister getDefaultLoopCounterRegister(const Triple &) const override {
150+
return kDefaultLoopCounterReg;
151+
}
152+
153+
void decrementLoopCounterAndJump(MachineBasicBlock &MBB,
154+
MachineBasicBlock &TargetMBB,
155+
const MCInstrInfo &MII,
156+
MCRegister LoopRegister) const override {
157+
// subs LoopRegister, LoopRegister, #1
158+
BuildMI(&MBB, DebugLoc(), MII.get(AArch64::SUBSXri))
159+
.addDef(LoopRegister)
160+
.addUse(LoopRegister)
161+
.addImm(1) // Subtract 1
162+
.addImm(0); // No shift amount
163+
// b.ne TargetMBB
164+
BuildMI(&MBB, DebugLoc(), MII.get(AArch64::Bcc))
165+
.addImm(AArch64CC::NE)
166+
.addMBB(&TargetMBB);
167+
}
168+
169+
// Registers that should not be selected for use in snippets.
170+
const MCPhysReg UnavailableRegisters[1] = {kDefaultLoopCounterReg};
171+
ArrayRef<MCPhysReg> getUnavailableRegisters() const override {
172+
return UnavailableRegisters;
173+
}
144174

145175
bool matchesArch(Triple::ArchType Arch) const override {
146176
return Arch == Triple::aarch64 || Arch == Triple::aarch64_be;

0 commit comments

Comments
 (0)