Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -4163,6 +4163,16 @@ !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``' ^^^^^^^^^^^^^^^ 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,9 @@ /// \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); 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,10 @@ 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");