summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Instruction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/Instruction.cpp')
-rw-r--r--llvm/lib/IR/Instruction.cpp23
1 files changed, 23 insertions, 0 deletions
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<MDString>(ProfileData->getOperand(0));
+ if (!ProfDataName || !ProfDataName->getString().equals("branch_weights"))
+ return;
+
+ SmallVector<uint32_t, 4> 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<ConstantInt>(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));
+}
OpenPOWER on IntegriCloud