[PATCH] Add function entry count metadata.
Justin Bogner
mail at justinbogner.com
Fri May 8 17:49:29 PDT 2015
Diego Novillo <dnovillo at google.com> writes:
> Return Optional<uint64_t> from getEntryCount to indicate whether a
> count is available.
Might as well get rid of hasEntryCount now and look the metadata up
directly in getEntryCount. I can't see why a consumer would need to know
there is a count and not need the count itself.
> I'm getting several odd failures in the testsuite. Even though the new code
> is only called from the unittest, I'm getting several related failures.
> For example,
>
> bin/opt -S test/Verifier/statepoint.ll -verify
> ----------------------------------------------
>
> Exit Code: 2
>
> Command Output (stderr):
> ------------------------
>
> gc.statepoint mismatch in number of vararg call args
>
> %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
>
> gc.statepoint mismatch in number of vararg call args
>
> %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
>
> gc.statepoint mismatch in number of vararg call args
>
> %0 = invoke i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1)
> to label %normal_dest unwind label %exceptional_return
>
> It seems related to metadata, but I'm not sure how my patch could've triggered
> this. Am I missing anything obvious?
This seems pretty weird - you're not even calling the new API yet...
> Thanks.
>
>
> http://reviews.llvm.org/D9628
>
> Files:
> include/llvm/IR/Function.h
> include/llvm/IR/MDBuilder.h
> lib/IR/MDBuilder.cpp
> unittests/IR/MetadataTest.cpp
>
> EMAIL PREFERENCES
> http://reviews.llvm.org/settings/panel/emailpreferences/
>
> Index: include/llvm/IR/Function.h
> ===================================================================
> --- include/llvm/IR/Function.h
> +++ include/llvm/IR/Function.h
> @@ -19,11 +19,16 @@
> #define LLVM_IR_FUNCTION_H
>
> #include "llvm/ADT/iterator_range.h"
> +#include "llvm/ADT/Optional.h"
> #include "llvm/IR/Argument.h"
> #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 +199,30 @@
> 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.
> + Optional<uint64_t> getEntryCount() const {
> + if (!hasEntryCount())
> + return None;
> + 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());
> +}
> +
> }
More information about the llvm-commits
mailing list