Skip to content

Commit b0ff643

Browse files
committed
[AArch64] Lower READCYCLECOUNTER using MRS PMCCTNR_EL0.
This matches the ARM behavior. In both cases, the register is part of the optional Performance Monitors extension, so, add the feature, and enable it for the A-class processors we support. Differential Revision: http://reviews.llvm.org/D12425 llvm-svn: 246555
1 parent abdb2d2 commit b0ff643

File tree

6 files changed

+40
-6
lines changed

6 files changed

+40
-6
lines changed

llvm/lib/Target/AArch64/AArch64.td

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ def FeatureCrypto : SubtargetFeature<"crypto", "HasCrypto", "true",
3232
def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true",
3333
"Enable ARMv8 CRC-32 checksum instructions">;
3434

35+
def FeaturePerfMon : SubtargetFeature<"perfmon", "HasPerfMon", "true",
36+
"Enable ARMv8 PMUv3 Performance Monitors extension">;
37+
3538
/// Cyclone has register move instructions which are "free".
3639
def FeatureZCRegMove : SubtargetFeature<"zcm", "HasZeroCycleRegMove", "true",
3740
"Has zero-cycle register moves">;
@@ -84,26 +87,30 @@ def ProcA53 : SubtargetFeature<"a53", "ARMProcFamily", "CortexA53",
8487
[FeatureFPARMv8,
8588
FeatureNEON,
8689
FeatureCrypto,
87-
FeatureCRC]>;
90+
FeatureCRC,
91+
FeaturePerfMon]>;
8892

8993
def ProcA57 : SubtargetFeature<"a57", "ARMProcFamily", "CortexA57",
9094
"Cortex-A57 ARM processors",
9195
[FeatureFPARMv8,
9296
FeatureNEON,
9397
FeatureCrypto,
94-
FeatureCRC]>;
98+
FeatureCRC,
99+
FeaturePerfMon]>;
95100

96101
def ProcCyclone : SubtargetFeature<"cyclone", "ARMProcFamily", "Cyclone",
97102
"Cyclone",
98103
[FeatureFPARMv8,
99104
FeatureNEON,
100105
FeatureCrypto,
101106
FeatureCRC,
107+
FeaturePerfMon,
102108
FeatureZCRegMove, FeatureZCZeroing]>;
103109

104110
def : ProcessorModel<"generic", NoSchedModel, [FeatureFPARMv8,
105111
FeatureNEON,
106-
FeatureCRC]>;
112+
FeatureCRC,
113+
FeaturePerfMon]>;
107114

108115
def : ProcessorModel<"cortex-a53", CortexA53Model, [ProcA53]>;
109116
def : ProcessorModel<"cortex-a57", CortexA57Model, [ProcA57]>;

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,11 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
399399

400400
setOperationAction(ISD::PREFETCH, MVT::Other, Custom);
401401

402+
// Lower READCYCLECOUNTER using an mrs from PMCCNTR_EL0.
403+
// This requires the Performance Monitors extension.
404+
if (Subtarget->hasPerfMon())
405+
setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Legal);
406+
402407
if (Subtarget->isTargetMachO()) {
403408
// For iOS, we don't want to the normal expansion of a libcall to
404409
// sincos. We want to issue a libcall to __sincos_stret to avoid memory

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def HasCrypto : Predicate<"Subtarget->hasCrypto()">,
2424
AssemblerPredicate<"FeatureCrypto", "crypto">;
2525
def HasCRC : Predicate<"Subtarget->hasCRC()">,
2626
AssemblerPredicate<"FeatureCRC", "crc">;
27+
def HasPerfMon : Predicate<"Subtarget->hasPerfMon()">;
2728
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
2829
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
2930
def IsCyclone : Predicate<"Subtarget->isCyclone()">;
@@ -404,6 +405,10 @@ def MSRpstate: MSRpstateI;
404405
// TPIDR_EL0.
405406
def : Pat<(AArch64threadpointer), (MRS 0xde82)>;
406407

408+
// The cycle counter PMC register is PMCCNTR_EL0.
409+
let Predicates = [HasPerfMon] in
410+
def : Pat<(readcyclecounter), (MRS 0xdce8)>;
411+
407412
// Generic system instructions
408413
def SYSxt : SystemXtI<0, "sys">;
409414
def SYSLxt : SystemLXtI<1, "sysl">;

llvm/lib/Target/AArch64/AArch64Subtarget.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
4747
const TargetMachine &TM, bool LittleEndian)
4848
: AArch64GenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others),
4949
HasV8_1aOps(false), HasFPARMv8(false), HasNEON(false), HasCrypto(false),
50-
HasCRC(false), HasZeroCycleRegMove(false), HasZeroCycleZeroing(false),
51-
StrictAlign(false), ReserveX18(false), IsLittle(LittleEndian),
52-
CPUString(CPU), TargetTriple(TT), FrameLowering(),
50+
HasCRC(false), HasPerfMon(false), HasZeroCycleRegMove(false),
51+
HasZeroCycleZeroing(false), StrictAlign(false), ReserveX18(false),
52+
IsLittle(LittleEndian), CPUString(CPU), TargetTriple(TT), FrameLowering(),
5353
InstrInfo(initializeSubtargetDependencies(FS)), TSInfo(),
5454
TLInfo(TM, *this) {}
5555

llvm/lib/Target/AArch64/AArch64Subtarget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class AArch64Subtarget : public AArch64GenSubtargetInfo {
4444
bool HasNEON;
4545
bool HasCrypto;
4646
bool HasCRC;
47+
bool HasPerfMon;
4748

4849
// HasZeroCycleRegMove - Has zero-cycle register mov instructions.
4950
bool HasZeroCycleRegMove;
@@ -114,6 +115,7 @@ class AArch64Subtarget : public AArch64GenSubtargetInfo {
114115
bool hasNEON() const { return HasNEON; }
115116
bool hasCrypto() const { return HasCrypto; }
116117
bool hasCRC() const { return HasCRC; }
118+
bool hasPerfMon() const { return HasPerfMon; }
117119

118120
bool isLittleEndian() const { return IsLittle; }
119121

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
; RUN: llc -mtriple=aarch64-unknown-unknown -asm-verbose=false < %s |\
2+
; RUN: FileCheck %s --check-prefix=CHECK --check-prefix=PERFMON
3+
; RUN: llc -mtriple=aarch64-unknown-unknown -mattr=-perfmon -asm-verbose=false < %s |\
4+
; RUN: FileCheck %s --check-prefix=CHECK --check-prefix=NOPERFMON
5+
6+
define i64 @test_readcyclecounter() nounwind {
7+
; CHECK-LABEL: test_readcyclecounter:
8+
; PERFMON-NEXT: mrs x0, PMCCNTR_EL0
9+
; NOPERFMON-NEXT: mov x0, xzr
10+
; CHECK-NEXT: ret
11+
%tmp0 = call i64 @llvm.readcyclecounter()
12+
ret i64 %tmp0
13+
}
14+
15+
declare i64 @llvm.readcyclecounter()

0 commit comments

Comments
 (0)