continued readcyclecounter support

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24300 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Lenharth 2005-11-11 16:47:30 +00:00
parent aeef8fc5c6
commit 51b8d54922
12 changed files with 88 additions and 4 deletions

View File

@ -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">

View File

@ -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",

View File

@ -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:

View File

@ -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.

View File

@ -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";

View File

@ -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(),

View File

@ -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:

View File

@ -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> {

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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
}