[PATCH] D23619: Refactor metadata copying/swapping code to make it sharable
Duncan P. N. Exon Smith via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 17 13:19:37 PDT 2016
> On 2016-Aug-17, at 11:55, David Li <davidxl at google.com> wrote:
>
> davidxl created this revision.
> davidxl added reviewers: spatel, dexonsmith.
> davidxl added a subscriber: llvm-commits.
> Herald added a subscriber: mzolotukhin.
>
> No functional change is intended.
>
> https://reviews.llvm.org/D23619
>
> Files:
> include/llvm/IR/Instruction.h
> lib/IR/Instruction.cpp
> lib/IR/Instructions.cpp
> lib/Transforms/Scalar/LoopUnswitch.cpp
>
> <D23619.68394.patch>
> Index: lib/Transforms/Scalar/LoopUnswitch.cpp
> ===================================================================
> --- lib/Transforms/Scalar/LoopUnswitch.cpp
> +++ lib/Transforms/Scalar/LoopUnswitch.cpp
> @@ -742,42 +742,6 @@
> 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;
> - }
> - }
> - // 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,8 @@
>
> // Insert the new branch.
> BranchInst *BI = BranchInst::Create(TrueDest, FalseDest, BranchVal, InsertPt);
> - copyMetadata(BI, TI, Swapped);
> + if (TI)
> + BI->copyMetadata(*TI, Swapped);
This has different semantics than the old code.
- Previously, only MD_prof (with a possible swap), MD_dbg and
MD_make_implicit were copied.
- Now arbitrary metadata is copied.
Are you sure this makes sense? Why?
Another possibility that would let you keep the current semantics:
copyMetadata could take a list of IDs ( ArrayRef<unsigned>, say) for the
metadata that should be copied over.
>
> // If either edge is critical, split it. This helps preserve LoopSimplify
> // form for enclosing loops.
> Index: lib/IR/Instructions.cpp
> ===================================================================
> --- lib/IR/Instructions.cpp
> +++ lib/IR/Instructions.cpp
> @@ -1209,15 +1209,7 @@
>
> // 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();
It looks like swapProfMetadata() could be done separately.
> }
>
> BasicBlock *BranchInst::getSuccessorV(unsigned idx) const {
> Index: lib/IR/Instruction.cpp
> ===================================================================
> --- lib/IR/Instruction.cpp
> +++ lib/IR/Instruction.cpp
> @@ -627,6 +627,41 @@
> 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));
> +}
> +
> +void Instruction::copyMetadata(const Instruction &SrcInst, bool doSwapping) {
"ShouldSwap" seems like a better name for the "doSwapping" parameter.
However, I wonder whether it makes sense at all here? Why not just have
the caller call swapProfMetadata?
> + if (!SrcInst.hasMetadata())
> + return;
> +
> + // 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)
> + setMetadata(MD.first, MD.second);
> +
> + setDebugLoc(SrcInst.getDebugLoc());
> +
> + if (doSwapping)
> + swapProfMetadata();
I.e., the caller could do this. Or are you planning to optimize this
in the future?
> + return;
> +}
> +
> Instruction *Instruction::clone() const {
> Instruction *New = nullptr;
> switch (getOpcode()) {
> @@ -641,16 +676,6 @@
> }
>
> 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, false);
> return New;
> }
> Index: include/llvm/IR/Instruction.h
> ===================================================================
> --- include/llvm/IR/Instruction.h
> +++ include/llvm/IR/Instruction.h
> @@ -197,6 +197,15 @@
> void setMetadata(unsigned KindID, MDNode *Node);
> void setMetadata(StringRef Kind, MDNode *Node);
>
> + /// Copy metadata from \p SrcInst to this instruction. If \p doSwapping
> + /// is set to true, \c MD_prof meta data will be swapped.
> + void copyMetadata(const Instruction &SrcInst, bool doSwapping);
s/doSwapping/ShouldSwapProf/ (if we keep it).
> +
> + /// 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
>
More information about the llvm-commits
mailing list