[PATCH] Add function entry count metadata.

Diego Novillo dnovillo at google.com
Fri May 8 16:04:45 PDT 2015


Hi dexonsmith, bogner,

This adds three Function methods to handle function entry counts:
setEntryCount(), hasEntryCount() and getEntryCount().

Entry counts are stored under the MD_prof metadata node with the name
"function_entry_count". They are unsigned 64 bit values set by profilers
(instrumentation and sample profiler changes coming up).

I had some internal debate about what to return when
Function::getEntryCount() is called without the function having its
metadata set. I don't want to return a special sentinel value, because
those are typically problematic down the road.

So, I added a Function::hasEntryCount() predicate. If
Function::getEntryCount() is called with no metadata present, it will
cause a compiler assertion.

http://reviews.llvm.org/D9628

Files:
  include/llvm/IR/Function.h
  include/llvm/IR/MDBuilder.h
  lib/IR/MDBuilder.cpp
  unittests/IR/MetadataTest.cpp

Index: include/llvm/IR/Function.h
===================================================================
--- include/llvm/IR/Function.h
+++ include/llvm/IR/Function.h
@@ -23,7 +23,11 @@
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/GlobalObject.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Metadata.h"
 #include "llvm/Support/Compiler.h"
 
 namespace llvm {
@@ -194,6 +198,29 @@
                                  AttributeSet::FunctionIndex, Kind, Value));
   }
 
+  /// @brief Set the entry count for this function.
+  void setEntryCount(uint64_t Count) {
+    MDBuilder MDB(getContext());
+    setMetadata(LLVMContext::MD_prof, MDB.createFunctionEntryCount(Count));
+  }
+
+  /// @brief Return true if the function has a known entry count.
+  bool hasEntryCount() const {
+    MDNode *MD = getMetadata(LLVMContext::MD_prof);
+    if (MD && MD->getOperand(0))
+      if (MDString* MDS = dyn_cast<MDString>(MD->getOperand(0)))
+        return MDS->getString().equals("function_entry_count");
+    return false;
+  }
+
+  /// @brief Get the entry count for this function.
+  uint64_t getEntryCount() const {
+    assert(hasEntryCount() && "No entry count available for this function");
+    MDNode *MD = getMetadata(LLVMContext::MD_prof);
+    ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));
+    return CI->getValue().getZExtValue();
+  }
+
   /// @brief Return true if the function has the attribute.
   bool hasFnAttribute(Attribute::AttrKind Kind) const {
     return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
Index: include/llvm/IR/MDBuilder.h
===================================================================
--- include/llvm/IR/MDBuilder.h
+++ include/llvm/IR/MDBuilder.h
@@ -60,6 +60,9 @@
   /// \brief Return metadata containing a number of branch weights.
   MDNode *createBranchWeights(ArrayRef<uint32_t> Weights);
 
+  /// \brief Return metadata containing the entry count for a function.
+  MDNode *createFunctionEntryCount(uint64_t Count);
+
   //===------------------------------------------------------------------===//
   // Range metadata.
   //===------------------------------------------------------------------===//
Index: lib/IR/MDBuilder.cpp
===================================================================
--- lib/IR/MDBuilder.cpp
+++ lib/IR/MDBuilder.cpp
@@ -53,6 +53,16 @@
   return MDNode::get(Context, Vals);
 }
 
+MDNode *MDBuilder::createFunctionEntryCount(uint64_t Count) {
+  SmallVector<Metadata *, 2> Vals(2);
+  Vals[0] = createString("function_entry_count");
+
+  Type *Int64Ty = Type::getInt64Ty(Context);
+  Vals[1] = createConstant(ConstantInt::get(Int64Ty, Count));
+
+  return MDNode::get(Context, Vals);
+}
+
 MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) {
   assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");
 
Index: unittests/IR/MetadataTest.cpp
===================================================================
--- unittests/IR/MetadataTest.cpp
+++ unittests/IR/MetadataTest.cpp
@@ -2272,4 +2272,12 @@
   EXPECT_FALSE(verifyFunction(*F));
 }
 
+TEST_F(FunctionAttachmentTest, EntryCount) {
+  Function *F = getFunction("foo");
+  EXPECT_FALSE(F->hasEntryCount());
+  F->setEntryCount(12304);
+  EXPECT_TRUE(F->hasEntryCount());
+  EXPECT_EQ(12304u, F->getEntryCount());
+}
+
 }

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9628.25380.patch
Type: text/x-patch
Size: 3460 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150508/2a1983b2/attachment.bin>


More information about the llvm-commits mailing list