diff options
-rw-r--r-- | docs/LanguageExtensions.html | 37 | ||||
-rw-r--r-- | include/clang/Basic/Builtins.def | 1 | ||||
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 4 | ||||
-rw-r--r-- | test/CodeGen/builtins.c | 6 |
4 files changed, 48 insertions, 0 deletions
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 @@ <li><a href="#complex-list-init">Initializer lists for complex numbers in C</a></li> <li><a href="#builtins">Builtin Functions</a> <ul> + <li><a href="#__builtin_readcyclecounter">__builtin_readcyclecounter</a></li> <li><a href="#__builtin_shufflevector">__builtin_shufflevector</a></li> <li><a href="#__builtin_unreachable">__builtin_unreachable</a></li> <li><a href="#__sync_swap">__sync_swap</a></li> @@ -1367,6 +1368,42 @@ vector support</a> instead of builtins, in order to reduce the number of builtins that we need to implement.</p> <!-- ======================================================================= --> +<h3><a name="__builtin_readcyclecounter">__builtin_readcyclecounter</a></h3> +<!-- ======================================================================= --> + +<p><tt>__builtin_readcyclecounter</tt> is used to access the cycle counter +register (or a similar low-latency, high-accuracy clock) on those targets that +support it. +</p> + +<p><b>Syntax:</b></p> + +<pre> +__builtin_readcyclecounter() +</pre> + +<p><b>Example of Use:</b></p> + +<pre> +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 +</pre> + +<p><b>Description:</b></p> + +<p>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. +</p> + +<p>Query for this feature with __has_builtin(__builtin_readcyclecounter).</p> + +<!-- ======================================================================= --> <h3><a name="__builtin_shufflevector">__builtin_shufflevector</a></h3> <!-- ======================================================================= --> 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(); +} |