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 assert (PrevID == 0 || ptr_id - PrevID == 1);
72 void EmitRef(const T& ref) { EmitPtr(&ref); }
75 void EmitOwnedPtr(T* ptr) {
77 if (ptr) SerializeTrait<T>::Emit(*this,*ptr);
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));
87 EmitDiffPtrID(p2,EmitPtr(p1,true));
89 if (p1) SerializeTrait<T1>::Emit(*this,*p1);
90 if (p2) SerializeTrait<T2>::Emit(*this,*p2);
93 template <typename T1, typename T2, typename T3>
94 void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3) {
95 EmitDiffPtrID(p3,EmitDiffPtrID(p2,EmitPtr(p1)));
97 if (p1) SerializeTrait<T1>::Emit(*this,*p1);
98 if (p2) SerializeTrait<T2>::Emit(*this,*p2);
99 if (p3) SerializeTrait<T3>::Emit(*this,*p3);
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))));
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);
112 template <typename T>
113 void BatchEmitOwnedPtrs(unsigned NumPtrs, T* const * Ptrs) {
116 for (unsigned i = 0; i < NumPtrs; ++i) {
117 if (i == 0) ID = EmitPtr(Ptrs[i],true);
118 else ID = EmitDiffPtrID(Ptrs[i],ID);
121 for (unsigned i = 0; i < NumPtrs; ++i)
122 if (Ptrs[i]) SerializeTrait<T>::Emit(*this,*Ptrs[i]);
125 template <typename T1, typename T2>
126 void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, T2* p2) {
128 SerializedPtrID ID = EmitPtr(p2,true);
130 for (unsigned i = 0; i < NumT1Ptrs; ++i)
131 ID = EmitDiffPtrID(Ptrs[i],ID);
133 if (p2) SerializeTrait<T2>::Emit(*this,*p2);
135 for (unsigned i = 0; i < NumT1Ptrs; ++i)
136 if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);
139 template <typename T1, typename T2, typename T3>
140 void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs,
143 SerializedPtrID TempID = EmitDiffPtrID(p3,EmitPtr(p2,true));
145 for (unsigned i = 0; i < NumT1Ptrs; ++i)
146 TempID = EmitDiffPtrID(Ptrs[i],TempID);
148 if (p2) SerializeTrait<T2>::Emit(*this,*p2);
149 if (p3) SerializeTrait<T3>::Emit(*this,*p3);
151 for (unsigned i = 0; i < NumT1Ptrs; ++i)
152 if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);
156 bool isRegistered(const void* p) const;
158 void FlushRecord() { if (inRecord()) EmitRecord(); }
159 void EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3);
164 inline bool inRecord() { return Record.size() > 0; }
165 SerializedPtrID getPtrId(const void* ptr);
168 } // end namespace llvm