From e593049fb057a014e912973e8717463e060c9d60 Mon Sep 17 00:00:00 2001 From: Dehao Chen Date: Mon, 20 Mar 2017 16:40:44 +0000 Subject: Updates branch_weights annotation for call instructions during inlining. Summary: Inliner should update the branch_weights annotation to scale it to proper value. Reviewers: davidxl, eraman Reviewed By: eraman Subscribers: zzheng, llvm-commits Differential Revision: https://reviews.llvm.org/D30767 llvm-svn: 298270 --- llvm/lib/IR/Instruction.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'llvm/lib/IR') diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 2ca496e2dc7..fc453d4f8d7 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -17,6 +17,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" +#include "llvm/IR/MDBuilder.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" using namespace llvm; @@ -629,3 +630,25 @@ Instruction *Instruction::clone() const { New->copyMetadata(*this); 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")) + return; + + SmallVector Weights; + for (unsigned i = 1; i < ProfileData->getNumOperands(); i++) { + // Using APInt::div may be expensive, but most cases should fit in 64 bits. + APInt Val(128, mdconst::dyn_extract(ProfileData->getOperand(i)) + ->getValue() + .getZExtValue()); + Val *= APInt(128, S); + Weights.push_back(Val.udiv(APInt(128, T)).getLimitedValue()); + } + MDBuilder MDB(getContext()); + setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(Weights)); +} -- cgit v1.2.3