diff --git a/docs/LangRef.html b/docs/LangRef.html
index 9cb7e6392ab..2b81279b6e5 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -105,6 +105,7 @@
+
+
alloc metadata may be attached to any instruction returning a
+ pointer. It can be used to express the size and offset relative to the
+ beginning of the buffer pointed by.
+
+
+
+The first parameter is a function that returns the size of the buffer, and
+ the second (optional) parameter is a function that returns the offset from
+ the beginning of the buffer. If the second parameter is not present or null,
+ the offset is assumed to be null. Both functions must be either readonly or
+ readnone.
+alloc metadata can have additional parameters, which are passed to
+ the size and offset functions when they are evaluated. Therefore the size and
+ offset functions must have the same signature.
+
+
+
+
+
Examples:
+
+
+ ; size of buffer allocated by this call is my_malloc_size(%s), and offset=0
+ %a = call my_malloc(%s), !alloc !{i32 (i32)* @my_malloc_size, null, i32 %s}
+
+ ; size of the buffer pointed by *ptr is size(%x), and offset=offset(%x)
+ %b = load i8** %foo, !alloc !{i32 (i32)* @size, i32 (i32)* @offset, i32 %x}
+
+ ; size of buffer allocated by this call is foo_size(), and offset=0
+ %a = call alloc_foo(%s), !alloc !0
+...
+!0 = metadata {i32 ()* @foo_size}
+
+
+
+
diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h
index a8306a9e761..d15f3e0850f 100644
--- a/include/llvm/LLVMContext.h
+++ b/include/llvm/LLVMContext.h
@@ -43,7 +43,8 @@ public:
MD_tbaa = 1, // "tbaa"
MD_prof = 2, // "prof"
MD_fpmath = 3, // "fpmath"
- MD_range = 4 // "range"
+ MD_range = 4, // "range"
+ MD_alloc = 5 // "alloc"
};
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp
index f07f0b39392..a140543a51e 100644
--- a/lib/VMCore/LLVMContext.cpp
+++ b/lib/VMCore/LLVMContext.cpp
@@ -53,6 +53,11 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
unsigned RangeID = getMDKindID("range");
assert(RangeID == MD_range && "range kind id drifted");
(void)RangeID;
+
+ // Create the 'alloc' metadata kind.
+ unsigned AllocID = getMDKindID("alloc");
+ assert(AllocID == MD_alloc && "alloc kind id drifted");
+ (void)AllocID;
}
LLVMContext::~LLVMContext() { delete pImpl; }
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 477b81dc67f..2ca4854d9ac 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -1672,6 +1672,39 @@ void Verifier::visitInstruction(Instruction &I) {
}
}
+ if (MDNode *MD = I.getMetadata(LLVMContext::MD_alloc)) {
+ Assert1(I.getType()->isPointerTy(), "alloc requires a pointer result", &I);
+ Assert1(MD->getNumOperands() >= 1, "alloc takes at least one operand", &I);
+ Function *SizeFn = dyn_cast