Implemented optimization for BatchEmitOwnedPtrs that we only emit one complete
[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       EmitInt(0);
61     else {
62       assert (ptr_id > PrevID);
63       EmitInt(ptr_id-PrevID);
64     }
65     
66     return ptr_id;    
67   }    
68     
69   
70   template <typename T>
71   void EmitRef(const T& ref) { EmitPtr(&ref); }
72   
73   template <typename T>
74   void EmitOwnedPtr(T* ptr) {
75     EmitPtr(ptr);
76     if (ptr) SerializeTrait<T>::Emit(*this,*ptr);
77   }
78   
79   template <typename T1, typename T2>
80   void BatchEmitOwnedPtrs(T1* p1, T2* p2) {
81     // Optimization: Only emit the differences between the IDs.  Most of
82     // the time this difference will be "1", thus resulting in fewer bits.
83     assert (!isRegistered(p1));
84     assert (!isRegistered(p2));
85     
86     EmitDiffPtrID(p2,EmitPtr(p1,true));
87
88     if (p1) SerializeTrait<T1>::Emit(*this,*p1);
89     if (p2) SerializeTrait<T2>::Emit(*this,*p2);    
90   }
91
92   template <typename T1, typename T2, typename T3>
93   void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3) {
94     EmitDiffPtrID(p3,EmitDiffPtrID(p2,EmitPtr(p1)));
95
96     if (p1) SerializeTrait<T1>::Emit(*this,*p1);
97     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
98     if (p3) SerializeTrait<T3>::Emit(*this,*p3);
99   }
100   
101   template <typename T1, typename T2, typename T3, typename T4>
102   void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3, T4& p4) {
103     EmitDiffPtrID(p4,EmitDiffPtrID(p3,EmitDiffPtrID(p2,EmitPtr(p1))));
104
105     if (p1) SerializeTrait<T1>::Emit(*this,*p1);
106     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
107     if (p3) SerializeTrait<T3>::Emit(*this,*p3);
108     if (p4) SerializeTrait<T4>::Emit(*this,*p4);
109   }
110
111   template <typename T>
112   void BatchEmitOwnedPtrs(unsigned NumPtrs, T* const * Ptrs) {
113     SerializedPtrID ID;
114     
115     for (unsigned i = 0; i < NumPtrs; ++i) {
116       if (i == 0) ID = EmitPtr(Ptrs[i],true);
117       else ID = EmitDiffPtrID(Ptrs[i],ID);
118     }
119
120     for (unsigned i = 0; i < NumPtrs; ++i)
121       if (Ptrs[i]) SerializeTrait<T>::Emit(*this,*Ptrs[i]);
122   }
123   
124   template <typename T1, typename T2>
125   void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, T2* p2) {
126     
127     SerializedPtrID ID = EmitPtr(p2,true);
128
129     for (unsigned i = 0; i < NumT1Ptrs; ++i)
130       ID = EmitDiffPtrID(Ptrs[i],ID);
131     
132     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
133     
134     for (unsigned i = 0; i < NumT1Ptrs; ++i)
135       if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);    
136   }
137   
138   template <typename T1, typename T2, typename T3>
139   void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs,
140                           T2* p2, T3* p3) {
141     
142     SerializedPtrID TempID = EmitDiffPtrID(p3,EmitPtr(p2,true));
143     
144     for (unsigned i = 0; i < NumT1Ptrs; ++i)
145       TempID = EmitDiffPtrID(Ptrs[i],TempID);
146     
147     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
148     if (p3) SerializeTrait<T3>::Emit(*this,*p3);
149     
150     for (unsigned i = 0; i < NumT1Ptrs; ++i)
151       if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);
152     
153   }
154     
155   bool isRegistered(const void* p) const;
156   
157   void FlushRecord() { if (inRecord()) EmitRecord(); }  
158   void EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3);
159   void ExitBlock();    
160   
161 private:
162   void EmitRecord();
163   inline bool inRecord() { return Record.size() > 0; }
164   SerializedPtrID getPtrId(const void* ptr);
165 };
166
167 } // end namespace llvm
168 #endif