From 1cded9afe4df04564b38d63556fa4f7c53c52e2b Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 2 Sep 2015 19:06:43 +0000 Subject: [PATCH] add unpredictable metadata type for control flow This patch defines 'unpredictable' metadata. This metadata can be used to signal to the optimizer or backend that a branch or switch is unpredictable, and therefore, it's probably better to not split a compound predicate into multiple branches such as in CodeGenPrepare::splitBranchCondition(). This was discussed in: https://llvm.org/bugs/show_bug.cgi?id=23827 Dependent patches to alter codegen and expose this in clang to follow. Differential Revision; http://reviews.llvm.org/D12341 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246688 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LangRef.rst | 10 ++++++++++ include/llvm/IR/IRBuilder.h | 19 ++++++++++++------- include/llvm/IR/LLVMContext.h | 3 ++- include/llvm/IR/MDBuilder.h | 3 +++ lib/IR/LLVMContext.cpp | 6 ++++++ lib/IR/MDBuilder.cpp | 4 ++++ 6 files changed, 37 insertions(+), 8 deletions(-) diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 9bcbd89c301..3c29e9a0618 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -4163,6 +4163,16 @@ Examples: !2 = !{ i8 0, i8 2, i8 3, i8 6 } !3 = !{ i8 -2, i8 0, i8 3, i8 6 } +'``unpredictable``' Metadata +^^^^^^^^^^^^^^^^^^^^^ + +``unpredictable`` metadata may be attached to any branch or switch +instruction. It can be used to express the unpredictability of control +flow. Similar to the llvm.expect intrinsic, it may be used to alter +optimizations related to compare and branch instructions. The metadata +is treated as a boolean value; if it exists, it signals that the branch +or switch that it is attached to is completely unpredictable. + '``llvm.loop``' ^^^^^^^^^^^^^^^ diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index 5c66e848325..044b5c59f7c 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -577,12 +577,15 @@ public: //===--------------------------------------------------------------------===// private: - /// \brief Helper to add branch weight metadata onto an instruction. + /// \brief Helper to add branch weight and unpredictable metadata onto an + /// instruction. /// \returns The annotated instruction. template - InstTy *addBranchWeights(InstTy *I, MDNode *Weights) { + InstTy *addBranchMetadata(InstTy *I, MDNode *Weights, MDNode *Unpredictable) { if (Weights) I->setMetadata(LLVMContext::MD_prof, Weights); + if (Unpredictable) + I->setMetadata(LLVMContext::MD_unpredictable, Unpredictable); return I; } @@ -619,9 +622,10 @@ public: /// \brief Create a conditional 'br Cond, TrueDest, FalseDest' /// instruction. BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, - MDNode *BranchWeights = nullptr) { - return Insert(addBranchWeights(BranchInst::Create(True, False, Cond), - BranchWeights)); + MDNode *BranchWeights = nullptr, + MDNode *Unpredictable = nullptr) { + return Insert(addBranchMetadata(BranchInst::Create(True, False, Cond), + BranchWeights, Unpredictable)); } /// \brief Create a switch instruction with the specified value, default dest, @@ -629,8 +633,9 @@ public: /// allocation). SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10, MDNode *BranchWeights = nullptr) { - return Insert(addBranchWeights(SwitchInst::Create(V, Dest, NumCases), - BranchWeights)); + // TODO: Add unpredictable metadata for a switch. + return Insert(addBranchMetadata(SwitchInst::Create(V, Dest, NumCases), + BranchWeights, nullptr)); } /// \brief Create an indirect branch instruction with the specified address diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index e58f2a9b01e..4c9f8e5e92a 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -61,7 +61,8 @@ public: MD_nonnull = 11, // "nonnull" MD_dereferenceable = 12, // "dereferenceable" MD_dereferenceable_or_null = 13, // "dereferenceable_or_null" - MD_make_implicit = 14 // "make.implicit" + MD_make_implicit = 14, // "make.implicit" + MD_unpredictable = 15 // "unpredictable" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h index ceb1c736e5c..35341e3271f 100644 --- a/include/llvm/IR/MDBuilder.h +++ b/include/llvm/IR/MDBuilder.h @@ -60,6 +60,9 @@ public: /// \brief Return metadata containing a number of branch weights. MDNode *createBranchWeights(ArrayRef Weights); + /// Return metadata specifying that a branch or switch is unpredictable. + MDNode *createUnpredictable(); + /// Return metadata containing the entry count for a function. MDNode *createFunctionEntryCount(uint64_t Count); diff --git a/lib/IR/LLVMContext.cpp b/lib/IR/LLVMContext.cpp index af7609f250f..77fd3e1c198 100644 --- a/lib/IR/LLVMContext.cpp +++ b/lib/IR/LLVMContext.cpp @@ -110,6 +110,12 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { assert(MakeImplicitID == MD_make_implicit && "make.implicit kind id drifted"); (void)MakeImplicitID; + + // Create the 'unpredictable' metadata kind. + unsigned UnpredictableID = getMDKindID("unpredictable"); + assert(UnpredictableID == MD_unpredictable && + "unpredictable kind id drifted"); + (void)UnpredictableID; } LLVMContext::~LLVMContext() { delete pImpl; } diff --git a/lib/IR/MDBuilder.cpp b/lib/IR/MDBuilder.cpp index b4c5ca7c6a1..f333dcee4d1 100644 --- a/lib/IR/MDBuilder.cpp +++ b/lib/IR/MDBuilder.cpp @@ -53,6 +53,10 @@ MDNode *MDBuilder::createBranchWeights(ArrayRef Weights) { return MDNode::get(Context, Vals); } +MDNode *MDBuilder::createUnpredictable() { + return MDNode::get(Context, None); +} + MDNode *MDBuilder::createFunctionEntryCount(uint64_t Count) { SmallVector Vals(2); Vals[0] = createString("function_entry_count"); -- 2.34.1