From 51b8d54922350b7e1c2cd5a5183ef2c5f5d1b1d5 Mon Sep 17 00:00:00 2001 From: Andrew Lenharth Date: Fri, 11 Nov 2005 16:47:30 +0000 Subject: [PATCH] continued readcyclecounter support git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24300 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LangRef.html | 34 +++++++++++++++++++ lib/Analysis/BasicAliasAnalysis.cpp | 1 + lib/CodeGen/IntrinsicLowering.cpp | 6 ++++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 5 +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 1 + lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 3 ++ lib/Target/Alpha/AlphaISelPattern.cpp | 5 +++ lib/Target/Alpha/AlphaInstrFormats.td | 9 +++++ lib/Target/Alpha/AlphaInstrInfo.td | 3 +- lib/VMCore/Function.cpp | 7 ++-- lib/VMCore/Verifier.cpp | 8 +++++ test/CodeGen/Alpha/rpcc.ll | 10 ++++++ 12 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/Alpha/rpcc.ll diff --git a/docs/LangRef.html b/docs/LangRef.html index 72dfd88c1b6..dd02a9e4a29 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -128,6 +128,7 @@
  • 'llvm.frameaddress' Intrinsic
  • 'llvm.prefetch' Intrinsic
  • 'llvm.pcmarker' Intrinsic
  • +
  • llvm.readcyclecounter' Intrinsic
  • Operating System Intrinsics @@ -2811,6 +2812,39 @@ support this intrinisic may ignore it. + + + +
    + +
    Syntax:
    +
    +  declare ulong %llvm.readcyclecounter( )
    +
    + +
    Overview:
    + + +

    +The 'llvm.readcyclecounter' intrinsic provides access to the cycle +counter register (or similar low latency, high accuracy clocks) on those targets +that support it. On X86, it should map to RDTSC. On Alpha, it should map to RPCC. +As the backing counters overflow quickly (on the order of 9 seconds on alpha), this +should only be used for small timings. +

    + +
    Semantics:
    + +

    +When directly supported, reading the cycle counter should not modify any memory. +Implementations are allowed to either return a application specific value or a +system wide value. On backends without support, this is lowered to a constant 0. +

    + +
    +
    diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 86cc5646be6..ef0a685adb9 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -709,6 +709,7 @@ static const char *DoesntAccessMemoryTable[] = { // LLVM intrinsics: "llvm.frameaddress", "llvm.returnaddress", "llvm.readport", "llvm.isunordered", "llvm.sqrt", "llvm.ctpop", "llvm.ctlz", "llvm.cttz", + "llvm.readcyclecounter", "abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl", "trunc", "truncf", "truncl", "ldexp", diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp index a570ef54c45..256f0ffa567 100644 --- a/lib/CodeGen/IntrinsicLowering.cpp +++ b/lib/CodeGen/IntrinsicLowering.cpp @@ -262,6 +262,12 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { case Intrinsic::pcmarker: break; // Simply strip out pcmarker on unsupported architectures + case Intrinsic::readcyclecounter: { + std::cerr << "WARNING: this target does not support the llvm.readcyclecounter" + << " intrinsic. It is being lowered to a constant 0\n"; + CI->replaceAllUsesWith(ConstantUInt::get(Type::ULongTy, 0)); + break; + } case Intrinsic::dbg_stoppoint: case Intrinsic::dbg_region_start: diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 56ab18c773d..03813d0f94d 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1122,6 +1122,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { if (Tmp1 != Node->getOperand(0)) Result = DAG.getNode(ISD::PCMARKER, MVT::Other, Tmp1,Node->getOperand(1)); break; + case ISD::READCYCLECOUNTER: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain + if (Tmp1 != Node->getOperand(0)) + Result = DAG.getNode(ISD::READCYCLECOUNTER, MVT::i64, Tmp1); + break; case ISD::TRUNCSTORE: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the pointer. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 3c0baf05631..7b8046ea0f8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1624,6 +1624,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const { } case ISD::PCMARKER: return "PCMarker"; + case ISD::READCYCLECOUNTER: return "ReadCycleCounter"; case ISD::SRCVALUE: return "SrcValue"; case ISD::VALUETYPE: return "ValueType"; case ISD::EntryToken: return "EntryToken"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e954f15d542..ae61e208963 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -804,6 +804,9 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp)); return 0; } + case Intrinsic::readcyclecounter: + setValue(&I, DAG.getNode(ISD::READCYCLECOUNTER, MVT::i64, getRoot())); + return 0; case Intrinsic::cttz: setValue(&I, DAG.getNode(ISD::CTTZ, getValue(I.getOperand(1)).getValueType(), diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp index eb13486c7f2..791fcedccde 100644 --- a/lib/Target/Alpha/AlphaISelPattern.cpp +++ b/lib/Target/Alpha/AlphaISelPattern.cpp @@ -549,6 +549,11 @@ unsigned AlphaISel::SelectExpr(SDOperand N) { Node->dump(); assert(0 && "Node not handled!\n"); + case ISD::READCYCLECOUNTER: + Select(N.getOperand(0)); //Select chain + BuildMI(BB, Alpha::RPCC, 1, Result).addReg(Alpha::R31); + return Result; + case ISD::CTPOP: case ISD::CTTZ: case ISD::CTLZ: diff --git a/lib/Target/Alpha/AlphaInstrFormats.td b/lib/Target/Alpha/AlphaInstrFormats.td index c34b624dcc3..7180409ef51 100644 --- a/lib/Target/Alpha/AlphaInstrFormats.td +++ b/lib/Target/Alpha/AlphaInstrFormats.td @@ -50,6 +50,15 @@ class MForm opcode, string asmstr> let Inst{20-16} = Rb; let Inst{15-0} = disp; } +class MfcForm opcode, bits<16> fc, string asmstr> + : InstAlpha { + bits<5> Ra; + bits<5> Rb; + + let Inst{25-21} = Ra; + let Inst{20-16} = Rb; + let Inst{15-0} = fc; +} class MgForm opcode, string asmstr> : InstAlpha { diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td index 55842964a15..e1ae7d13d5c 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.td +++ b/lib/Target/Alpha/AlphaInstrInfo.td @@ -465,6 +465,8 @@ def FBLE : FBForm<0x33, "fble $RA,$DISP">; //Floating branch if <= zero def FBLT : FBForm<0x32, "fblt $RA,$DISP">; //Floating branch if < zero def FBNE : FBForm<0x35, "fbne $RA,$DISP">; //Floating branch if != zero +def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter + //Basic Floating point ops //Floats @@ -558,7 +560,6 @@ def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC", //LDQ_L Mem 2B Load quadword locked //LDQ_U Mem 0B Load unaligned quadword //MB Mfc 18.4000 Memory barrier -//RPCC Mfc 18.C000 Read process cycle counter //STL_C Mem 2E Store longword conditional //STQ_C Mem 2F Store quadword conditional //STQ_U Mem 0F Store unaligned quadword diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 1e68289f652..291e70a8f45 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -243,9 +243,10 @@ unsigned Function::getIntrinsicID() const { if (getName() == "llvm.pcmarker") return Intrinsic::pcmarker; break; case 'r': - if (getName() == "llvm.returnaddress") return Intrinsic::returnaddress; - if (getName() == "llvm.readport") return Intrinsic::readport; - if (getName() == "llvm.readio") return Intrinsic::readio; + if (getName() == "llvm.returnaddress") return Intrinsic::returnaddress; + if (getName() == "llvm.readport") return Intrinsic::readport; + if (getName() == "llvm.readio") return Intrinsic::readio; + if (getName() == "llvm.readcyclecounter") return Intrinsic::readcyclecounter; break; case 's': if (getName() == "llvm.setjmp") return Intrinsic::setjmp; diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 0b1670ee710..39800b11bb8 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -726,6 +726,14 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { NumArgs = 2; break; + case Intrinsic::readcyclecounter: + Assert1(FT->getNumParams() == 0, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == Type::ULongTy, + "Return type is not ulong!", IF); + NumArgs = 0; + break; + case Intrinsic::ctpop: case Intrinsic::ctlz: case Intrinsic::cttz: diff --git a/test/CodeGen/Alpha/rpcc.ll b/test/CodeGen/Alpha/rpcc.ll new file mode 100644 index 00000000000..fbf97ad60c3 --- /dev/null +++ b/test/CodeGen/Alpha/rpcc.ll @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc -march=alpha | grep rpcc + +declare ulong %llvm.readcyclecounter() + +ulong %foo() { +entry: +%tmp.1 = call ulong %llvm.readcyclecounter () +ret ulong %tmp.1 +} + -- 2.34.1