diff options
author | Sanjay Patel <spatel@rotateright.com> | 2015-09-02 20:01:30 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2015-09-02 20:01:30 +0000 |
commit | a24296b459660924f4c9f50321c0c0bf6ca1ee89 (patch) | |
tree | f976b50ecdfe9b8bc14b2ce8a6c30905277146f8 /clang/lib | |
parent | d428e203a01aa22a2f7d5c5f2954caed7f4888a6 (diff) | |
download | bcm5719-llvm-a24296b459660924f4c9f50321c0c0bf6ca1ee89.tar.gz bcm5719-llvm-a24296b459660924f4c9f50321c0c0bf6ca1ee89.zip |
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
llvm-svn: 246699
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 19 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp | 5 |
3 files changed, 27 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index a04a1c12560..9079462cd83 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -455,6 +455,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, "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(); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 9bf4161e945..ea387d3f080 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -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::EmitBranchOnBoolExpr(const Expr *Cond, 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::EmitBranchOnBoolExpr(const Expr *Cond, 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 diff --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp index 104a81eac4c..dab2f61229a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -41,11 +41,12 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE, 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()); |