UseListShuffleVector: Add a copy constructor to appease msc17.
[oota-llvm.git] / include / llvm / IR / UseListOrder.h
1 //===- llvm/IR/UseListOrder.h - LLVM Use List Order functions ---*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file has functions to modify the use-list order and to verify that it
11 // doesn't change after serialization.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_IR_USELISTORDER_H
16 #define LLVM_IR_USELISTORDER_H
17
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include <vector>
21
22 namespace llvm {
23
24 class Module;
25 class Function;
26 class Value;
27
28 /// \brief Structure to hold a use-list shuffle vector.
29 ///
30 /// Stores most use-lists locally, but large use-lists use an extra heap entry.
31 /// Costs two fewer pointers than the equivalent \a SmallVector.
32 class UseListShuffleVector {
33   unsigned Size;
34   union {
35     unsigned *Ptr;
36     unsigned Array[6];
37   } Storage;
38
39   bool isSmall() const { return Size <= 6; }
40   unsigned *data() { return isSmall() ? Storage.Array : Storage.Ptr; }
41   const unsigned *data() const {
42     return isSmall() ? Storage.Array : Storage.Ptr;
43   }
44
45 public:
46   UseListShuffleVector() : Size(0) {}
47   UseListShuffleVector(UseListShuffleVector &&X) {
48     std::memcpy(this, &X, sizeof(UseListShuffleVector));
49     X.Size = 0;
50   }
51   UseListShuffleVector(const UseListShuffleVector &X) {
52     std::memcpy(this, &X, sizeof(UseListShuffleVector));
53     if (!isSmall()) {
54       Storage.Ptr = new unsigned[Size];
55       std::memcpy(Storage.Ptr, X.Storage.Ptr, Size * sizeof(*Storage.Ptr));
56     }
57   }
58   explicit UseListShuffleVector(size_t Size) : Size(Size) {
59     if (!isSmall())
60       Storage.Ptr = new unsigned[Size];
61   }
62   ~UseListShuffleVector() {
63     if (!isSmall())
64       delete[] Storage.Ptr;
65   }
66
67   typedef unsigned *iterator;
68   typedef const unsigned *const_iterator;
69
70   size_t size() const { return Size; }
71   iterator begin() { return data(); }
72   iterator end() { return begin() + size(); }
73   const_iterator begin() const { return data(); }
74   const_iterator end() const { return begin() + size(); }
75   unsigned &operator[](size_t I) { return data()[I]; }
76   unsigned operator[](size_t I) const { return data()[I]; }
77 };
78
79 /// \brief Structure to hold a use-list order.
80 struct UseListOrder {
81   const Value *V;
82   const Function *F;
83   UseListShuffleVector Shuffle;
84
85   UseListOrder(const Value *V, const Function *F, size_t ShuffleSize)
86       : V(V), F(F), Shuffle(ShuffleSize) {}
87 };
88
89 typedef std::vector<UseListOrder> UseListOrderStack;
90
91 /// \brief Whether to preserve use-list ordering.
92 bool shouldPreserveBitcodeUseListOrder();
93 bool shouldPreserveAssemblyUseListOrder();
94
95 /// \brief Shuffle all use-lists in a module.
96 ///
97 /// Adds \c SeedOffset to the default seed for the random number generator.
98 void shuffleUseLists(Module &M, unsigned SeedOffset = 0);
99
100 } // end namespace llvm
101
102 #endif