From dc49140b4429c3eb0966f8169cd533660002ae41 Mon Sep 17 00:00:00 2001 From: Xinliang David Li Date: Tue, 23 Aug 2016 15:39:03 +0000 Subject: [PATCH] [Profile] refactor meta data copying/swapping code Differential Revision: http://reviews.llvm.org/D23619 llvm-svn: 279523 --- llvm/include/llvm/IR/Instruction.h | 10 ++++ llvm/lib/IR/Instruction.cpp | 54 ++++++++++++++++----- llvm/lib/IR/Instructions.cpp | 10 +--- llvm/lib/Transforms/Scalar/LoopUnswitch.cpp | 45 +++-------------- 4 files changed, 62 insertions(+), 57 deletions(-) diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index 576f439977c5..8305a707d70a 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -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 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 diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index cfddbf78f0c5..4a1f11a136b0 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -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(ProfileData->getOperand(0))) + return; + + MDString *MDName = cast(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 WL) { + if (!SrcInst.hasMetadata()) + return; + + DenseSet WLS; + for (unsigned M : WL) + WLS.insert(M); + + // Otherwise, enumerate and copy over metadata from the old instruction to the + // new one. + SmallVector, 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, 4> TheMDs; - getAllMetadataOtherThanDebugLoc(TheMDs); - for (const auto &MD : TheMDs) - New->setMetadata(MD.first, MD.second); - - New->setDebugLoc(getDebugLoc()); + New->copyMetadata(*this); return New; } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 43d7927ce6a8..5355f1a617a0 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -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 { diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp index ee8c324b7276..93c10d53ebbf 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -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, 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(MD.second->getOperand(0))) { - MDString *MDName = cast(MD.second->getOperand(0)); - if (MDName->getString() == "branch_weights") { - auto *ValT = cast_or_null( - MD.second->getOperand(1))->getValue(); - auto *ValF = cast_or_null( - MD.second->getOperand(2))->getValue(); - assert(ValT && ValF && "Invalid Operands of branch_weights"); - auto NewMD = - MDBuilder(DstInst->getParent()->getContext()) - .createBranchWeights(cast(ValF)->getZExtValue(), - cast(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 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.