From: Hal Finkel
Date: Sun, 5 Aug 2012 22:03:08 +0000 (+0000)
Subject: Add __builtin_readcyclecounter() to produce the @llvm.readcyclecounter() intrinsic.
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a841c19f7860393d6319bf40e9d662284462771d;p=clang
Add __builtin_readcyclecounter() to produce the @llvm.readcyclecounter() intrinsic.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161310 91177308-0d34-0410-b5e6-96231b3b80d8
---
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
index 0b99263bba..eac3c69997 100644
--- a/docs/LanguageExtensions.html
+++ b/docs/LanguageExtensions.html
@@ -98,6 +98,7 @@
Initializer lists for complex numbers in C
Builtin Functions
+
+
+
+
+__builtin_readcyclecounter is used to access the cycle counter
+register (or a similar low-latency, high-accuracy clock) on those targets that
+support it.
+
+
+Syntax:
+
+
+__builtin_readcyclecounter()
+
+
+Example of Use:
+
+
+unsigned long long t0 = __builtin_readcyclecounter();
+do_something();
+unsigned long long t1 = __builtin_readcyclecounter();
+unsigned long long cycles_to_do_something = t1 - t0; // assuming no overflow
+
+
+Description:
+
+The __builtin_readcyclecounter() builtin returns the cycle counter value,
+which may be either global or process/thread-specific depending on the target.
+As the backing counters often overflow quickly (on the order of
+seconds) this should only be used for timing small intervals. When not
+supported by the target, the return value is always zero. This builtin
+takes no arguments and produces an unsigned long long result.
+
+
+Query for this feature with __has_builtin(__builtin_readcyclecounter).
+
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 63e8d08642..1b060a5092 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -476,6 +476,7 @@ BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
BUILTIN(__builtin_expect, "LiLiLi" , "nc")
BUILTIN(__builtin_prefetch, "vvC*.", "nc")
+BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
BUILTIN(__builtin_trap, "v", "nr")
BUILTIN(__builtin_unreachable, "v", "nr")
BUILTIN(__builtin_shufflevector, "v." , "nc")
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index e47a9a3f87..65c782e1cf 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -365,6 +365,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
return RValue::get(Builder.CreateCall4(F, Address, RW, Locality, Data));
}
+ case Builtin::BI__builtin_readcyclecounter: {
+ Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
+ return RValue::get(Builder.CreateCall(F));
+ }
case Builtin::BI__builtin_trap: {
Value *F = CGM.getIntrinsic(Intrinsic::trap);
return RValue::get(Builder.CreateCall(F));
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index fca087e197..65b9ad111f 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -203,3 +203,9 @@ void test_builtin_longjmp(void **buffer) {
__builtin_longjmp(buffer, 1);
// CHECK-NEXT: unreachable
}
+
+// CHECK: define i64 @test_builtin_readcyclecounter
+long long test_builtin_readcyclecounter() {
+ // CHECK: call i64 @llvm.readcyclecounter()
+ return __builtin_readcyclecounter();
+}