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

llvm-svn: 246688
This commit is contained in:
Sanjay Patel 2015-09-02 19:06:43 +00:00
parent 63fae0e58b
commit a99ab1f536
6 changed files with 37 additions and 8 deletions

View File

@ -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``'
^^^^^^^^^^^^^^^

View File

@ -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 <typename InstTy>
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

View File

@ -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.

View File

@ -60,6 +60,9 @@ public:
/// \brief Return metadata containing a number of branch weights.
MDNode *createBranchWeights(ArrayRef<uint32_t> 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);

View File

@ -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; }

View File

@ -53,6 +53,10 @@ MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) {
return MDNode::get(Context, Vals);
}
MDNode *MDBuilder::createUnpredictable() {
return MDNode::get(Context, None);
}
MDNode *MDBuilder::createFunctionEntryCount(uint64_t Count) {
SmallVector<Metadata *, 2> Vals(2);
Vals[0] = createString("function_entry_count");