From 7a0ec3b9438db1bedfb31a0967748e51ba620ee5 Mon Sep 17 00:00:00 2001 From: Wei Mi Date: Mon, 22 Apr 2019 17:04:51 +0000 Subject: [PATCH] [PGO/SamplePGO][NFC] Move the function updateProfWeight from Instruction to CallInst. The issue was raised here: https://reviews.llvm.org/D60903#1472783 The function Instruction::updateProfWeight is only used for CallInst in profile update. From the current interface, it is very easy to think that the function can also be used for branch instruction. However, Branch instruction does't need the scaling the function provides for branch_weights and VP (value profile), in addition, scaling may introduce inaccuracy for branch probablity. The patch moves the function updateProfWeight from Instruction class to CallInst to remove the confusion. The patch also changes the scaling of branch_weights from a loop to a block because we know that ProfileData for branch_weights of CallInst will only have two operands at most. Differential Revision: https://reviews.llvm.org/D60911 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358900 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/Instruction.h | 3 --- include/llvm/IR/Instructions.h | 3 +++ lib/IR/Instruction.cpp | 43 --------------------------------- lib/IR/Instructions.cpp | 44 ++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 46 deletions(-) diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index b940d125a27..499c8166dc3 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -311,9 +311,6 @@ public: /// Returns false if no metadata was found. bool extractProfTotalWeight(uint64_t &TotalVal) const; - /// Updates branch_weights metadata by scaling it by \p S / \p T. - void updateProfWeight(uint64_t S, uint64_t T); - /// Sets the branch_weights metadata to \p W for CallInst. void setProfWeight(uint64_t W); diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 91e04ea59c8..095c82f5c42 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1730,6 +1730,9 @@ public: return isa(V) && classof(cast(V)); } + /// Updates profile metadata by scaling it by \p S / \p T. + void updateProfWeight(uint64_t S, uint64_t T); + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. diff --git a/lib/IR/Instruction.cpp b/lib/IR/Instruction.cpp index 32f3bfa66b1..f15bd601727 100644 --- a/lib/IR/Instruction.cpp +++ b/lib/IR/Instruction.cpp @@ -735,49 +735,6 @@ Instruction *Instruction::clone() const { return New; } -void Instruction::updateProfWeight(uint64_t S, uint64_t T) { - auto *ProfileData = getMetadata(LLVMContext::MD_prof); - if (ProfileData == nullptr) - return; - - auto *ProfDataName = dyn_cast(ProfileData->getOperand(0)); - if (!ProfDataName || (!ProfDataName->getString().equals("branch_weights") && - !ProfDataName->getString().equals("VP"))) - return; - - MDBuilder MDB(getContext()); - SmallVector Vals; - Vals.push_back(ProfileData->getOperand(0)); - APInt APS(128, S), APT(128, T); - if (ProfDataName->getString().equals("branch_weights")) - for (unsigned i = 1; i < ProfileData->getNumOperands(); i++) { - // Using APInt::div may be expensive, but most cases should fit 64 bits. - APInt Val(128, - mdconst::dyn_extract(ProfileData->getOperand(i)) - ->getValue() - .getZExtValue()); - Val *= APS; - Vals.push_back(MDB.createConstant( - ConstantInt::get(Type::getInt64Ty(getContext()), - Val.udiv(APT).getLimitedValue()))); - } - else if (ProfDataName->getString().equals("VP")) - for (unsigned i = 1; i < ProfileData->getNumOperands(); i += 2) { - // The first value is the key of the value profile, which will not change. - Vals.push_back(ProfileData->getOperand(i)); - // Using APInt::div may be expensive, but most cases should fit 64 bits. - APInt Val(128, - mdconst::dyn_extract(ProfileData->getOperand(i + 1)) - ->getValue() - .getZExtValue()); - Val *= APS; - Vals.push_back(MDB.createConstant( - ConstantInt::get(Type::getInt64Ty(getContext()), - Val.udiv(APT).getLimitedValue()))); - } - setMetadata(LLVMContext::MD_prof, MDNode::get(getContext(), Vals)); -} - void Instruction::setProfWeight(uint64_t W) { assert(isa(this) && "Can only set weights for call like instructions"); diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index d65c61c891a..ce281e0ed38 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -28,6 +28,7 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/MDBuilder.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" @@ -458,6 +459,49 @@ CallInst *CallInst::Create(CallInst *CI, ArrayRef OpB, return NewCI; } +// Update profile weight for call instruction by scaling it using the ratio +// of S/T. The meaning of "branch_weights" meta data for call instruction is +// transfered to represent call count. +void CallInst::updateProfWeight(uint64_t S, uint64_t T) { + auto *ProfileData = getMetadata(LLVMContext::MD_prof); + if (ProfileData == nullptr) + return; + + auto *ProfDataName = dyn_cast(ProfileData->getOperand(0)); + if (!ProfDataName || (!ProfDataName->getString().equals("branch_weights") && + !ProfDataName->getString().equals("VP"))) + return; + + MDBuilder MDB(getContext()); + SmallVector Vals; + Vals.push_back(ProfileData->getOperand(0)); + APInt APS(128, S), APT(128, T); + if (ProfDataName->getString().equals("branch_weights") && + ProfileData->getNumOperands() > 0) { + // Using APInt::div may be expensive, but most cases should fit 64 bits. + APInt Val(128, mdconst::dyn_extract(ProfileData->getOperand(1)) + ->getValue() + .getZExtValue()); + Val *= APS; + Vals.push_back(MDB.createConstant(ConstantInt::get( + Type::getInt64Ty(getContext()), Val.udiv(APT).getLimitedValue()))); + } else if (ProfDataName->getString().equals("VP")) + for (unsigned i = 1; i < ProfileData->getNumOperands(); i += 2) { + // The first value is the key of the value profile, which will not change. + Vals.push_back(ProfileData->getOperand(i)); + // Using APInt::div may be expensive, but most cases should fit 64 bits. + APInt Val(128, + mdconst::dyn_extract(ProfileData->getOperand(i + 1)) + ->getValue() + .getZExtValue()); + Val *= APS; + Vals.push_back(MDB.createConstant( + ConstantInt::get(Type::getInt64Ty(getContext()), + Val.udiv(APT).getLimitedValue()))); + } + setMetadata(LLVMContext::MD_prof, MDNode::get(getContext(), Vals)); +} + /// IsConstantOne - Return true only if val is constant int 1 static bool IsConstantOne(Value *val) { assert(val && "IsConstantOne does not work with nullptr val"); -- 2.50.1