r246699 - add __builtin_unpredictable and convert to metadata
Sanjay Patel via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 2 13:01:31 PDT 2015
Author: spatel
Date: Wed Sep 2 15:01:30 2015
New Revision: 246699
URL: http://llvm.org/viewvc/llvm-project?rev=246699&view=rev
Log:
add __builtin_unpredictable and convert to metadata
This patch depends on r246688 (D12341).
The goal is to make LLVM generate different code for these functions for a target that
has cheap branches (see PR23827 for more details):
int foo();
int normal(int x, int y, int z) {
if (x != 0 && y != 0) return foo();
return 1;
}
int crazy(int x, int y) {
if (__builtin_unpredictable(x != 0 && y != 0)) return foo();
return 1;
}
Differential Revision: http://reviews.llvm.org/D12458
Added:
cfe/trunk/test/CodeGen/builtin-unpredictable.c
Modified:
cfe/trunk/docs/LanguageExtensions.rst
cfe/trunk/include/clang/Basic/Builtins.def
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=246699&r1=246698&r2=246699&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Wed Sep 2 15:01:30 2015
@@ -1540,6 +1540,33 @@ takes no arguments and produces a void r
Query for this feature with ``__has_builtin(__builtin_unreachable)``.
+``__builtin_unpredictable``
+---------------------------
+
+``__builtin_unpredictable`` is used to indicate that a branch condition is
+unpredictable by hardware mechanisms such as branch prediction logic.
+
+**Syntax**:
+
+.. code-block:: c++
+
+ __builtin_unpredictable(long long)
+
+**Example of use**:
+
+.. code-block:: c++
+
+ if (__builtin_unpredictable(x > 0)) {
+ foo();
+ }
+
+**Description**:
+
+The ``__builtin_unpredictable()`` builtin is expected to be used with control
+flow conditions such as in ``if`` and ``switch`` statements.
+
+Query for this feature with ``__has_builtin(__builtin_unpredictable)``.
+
``__sync_swap``
---------------
Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=246699&r1=246698&r2=246699&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Wed Sep 2 15:01:30 2015
@@ -489,6 +489,7 @@ BUILTIN(__builtin___printf_chk, "iicC*."
BUILTIN(__builtin___vfprintf_chk, "iP*icC*a", "FP:2:")
BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
+BUILTIN(__builtin_unpredictable, "LiLi" , "nc")
BUILTIN(__builtin_expect, "LiLiLi" , "nc")
BUILTIN(__builtin_prefetch, "vvC*.", "nc")
BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=246699&r1=246698&r2=246699&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Wed Sep 2 15:01:30 2015
@@ -455,6 +455,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(
"cast");
return RValue::get(Result);
}
+ case Builtin::BI__builtin_unpredictable: {
+ // Always return the argument of __builtin_unpredictable. LLVM does not
+ // handle this builtin. Metadata for this builtin should be added directly
+ // to instructions such as branches or switches that use it.
+ return RValue::get(EmitScalarExpr(E->getArg(0)));
+ }
case Builtin::BI__builtin_expect: {
Value *ArgValue = EmitScalarExpr(E->getArg(0));
llvm::Type *ArgType = ArgValue->getType();
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=246699&r1=246698&r2=246699&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Sep 2 15:01:30 2015
@@ -24,6 +24,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtCXX.h"
+#include "clang/Basic/Builtins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/Frontend/CodeGenOptions.h"
@@ -1203,6 +1204,22 @@ void CodeGenFunction::EmitBranchOnBoolEx
return;
}
+ // If the branch has a condition wrapped by __builtin_unpredictable,
+ // create metadata that specifies that the branch is unpredictable.
+ // Don't bother if not optimizing because that metadata would not be used.
+ llvm::MDNode *Unpredictable = nullptr;
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0) {
+ if (const CallExpr *Call = dyn_cast<CallExpr>(Cond)) {
+ const Decl *TargetDecl = Call->getCalleeDecl();
+ if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
+ if (FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
+ llvm::MDBuilder MDHelper(getLLVMContext());
+ Unpredictable = MDHelper.createUnpredictable();
+ }
+ }
+ }
+ }
+
// Create branch weights based on the number of times we get here and the
// number of times the condition should be true.
uint64_t CurrentCount = std::max(getCurrentProfileCount(), TrueCount);
@@ -1215,7 +1232,7 @@ void CodeGenFunction::EmitBranchOnBoolEx
ApplyDebugLocation DL(*this, Cond);
CondV = EvaluateExprAsBool(Cond);
}
- Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights);
+ Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights, Unpredictable);
}
/// ErrorUnsupported - Print out an error that codegen doesn't support the
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp?rev=246699&r1=246698&r2=246699&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp Wed Sep 2 15:01:30 2015
@@ -41,11 +41,12 @@ bool BuiltinFunctionChecker::evalCall(co
default:
return false;
+ case Builtin::BI__builtin_unpredictable:
case Builtin::BI__builtin_expect:
case Builtin::BI__builtin_assume_aligned:
case Builtin::BI__builtin_addressof: {
- // For __builtin_expect and __builtin_assume_aligned, just return the value
- // of the subexpression.
+ // For __builtin_unpredictable, __builtin_expect, and
+ // __builtin_assume_aligned, just return the value of the subexpression.
// __builtin_addressof is going from a reference to a pointer, but those
// are represented the same way in the analyzer.
assert (CE->arg_begin() != CE->arg_end());
Added: cfe/trunk/test/CodeGen/builtin-unpredictable.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-unpredictable.c?rev=246699&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/builtin-unpredictable.c (added)
+++ cfe/trunk/test/CodeGen/builtin-unpredictable.c Wed Sep 2 15:01:30 2015
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O1 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck %s --check-prefix=CHECK_O0
+
+// When optimizing, the builtin should be converted to metadata.
+// When not optimizing, there should be no metadata created for the builtin.
+// In both cases, the builtin should be removed from the code.
+
+void foo();
+void branch(int x) {
+// CHECK-LABEL: define void @branch(
+
+// CHECK-NOT: builtin_unpredictable
+// CHECK: !unpredictable [[METADATA:.+]]
+// CHECK: [[METADATA]] = !{}
+
+// CHECK_O0-NOT: builtin_unpredictable
+// CHECK_O0-NOT: !unpredictable
+
+ if (__builtin_unpredictable(x > 0))
+ foo ();
+}
+
+// TODO: Add metadata for unpredictable switches.
+int unpredictable_switch(int x) {
+ switch(__builtin_unpredictable(x)) {
+ default:
+ return 0;
+ case 0:
+ case 1:
+ case 2:
+ return 1;
+ case 5:
+ return 5;
+ };
+
+ return 0;
+}
+
More information about the cfe-commits
mailing list