[llvm] r182603 - ARM: implement @llvm.readcyclecounter intrinsic
JF Bastien
jfb at google.com
Fri May 24 13:49:25 PDT 2013
PMUSERENR.EN seems to default to zero on Linux, no? At least my local
Ubuntu A15 board test says so, and as expected I get SIGILL in user mode.
Wouldn't it also useful to have an intrinsic to check for the value? "mrc
p15, 0, %0, c9, c14, 0"'s bottom bit should do it. Or figure out which OS
also supports PMUSERENR.EN=1 by default, with an override flag?
On Thu, May 23, 2013 at 12:11 PM, Tim Northover <t.p.northover at gmail.com>wrote:
> Author: tnorthover
> Date: Thu May 23 14:11:20 2013
> New Revision: 182603
>
> URL: http://llvm.org/viewvc/llvm-project?rev=182603&view=rev
> Log:
> ARM: implement @llvm.readcyclecounter intrinsic
>
> This implements the @llvm.readcyclecounter intrinsic as the specific
> MRC instruction specified in the ARM manuals for CPUs with the Power
> Management extensions.
>
> Older CPUs had slightly different methods which may also have to be
> implemented eventually, but this should cover all v7 cases.
>
> rdar://problem/13939186
>
> Added:
> llvm/trunk/test/CodeGen/ARM/readcyclecounter.ll
> Modified:
> llvm/trunk/docs/LangRef.rst
> llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>
> Modified: llvm/trunk/docs/LangRef.rst
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=182603&r1=182602&r2=182603&view=diff
>
> ==============================================================================
> --- llvm/trunk/docs/LangRef.rst (original)
> +++ llvm/trunk/docs/LangRef.rst Thu May 23 14:11:20 2013
> @@ -6663,6 +6663,9 @@ memory. Implementations are allowed to e
> specific value or a system wide value. On backends without support, this
> is lowered to a constant 0.
>
> +Note that runtime support may be conditional on the privilege-level code
> is
> +running at and the host platform.
> +
> Standard C Library Intrinsics
> -----------------------------
>
>
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=182603&r1=182602&r2=182603&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu May 23 14:11:20 2013
> @@ -681,6 +681,8 @@ ARMTargetLowering::ARMTargetLowering(Tar
> setOperationAction(ISD::CTTZ_ZERO_UNDEF , MVT::i32 , Expand);
> setOperationAction(ISD::CTLZ_ZERO_UNDEF , MVT::i32 , Expand);
>
> + setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);
> +
> // Only ARMv6 has BSWAP.
> if (!Subtarget->hasV6Ops())
> setOperationAction(ISD::BSWAP, MVT::i32, Expand);
> @@ -5702,7 +5704,6 @@ static SDValue LowerAtomicLoadStore(SDVa
> return SDValue();
> }
>
> -
> static void
> ReplaceATOMIC_OP_64(SDNode *Node, SmallVectorImpl<SDValue>& Results,
> SelectionDAG &DAG, unsigned NewOp) {
> @@ -5736,6 +5737,44 @@ ReplaceATOMIC_OP_64(SDNode *Node, SmallV
> Results.push_back(Result.getValue(2));
> }
>
> +static void ReplaceREADCYCLECOUNTER(SDNode *N,
> + SmallVectorImpl<SDValue> &Results,
> + SelectionDAG &DAG,
> + const ARMSubtarget *Subtarget) {
> + DebugLoc DL = N->getDebugLoc();
> + SDValue Cycles32, OutChain;
> +
> + if (Subtarget->hasPerfMon()) {
> + // Under Power Management extensions, the cycle-count is:
> + // mrc p15, #0, <Rt>, c9, c13, #0
> + SDValue Ops[] = { N->getOperand(0), // Chain
> + DAG.getConstant(Intrinsic::arm_mrc, MVT::i32),
> + DAG.getConstant(15, MVT::i32),
> + DAG.getConstant(0, MVT::i32),
> + DAG.getConstant(9, MVT::i32),
> + DAG.getConstant(13, MVT::i32),
> + DAG.getConstant(0, MVT::i32)
> + };
> +
> + Cycles32 = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
> + DAG.getVTList(MVT::i32, MVT::Other), &Ops[0],
> + array_lengthof(Ops));
> + OutChain = Cycles32.getValue(1);
> + } else {
> + // Intrinsic is defined to return 0 on unsupported platforms.
> Technically
> + // there are older ARM CPUs that have implementation-specific ways of
> + // obtaining this information (FIXME!).
> + Cycles32 = DAG.getConstant(0, MVT::i32);
> + OutChain = DAG.getEntryNode();
> + }
> +
> +
> + SDValue Cycles64 = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64,
> + Cycles32, DAG.getConstant(0, MVT::i32));
> + Results.push_back(Cycles64);
> + Results.push_back(OutChain);
> +}
> +
> SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
> const {
> switch (Op.getOpcode()) {
> default: llvm_unreachable("Don't know how to custom lower this!");
> @@ -5813,6 +5852,9 @@ void ARMTargetLowering::ReplaceNodeResul
> case ISD::SRA:
> Res = Expand64BitShift(N, DAG, Subtarget);
> break;
> + case ISD::READCYCLECOUNTER:
> + ReplaceREADCYCLECOUNTER(N, Results, DAG, Subtarget);
> + return;
> case ISD::ATOMIC_LOAD_ADD:
> ReplaceATOMIC_OP_64(N, Results, DAG, ARMISD::ATOMADD64_DAG);
> return;
>
> Added: llvm/trunk/test/CodeGen/ARM/readcyclecounter.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/readcyclecounter.ll?rev=182603&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/readcyclecounter.ll (added)
> +++ llvm/trunk/test/CodeGen/ARM/readcyclecounter.ll Thu May 23 14:11:20
> 2013
> @@ -0,0 +1,24 @@
> +; RUN: llc -mtriple=armv7-none-linux-gnueabi < %s | FileCheck %s
> +; RUN: llc -mtriple=thumbv7-none-linux-gnueabi < %s | FileCheck %s
> +; RUN: llc -mtriple=armv7-none-linux-gnueabi -mattr=-perfmon < %s |
> FileCheck %s --check-prefix=CHECK-NO-PERFMON
> +; RUN: llc -mtriple=armv6-none-linux-gnueabi < %s | FileCheck %s
> --check-prefix=CHECK-NO-PERFMON
> +
> +; The performance monitor we're looking for is an ARMv7 extension. It
> should be
> +; possible to disable it, but realistically present on at least every v7-A
> +; processor (but not on v6, at least by default).
> +
> +declare i64 @llvm.readcyclecounter()
> +
> +define i64 @get_count() {
> + %val = call i64 @llvm.readcyclecounter()
> + ret i64 %val
> +
> + ; As usual, exact registers only sort of matter but the cycle-count had
> better
> + ; end up in r0 in the end.
> +
> +; CHECK: mrc p15, #0, r0, c9, c13, #0
> +; CHECK: {{movs?}} r1, #0
> +
> +; CHECK-NO-PERFMON: {{movs?}} r0, #0
> +; CHECK-NO-PERFMON: {{movs?}} r1, #0
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130524/137e3a65/attachment.html>
More information about the llvm-commits
mailing list