summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Lenharth <andrewl@lenharth.org>2005-11-11 16:47:30 +0000
committerAndrew Lenharth <andrewl@lenharth.org>2005-11-11 16:47:30 +0000
commit51b8d54922350b7e1c2cd5a5183ef2c5f5d1b1d5 (patch)
tree76fbb3c458648bcc22897b27ad74c94b13bdc4ff
parentaeef8fc5c6124a34bd2a723071a3982b559c26f2 (diff)
downloadllvm-51b8d54922350b7e1c2cd5a5183ef2c5f5d1b1d5.tar.gz
llvm-51b8d54922350b7e1c2cd5a5183ef2c5f5d1b1d5.tar.bz2
llvm-51b8d54922350b7e1c2cd5a5183ef2c5f5d1b1d5.tar.xz
continued readcyclecounter support
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24300 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/LangRef.html34
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp1
-rw-r--r--lib/CodeGen/IntrinsicLowering.cpp6
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp3
-rw-r--r--lib/Target/Alpha/AlphaISelPattern.cpp5
-rw-r--r--lib/Target/Alpha/AlphaInstrFormats.td9
-rw-r--r--lib/Target/Alpha/AlphaInstrInfo.td3
-rw-r--r--lib/VMCore/Function.cpp7
-rw-r--r--lib/VMCore/Verifier.cpp8
-rw-r--r--test/CodeGen/Alpha/rpcc.ll10
12 files changed, 88 insertions, 4 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html
index 72dfd88c1b..dd02a9e4a2 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -128,6 +128,7 @@
<li><a href="#i_frameaddress">'<tt>llvm.frameaddress</tt>' Intrinsic</a></li>
<li><a href="#i_prefetch">'<tt>llvm.prefetch</tt>' Intrinsic</a></li>
<li><a href="#i_pcmarker">'<tt>llvm.pcmarker</tt>' Intrinsic</a></li>
+ <li><a href="#i_readcyclecounter"><tt>llvm.readcyclecounter</tt>' Intrinsic</a></li>
</ol>
</li>
<li><a href="#int_os">Operating System Intrinsics</a>
@@ -2811,6 +2812,39 @@ support this intrinisic may ignore it.
</div>
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="i_readcyclecounter">'<tt>llvm.readcyclecounter</tt>' Intrinsic</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<pre>
+ declare ulong %llvm.readcyclecounter( )
+</pre>
+
+<h5>Overview:</h5>
+
+
+<p>
+The '<tt>llvm.readcyclecounter</tt>' 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.
+</p>
+
+<h5>Semantics:</h5>
+
+<p>
+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.
+</p>
+
+</div>
+
<!-- ======================================================================= -->
<div class="doc_subsection">
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 86cc5646be..ef0a685adb 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 a570ef54c4..256f0ffa56 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 56ab18c773..03813d0f94 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 3c0baf0563..7b8046ea0f 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 e954f15d54..ae61e20896 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 eb13486c7f..791fcedccd 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 c34b624dcc..7180409ef5 100644
--- a/lib/Target/Alpha/AlphaInstrFormats.td
+++ b/lib/Target/Alpha/AlphaInstrFormats.td
@@ -50,6 +50,15 @@ class MForm<bits<6> opcode, string asmstr>
let Inst{20-16} = Rb;
let Inst{15-0} = disp;
}
+class MfcForm<bits<6> opcode, bits<16> fc, string asmstr>
+ : InstAlpha<opcode, (ops GPRC:$RA, GPRC:$RB), asmstr> {
+ bits<5> Ra;
+ bits<5> Rb;
+
+ let Inst{25-21} = Ra;
+ let Inst{20-16} = Rb;
+ let Inst{15-0} = fc;
+}
class MgForm<bits<6> opcode, string asmstr>
: InstAlpha<opcode, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB, s16imm:$NUM), asmstr> {
diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td
index 55842964a1..e1ae7d13d5 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 1e68289f65..291e70a8f4 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 0b1670ee71..39800b11bb 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 0000000000..fbf97ad60c
--- /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
+}
+