[llvm-commits] [llvm] r152090 - /llvm/trunk/include/llvm/ADT/UsuallyTinyPtrVector.h

Argyrios Kyrtzidis kyrtzidis at apple.com
Mon Mar 5 19:06:37 PST 2012


On Mar 5, 2012, at 6:24 PM, Benjamin Kramer wrote:

> On 06.03.2012, at 03:15, Argyrios Kyrtzidis <akyrtzi at gmail.com> wrote:
> 
>> Author: akirtzidis
>> Date: Mon Mar  5 20:08:48 2012
>> New Revision: 152090
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=152090&view=rev
>> Log:
>> Add include/llvm/ADT/UsuallyTinyPtrVector.h which is a vector that
>> optimizes the case where there is only one element.
> 
> Hi Argyrios,
> 
> What's the difference between UsuallyTinyPtrVector and the existing
> TinyPtrVector? Can they be unified somehow?

Hmm, with UsuallyTinyPtrVector you cannot copy it and you have to manually call Destroy on it ?
I think we can just use TinyPtrVector; maybe UsuallyTinyPtrVector was introduced before TinyPtrVector, not sure.

Thanks!

> 
> - Ben
> 
>> 
>> Added:
>>   llvm/trunk/include/llvm/ADT/UsuallyTinyPtrVector.h
>> 
>> Added: llvm/trunk/include/llvm/ADT/UsuallyTinyPtrVector.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/UsuallyTinyPtrVector.h?rev=152090&view=auto
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ADT/UsuallyTinyPtrVector.h (added)
>> +++ llvm/trunk/include/llvm/ADT/UsuallyTinyPtrVector.h Mon Mar  5 20:08:48 2012
>> @@ -0,0 +1,137 @@
>> +//===-- UsuallyTinyPtrVector.h - Pointer vector class -----------*- 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 UsuallyTinyPtrVector class, which is a vector that
>> +//  optimizes the case where there is only one element.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +#ifndef LLVM_ADT_USUALLY_TINY_PTR_VECTOR_H
>> +#define LLVM_ADT_USUALLY_TINY_PTR_VECTOR_H
>> +
>> +#include <vector>
>> +
>> +namespace llvm {
>> +
>> +/// \brief A vector class template that is optimized for storing a single
>> +/// pointer element.
>> +template<typename T>
>> +class UsuallyTinyPtrVector {
>> +  /// \brief Storage for the vector.
>> +  ///
>> +  /// When the low bit is zero, this is a T *. When the
>> +  /// low bit is one, this is a std::vector<T *> *.
>> +  mutable uintptr_t Storage;
>> +
>> +  typedef std::vector<T*> vector_type;
>> +
>> +public:
>> +  UsuallyTinyPtrVector() : Storage(0) { }
>> +  explicit UsuallyTinyPtrVector(T *Element)
>> +    : Storage(reinterpret_cast<uintptr_t>(Element)) { }
>> +
>> +  bool empty() const { return !Storage; }
>> +
>> +  typedef const T **iterator;
>> +  iterator begin() const;
>> +  iterator end() const;
>> +  size_t size() const;
>> +
>> +  void push_back(T *Method);
>> +  iterator erase(const iterator ElementPos);
>> +  void Destroy();
>> +};
>> +
>> +template<typename T>
>> +typename UsuallyTinyPtrVector<T>::iterator
>> +UsuallyTinyPtrVector<T>::begin() const {
>> +  if ((Storage & 0x01) == 0)
>> +    return reinterpret_cast<iterator>(&Storage);
>> +
>> +  vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
>> +  return &Vec->front();
>> +}
>> +
>> +template<typename T>
>> +typename UsuallyTinyPtrVector<T>::iterator
>> +UsuallyTinyPtrVector<T>::end() const {
>> +  if ((Storage & 0x01) == 0) {
>> +    if (Storage == 0)
>> +      return reinterpret_cast<iterator>(&Storage);
>> +
>> +    return reinterpret_cast<iterator>(&Storage) + 1;
>> +  }
>> +
>> +  vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
>> +  return &Vec->front() + Vec->size();
>> +}
>> +
>> +template<typename T>
>> +size_t UsuallyTinyPtrVector<T>::size() const {
>> +  if ((Storage & 0x01) == 0)
>> +    return (Storage == 0) ? 0 : 1;
>> +
>> +  vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
>> +  return Vec->size();
>> +}
>> +
>> +template<typename T>
>> +void UsuallyTinyPtrVector<T>::push_back(T *Element) {
>> +  if (Storage == 0) {
>> +    // 0 -> 1 element.
>> +    Storage = reinterpret_cast<uintptr_t>(Element);
>> +    return;
>> +  }
>> +
>> +  vector_type *Vec;
>> +  if ((Storage & 0x01) == 0) {
>> +    // 1 -> 2 elements. Allocate a new vector and push the element into that
>> +    // vector.
>> +    Vec = new vector_type;
>> +    Vec->push_back(reinterpret_cast<T *>(Storage));
>> +    Storage = reinterpret_cast<uintptr_t>(Vec) | 0x01;
>> +  } else
>> +    Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
>> +
>> +  // Add the new element to the vector.
>> +  Vec->push_back(Element);
>> +}
>> +
>> +template<typename T>
>> +typename UsuallyTinyPtrVector<T>::iterator
>> +UsuallyTinyPtrVector<T>::erase(
>> +  const typename UsuallyTinyPtrVector<T>::iterator ElementPos) {
>> +  // only one item
>> +  if ((Storage & 0x01) == 0) {
>> +    // if the element is found remove it
>> +    if (ElementPos == reinterpret_cast<T **>(&Storage))
>> +      Storage = 0;
>> +  } else {
>> +    // multiple items in a vector; just do the erase, there is no
>> +    // benefit to collapsing back to a pointer
>> +    vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
>> +    unsigned index = ElementPos -
>> +         const_cast<typename UsuallyTinyPtrVector<T>::iterator>(&Vec->front());
>> +    if (index < Vec->size())
>> +      return const_cast<typename UsuallyTinyPtrVector<T>::iterator>(
>> +                                         &*(Vec->erase(Vec->begin() + index)));
>> +  }
>> +  return end();
>> +}
>> +
>> +template<typename T>
>> +void UsuallyTinyPtrVector<T>::Destroy() {
>> +  if (Storage & 0x01)
>> +    delete reinterpret_cast<vector_type *>(Storage & ~0x01);
>> +
>> +  Storage = 0;
>> +}
>> +
>> +}
>> +#endif
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list