From 34b763694e74ee16e68fd85488bfe0443c51170d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 28 Nov 2008 23:31:44 +0000 Subject: add a generic "bitmangled pointer" class, which allows a parameterized pointer and integer type to be used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60224 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/PointerIntPair.h | 69 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 include/llvm/ADT/PointerIntPair.h (limited to 'include/llvm/ADT/PointerIntPair.h') diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h new file mode 100644 index 0000000000..955dd40c68 --- /dev/null +++ b/include/llvm/ADT/PointerIntPair.h @@ -0,0 +1,69 @@ +//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the PointerIntPair class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_POINTERINTPAIR_H +#define LLVM_ADT_POINTERINTPAIR_H + +#include + +namespace llvm { + +/// PointerIntPair - This class implements a pair of a pointer and small +/// integer. It is designed to represet this in the space required by one +/// pointer by bitmangling the integer into the low part of the pointer. This +/// can only be done for small integers: typically up to 3 bits, but it depends +/// on the alignment returned by the allocator in use. +/// +template +class PointerIntPair { + intptr_t Value; +public: + PointerIntPair() : Value(0) {} + PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) { + setPointer(Ptr); + setInt(Int); + } + + PointerTy getPointer() const { + return reinterpret_cast(Value & ~((1 << IntBits)-1)); + } + + IntType getInt() const { + return (IntType)(Value & (1 << IntBits)-1); + } + + void setPointer(PointerTy Ptr) { + intptr_t PtrVal = reinterpret_cast(Ptr); + assert((PtrVal & (1 << IntBits)-1) == 0 && + "Pointer is no sufficiently aligned"); + Value = PtrVal | (intptr_t)getInt(); + } + + void setInt(IntType Int) { + assert(Int < (1 << IntBits) && "Integer too large for field"); + Value |= reinterpret_cast(getPointer()) | (intptr_t)Int; + } + + void *getOpaqueValue() const { return reinterpret_cast(Value); } + void setFromOpaqueValue(void *Val) { Value = reinterpret_cast(Val);} + + bool operator==(const PointerIntPair &RHS) const { + return Value == RHS.Value; + } + bool operator!=(const PointerIntPair &RHS) const { + return Value != RHS.Value; + } +}; + +} // end namespace llvm +#endif -- cgit v1.2.3