mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-07 10:02:22 +00:00
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:
parent
63fae0e58b
commit
a99ab1f536
@ -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``'
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user