Changed implementation of Serialize::EmitDiffPtrID and
[oota-llvm.git] / include / llvm / Bitcode / Serialize.h
1 //==- Serialize.h - Generic Object Serialization to Bitcode -------*- C++ -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Ted Kremenek and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the interface for generic object serialization to
11 // LLVM bitcode.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_BITCODE_SERIALIZE_OUTPUT
16 #define LLVM_BITCODE_SERIALIZE_OUTPUT
17
18 #include "llvm/Bitcode/Serialization.h"
19 #include "llvm/Bitcode/BitstreamWriter.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/DenseMap.h"
22
23 namespace llvm {
24
25 class Serializer {
26   BitstreamWriter& Stream;
27   SmallVector<uint64_t,10> Record;
28   unsigned BlockLevel;
29   
30   typedef DenseMap<const void*,unsigned> MapTy;
31   MapTy PtrMap;
32   
33 public:
34   Serializer(BitstreamWriter& stream);
35   ~Serializer();
36   
37   template <typename T>
38   inline void Emit(const T& X) { SerializeTrait<T>::Emit(*this,X); }
39   
40   void EmitInt(uint64_t X);
41   void EmitSInt(int64_t X);
42   
43   void EmitBool(bool X) { EmitInt(X); }
44   void EmitCStr(const char* beg, const char* end);
45   void EmitCStr(const char* cstr);
46   
47   void EmitPtr(const void* ptr) { EmitInt(getPtrId(ptr)); }
48
49   SerializedPtrID EmitPtr(const void* ptr,bool) {
50     SerializedPtrID ptr_id = getPtrId(ptr);
51     EmitInt(ptr_id);
52     return ptr_id;
53   }
54   
55   SerializedPtrID EmitDiffPtrID(const void* ptr, SerializedPtrID PrevID) {
56     assert (!isRegistered(ptr));
57     SerializedPtrID ptr_id = getPtrId(ptr);
58
59     if (ptr_id == 0)
60       EmitBool(false);
61     else {
62       assert (ptr_id > PrevID);
63       assert (PrevID == 0 || ptr_id - PrevID == 1);
64       EmitBool(true);
65     }
66     
67     return ptr_id;    
68   }    
69     
70   
71   template <typename T>
72   void EmitRef(const T& ref) { EmitPtr(&ref); }
73   
74   template <typename T>
75   void EmitOwnedPtr(T* ptr) {
76     EmitPtr(ptr);
77     if (ptr) SerializeTrait<T>::Emit(*this,*ptr);
78   }
79   
80   template <typename T1, typename T2>
81   void BatchEmitOwnedPtrs(T1* p1, T2* p2) {
82     // Optimization: Only emit the differences between the IDs.  Most of
83     // the time this difference will be "1", thus resulting in fewer bits.
84     assert (!isRegistered(p1));
85     assert (!isRegistered(p2));
86     
87     EmitDiffPtrID(p2,EmitPtr(p1,true));
88
89     if (p1) SerializeTrait<T1>::Emit(*this,*p1);
90     if (p2) SerializeTrait<T2>::Emit(*this,*p2);    
91   }
92
93   template <typename T1, typename T2, typename T3>
94   void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3) {
95     EmitDiffPtrID(p3,EmitDiffPtrID(p2,EmitPtr(p1)));
96
97     if (p1) SerializeTrait<T1>::Emit(*this,*p1);
98     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
99     if (p3) SerializeTrait<T3>::Emit(*this,*p3);
100   }
101   
102   template <typename T1, typename T2, typename T3, typename T4>
103   void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3, T4& p4) {
104     EmitDiffPtrID(p4,EmitDiffPtrID(p3,EmitDiffPtrID(p2,EmitPtr(p1))));
105
106     if (p1) SerializeTrait<T1>::Emit(*this,*p1);
107     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
108     if (p3) SerializeTrait<T3>::Emit(*this,*p3);
109     if (p4) SerializeTrait<T4>::Emit(*this,*p4);
110   }
111
112   template <typename T>
113   void BatchEmitOwnedPtrs(unsigned NumPtrs, T* const * Ptrs) {
114     SerializedPtrID ID;
115     
116     for (unsigned i = 0; i < NumPtrs; ++i) {
117       if (i == 0) ID = EmitPtr(Ptrs[i],true);
118       else ID = EmitDiffPtrID(Ptrs[i],ID);
119     }
120
121     for (unsigned i = 0; i < NumPtrs; ++i)
122       if (Ptrs[i]) SerializeTrait<T>::Emit(*this,*Ptrs[i]);
123   }
124   
125   template <typename T1, typename T2>
126   void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, T2* p2) {
127     
128     SerializedPtrID ID = EmitPtr(p2,true);
129
130     for (unsigned i = 0; i < NumT1Ptrs; ++i)
131       ID = EmitDiffPtrID(Ptrs[i],ID);
132     
133     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
134     
135     for (unsigned i = 0; i < NumT1Ptrs; ++i)
136       if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);    
137   }
138   
139   template <typename T1, typename T2, typename T3>
140   void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs,
141                           T2* p2, T3* p3) {
142     
143     SerializedPtrID TempID = EmitDiffPtrID(p3,EmitPtr(p2,true));
144     
145     for (unsigned i = 0; i < NumT1Ptrs; ++i)
146       TempID = EmitDiffPtrID(Ptrs[i],TempID);
147     
148     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
149     if (p3) SerializeTrait<T3>::Emit(*this,*p3);
150     
151     for (unsigned i = 0; i < NumT1Ptrs; ++i)
152       if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);
153     
154   }
155     
156   bool isRegistered(const void* p) const;
157   
158   void FlushRecord() { if (inRecord()) EmitRecord(); }  
159   void EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3);
160   void ExitBlock();    
161   
162 private:
163   void EmitRecord();
164   inline bool inRecord() { return Record.size() > 0; }
165   SerializedPtrID getPtrId(const void* ptr);
166 };
167
168 } // end namespace llvm
169 #endif