1 //==- Serialize.h - Generic Object Serialization to Bitcode -------*- C++ -*-=//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This file defines the interface for generic object serialization to
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_BITCODE_SERIALIZE_OUTPUT
16 #define LLVM_BITCODE_SERIALIZE_OUTPUT
18 #include "llvm/Bitcode/Serialization.h"
19 #include "llvm/Bitcode/BitstreamWriter.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/DenseMap.h"
26 BitstreamWriter& Stream;
27 SmallVector<uint64_t,10> Record;
30 typedef DenseMap<const void*,unsigned> MapTy;
34 Serializer(BitstreamWriter& stream);
38 inline void Emit(const T& X) { SerializeTrait<T>::Emit(*this,X); }
40 void EmitInt(uint64_t X);
41 void EmitSInt(int64_t X);
43 void EmitBool(bool X) { EmitInt(X); }
44 void EmitCStr(const char* beg, const char* end);
45 void EmitCStr(const char* cstr);
47 void EmitPtr(const void* ptr) { EmitInt(getPtrId(ptr)); }
49 SerializedPtrID EmitPtr(const void* ptr,bool) {
50 SerializedPtrID ptr_id = getPtrId(ptr);
55 SerializedPtrID EmitDiffPtrID(const void* ptr, SerializedPtrID PrevID) {
56 assert (!isRegistered(ptr));
57 SerializedPtrID ptr_id = getPtrId(ptr);
62 assert (ptr_id > PrevID);
63 EmitInt(ptr_id-PrevID);
71 void EmitRef(const T& ref) { EmitPtr(&ref); }
74 void EmitOwnedPtr(T* ptr) {
76 if (ptr) SerializeTrait<T>::Emit(*this,*ptr);
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));
86 EmitDiffPtrID(p2,EmitPtr(p1,true));
88 if (p1) SerializeTrait<T1>::Emit(*this,*p1);
89 if (p2) SerializeTrait<T2>::Emit(*this,*p2);
92 template <typename T1, typename T2, typename T3>
93 void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3) {
94 EmitDiffPtrID(p3,EmitDiffPtrID(p2,EmitPtr(p1)));
96 if (p1) SerializeTrait<T1>::Emit(*this,*p1);
97 if (p2) SerializeTrait<T2>::Emit(*this,*p2);
98 if (p3) SerializeTrait<T3>::Emit(*this,*p3);
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))));
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);
111 template <typename T>
112 void BatchEmitOwnedPtrs(unsigned NumPtrs, T* const * Ptrs) {
115 for (unsigned i = 0; i < NumPtrs; ++i) {
116 if (i == 0) ID = EmitPtr(Ptrs[i],true);
117 else ID = EmitDiffPtrID(Ptrs[i],ID);
120 for (unsigned i = 0; i < NumPtrs; ++i)
121 if (Ptrs[i]) SerializeTrait<T>::Emit(*this,*Ptrs[i]);
124 template <typename T1, typename T2>
125 void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, T2* p2) {
127 SerializedPtrID ID = EmitPtr(p2,true);
129 for (unsigned i = 0; i < NumT1Ptrs; ++i)
130 ID = EmitDiffPtrID(Ptrs[i],ID);
132 if (p2) SerializeTrait<T2>::Emit(*this,*p2);
134 for (unsigned i = 0; i < NumT1Ptrs; ++i)
135 if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);
138 template <typename T1, typename T2, typename T3>
139 void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs,
142 SerializedPtrID TempID = EmitDiffPtrID(p3,EmitPtr(p2,true));
144 for (unsigned i = 0; i < NumT1Ptrs; ++i)
145 TempID = EmitDiffPtrID(Ptrs[i],TempID);
147 if (p2) SerializeTrait<T2>::Emit(*this,*p2);
148 if (p3) SerializeTrait<T3>::Emit(*this,*p3);
150 for (unsigned i = 0; i < NumT1Ptrs; ++i)
151 if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);
155 bool isRegistered(const void* p) const;
157 void FlushRecord() { if (inRecord()) EmitRecord(); }
158 void EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3);
163 inline bool inRecord() { return Record.size() > 0; }
164 SerializedPtrID getPtrId(const void* ptr);
167 } // end namespace llvm