[Profile] refactor meta data copying/swapping code

Differential Revision: http://reviews.llvm.org/D23619

llvm-svn: 279523
This commit is contained in:
Xinliang David Li 2016-08-23 15:39:03 +00:00
parent 298d546297
commit dc49140b44
4 changed files with 62 additions and 57 deletions

View File

@ -198,6 +198,16 @@ public:
void setMetadata(unsigned KindID, MDNode *Node);
void setMetadata(StringRef Kind, MDNode *Node);
/// Copy metadata from \p SrcInst to this instruction. \p WL, if not empty,
/// specifies the list of meta data that needs to be copied. If \p WL is
/// empty, all meta data will be copied.
void copyMetadata(const Instruction &SrcInst, ArrayRef<unsigned> WL = {});
/// If the instruction has "branch_weights" MD_prof metadata and the MDNode
/// has three operands (including name string), swap the order of the
/// metadata.
void swapProfMetadata();
/// Drop all unknown metadata except for debug locations.
/// @{
/// Passes are required to drop metadata they don't understand. This is a

View File

@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
@ -632,6 +633,47 @@ Instruction *Instruction::cloneImpl() const {
llvm_unreachable("Subclass of Instruction failed to implement cloneImpl");
}
void Instruction::swapProfMetadata() {
MDNode *ProfileData = getMetadata(LLVMContext::MD_prof);
if (!ProfileData || ProfileData->getNumOperands() != 3 ||
!isa<MDString>(ProfileData->getOperand(0)))
return;
MDString *MDName = cast<MDString>(ProfileData->getOperand(0));
if (MDName->getString() != "branch_weights")
return;
// The first operand is the name. Fetch them backwards and build a new one.
Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2),
ProfileData->getOperand(1)};
setMetadata(LLVMContext::MD_prof,
MDNode::get(ProfileData->getContext(), Ops));
}
/// Copy meta data from \p SrcInst to this instruction. If WL is empty, all
/// data will be copied, otherwise only ones specified in WL will be copied.
void Instruction::copyMetadata(const Instruction &SrcInst,
ArrayRef<unsigned> WL) {
if (!SrcInst.hasMetadata())
return;
DenseSet<unsigned> WLS;
for (unsigned M : WL)
WLS.insert(M);
// Otherwise, enumerate and copy over metadata from the old instruction to the
// new one.
SmallVector<std::pair<unsigned, MDNode *>, 4> TheMDs;
SrcInst.getAllMetadataOtherThanDebugLoc(TheMDs);
for (const auto &MD : TheMDs) {
if (WL.empty() || WLS.count(MD.first))
setMetadata(MD.first, MD.second);
}
if (WL.empty() || WLS.count(LLVMContext::MD_dbg))
setDebugLoc(SrcInst.getDebugLoc());
return;
}
Instruction *Instruction::clone() const {
Instruction *New = nullptr;
switch (getOpcode()) {
@ -646,16 +688,6 @@ Instruction *Instruction::clone() const {
}
New->SubclassOptionalData = SubclassOptionalData;
if (!hasMetadata())
return New;
// Otherwise, enumerate and copy over metadata from the old instruction to the
// new one.
SmallVector<std::pair<unsigned, MDNode *>, 4> TheMDs;
getAllMetadataOtherThanDebugLoc(TheMDs);
for (const auto &MD : TheMDs)
New->setMetadata(MD.first, MD.second);
New->setDebugLoc(getDebugLoc());
New->copyMetadata(*this);
return New;
}

View File

@ -1209,15 +1209,7 @@ void BranchInst::swapSuccessors() {
// Update profile metadata if present and it matches our structural
// expectations.
MDNode *ProfileData = getMetadata(LLVMContext::MD_prof);
if (!ProfileData || ProfileData->getNumOperands() != 3)
return;
// The first operand is the name. Fetch them backwards and build a new one.
Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2),
ProfileData->getOperand(1)};
setMetadata(LLVMContext::MD_prof,
MDNode::get(ProfileData->getContext(), Ops));
swapProfMetadata();
}
BasicBlock *BranchInst::getSuccessorV(unsigned idx) const {

View File

@ -742,42 +742,6 @@ static Loop *CloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM,
return &New;
}
static void copyMetadata(Instruction *DstInst, const Instruction *SrcInst,
bool Swapped) {
if (!SrcInst || !SrcInst->hasMetadata())
return;
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
SrcInst->getAllMetadata(MDs);
for (auto &MD : MDs) {
switch (MD.first) {
default:
break;
case LLVMContext::MD_prof:
if (Swapped && MD.second->getNumOperands() == 3 &&
isa<MDString>(MD.second->getOperand(0))) {
MDString *MDName = cast<MDString>(MD.second->getOperand(0));
if (MDName->getString() == "branch_weights") {
auto *ValT = cast_or_null<ConstantAsMetadata>(
MD.second->getOperand(1))->getValue();
auto *ValF = cast_or_null<ConstantAsMetadata>(
MD.second->getOperand(2))->getValue();
assert(ValT && ValF && "Invalid Operands of branch_weights");
auto NewMD =
MDBuilder(DstInst->getParent()->getContext())
.createBranchWeights(cast<ConstantInt>(ValF)->getZExtValue(),
cast<ConstantInt>(ValT)->getZExtValue());
MD.second = NewMD;
}
}
LLVM_FALLTHROUGH;
case LLVMContext::MD_make_implicit:
case LLVMContext::MD_dbg:
DstInst->setMetadata(MD.first, MD.second);
}
}
}
/// Emit a conditional branch on two values if LIC == Val, branch to TrueDst,
/// otherwise branch to FalseDest. Insert the code immediately before InsertPt.
void LoopUnswitch::EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
@ -800,7 +764,14 @@ void LoopUnswitch::EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
// Insert the new branch.
BranchInst *BI = BranchInst::Create(TrueDest, FalseDest, BranchVal, InsertPt);
copyMetadata(BI, TI, Swapped);
if (TI) {
// FIXME: check why white list is needed here:
ArrayRef<unsigned> WL = {LLVMContext::MD_dbg, LLVMContext::MD_prof,
LLVMContext::MD_make_implicit};
BI->copyMetadata(*TI, WL);
if (Swapped)
BI->swapProfMetadata();
}
// If either edge is critical, split it. This helps preserve LoopSimplify
// form for enclosing loops.