Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -4163,6 +4163,22 @@ !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 is used to express the unpredictability of control +flow and like the llvm.expect intrinsic, it may alter optimizations +related to branch instructions. + +The metadata node consists of a single positive integer number between +0 and 100 representing the unpredictability percentage for a branch or +switch. For example: + +.. code-block:: llvm + + !0 = !{ unpredictable i8 100 } ; completely unpredictable + '``llvm.loop``' ^^^^^^^^^^^^^^^ Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -577,12 +577,15 @@ //===--------------------------------------------------------------------===// 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 @@ /// \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 @@ /// 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 Index: include/llvm/IR/LLVMContext.h =================================================================== --- include/llvm/IR/LLVMContext.h +++ include/llvm/IR/LLVMContext.h @@ -61,7 +61,8 @@ 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. Index: include/llvm/IR/MDBuilder.h =================================================================== --- include/llvm/IR/MDBuilder.h +++ include/llvm/IR/MDBuilder.h @@ -60,6 +60,11 @@ /// \brief Return metadata containing a number of branch weights. MDNode *createBranchWeights(ArrayRef Weights); + /// Return metadata containing the unpredictability percentage of a branch. + /// 0 means the branch is completely predictable; + /// 100 means the branch is completely unpredictable. + MDNode *createUnpredictable(uint8_t Unpredictability = 0); + /// Return metadata containing the entry count for a function. MDNode *createFunctionEntryCount(uint64_t Count); Index: lib/IR/LLVMContext.cpp =================================================================== --- lib/IR/LLVMContext.cpp +++ lib/IR/LLVMContext.cpp @@ -110,6 +110,12 @@ 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; } Index: lib/IR/MDBuilder.cpp =================================================================== --- lib/IR/MDBuilder.cpp +++ lib/IR/MDBuilder.cpp @@ -53,6 +53,19 @@ return MDNode::get(Context, Vals); } +MDNode *MDBuilder::createUnpredictable(uint8_t Unpredictability) { + // If it's completely predictable, there's no need to add metadata. + // This is the default state. + if (Unpredictability == 0) + return nullptr; + + assert(Unpredictability <= 100 && + "Unpredictable metadata is an integral percentage from 0 to 100!"); + Type *Int8Ty = Type::getInt8Ty(Context); + Constant *C = ConstantInt::get(Int8Ty, Unpredictability); + return MDNode::get(Context, createConstant(C)); +} + MDNode *MDBuilder::createFunctionEntryCount(uint64_t Count) { SmallVector Vals(2); Vals[0] = createString("function_entry_count");