#ifndef LLVM_IR_USER_H
#define LLVM_IR_USER_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Value.h"
friend struct HungoffOperandTraits;
virtual void anchor();
+ LLVM_ATTRIBUTE_ALWAYS_INLINE inline static void *
+ allocateFixedOperandUser(size_t, unsigned, unsigned);
+
protected:
/// Allocate a User with an operand pointer co-allocated.
///
/// This is used for subclasses which have a fixed number of operands.
void *operator new(size_t Size, unsigned Us);
- User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps)
+ /// Allocate a User with the operands co-allocated. If DescBytes is non-zero
+ /// then allocate an additional DescBytes bytes before the operands. These
+ /// bytes can be accessed by calling getDescriptor.
+ ///
+ /// DescBytes needs to be divisible by sizeof(void *). The allocated
+ /// descriptor, if any, is aligned to sizeof(void *) bytes.
+ ///
+ /// This is used for subclasses which have a fixed number of operands.
+ void *operator new(size_t Size, unsigned Us, unsigned DescBytes);
+
+ User(Type *ty, unsigned vty, Use *, unsigned NumOps)
: Value(ty, vty) {
assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands");
NumUserOperands = NumOps;
unsigned getNumOperands() const { return NumUserOperands; }
+ /// Returns the descriptor co-allocated with this User instance.
+ ArrayRef<const uint8_t> getDescriptor() const;
+
+ /// Returns the descriptor co-allocated with this User instance.
+ MutableArrayRef<uint8_t> getDescriptor();
+
/// Set the number of operands on a GlobalVariable.
///
/// GlobalVariable always allocates space for a single operands, but
return value_op_iterator(op_end());
}
iterator_range<value_op_iterator> operand_values() {
- return iterator_range<value_op_iterator>(value_op_begin(), value_op_end());
+ return make_range(value_op_begin(), value_op_end());
}
/// \brief Drop all references to operands.
};
// Either Use objects, or a Use pointer can be prepended to User.
static_assert(AlignOf<Use>::Alignment >= AlignOf<User>::Alignment,
- "Alignment sufficient after objects prepended to User");
+ "Alignment is insufficient after objects prepended to User");
static_assert(AlignOf<Use *>::Alignment >= AlignOf<User>::Alignment,
- "Alignment sufficient after objects prepended to User");
+ "Alignment is insufficient after objects prepended to User");
template<> struct simplify_type<User::op_iterator> {
typedef Value* SimpleType;