From daf34e9d851aa520a187cfd602b97d3d3c1faa89 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 9 Sep 2015 22:39:06 +0000 Subject: convert builtin_unpredictable on a switch into metadata for LLVM llvm-svn: 247203 --- clang/lib/CodeGen/CGStmt.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'clang/lib/CodeGen') diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 4e95e2f3128..1ca119ef988 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -16,6 +16,7 @@ #include "CodeGenModule.h" #include "TargetInfo.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/LoopHint.h" @@ -25,6 +26,8 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/MDBuilder.h" + using namespace clang; using namespace CodeGen; @@ -1517,6 +1520,22 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { EmitBlock(SwitchExit.getBlock(), true); incrementProfileCounter(&S); + // If the switch has a condition wrapped by __builtin_unpredictable, + // create metadata that specifies that the switch is unpredictable. + // Don't bother if not optimizing because that metadata would not be used. + if (CGM.getCodeGenOpts().OptimizationLevel != 0) { + if (const CallExpr *Call = dyn_cast(S.getCond())) { + const Decl *TargetDecl = Call->getCalleeDecl(); + if (const FunctionDecl *FD = dyn_cast_or_null(TargetDecl)) { + if (FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) { + llvm::MDBuilder MDHelper(getLLVMContext()); + SwitchInsn->setMetadata(llvm::LLVMContext::MD_unpredictable, + MDHelper.createUnpredictable()); + } + } + } + } + if (SwitchWeights) { assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() && "switch weights do not match switch cases"); -- cgit v1.2.3