Index: lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp |
diff --git a/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp b/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp |
index 2e318020adbafb874b77dc8de54ef18ca5f41114..d77a79a2c91a5fed1dc2a0d591262dd194dcb924 100644 |
--- a/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp |
+++ b/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp |
@@ -11,6 +11,8 @@ |
// |
//===----------------------------------------------------------------------===// |
+#define DEBUG_TYPE "NaClBitcodeWriter" |
+ |
#include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
#include "NaClValueEnumerator.h" |
#include "llvm/ADT/Triple.h" |
@@ -23,6 +25,7 @@ |
#include "llvm/IR/Module.h" |
#include "llvm/IR/Operator.h" |
#include "llvm/IR/ValueSymbolTable.h" |
+#include "llvm/Support/Debug.h" |
#include "llvm/Support/CommandLine.h" |
#include "llvm/Support/ErrorHandling.h" |
#include "llvm/Support/MathExtras.h" |
@@ -32,20 +35,39 @@ |
#include <map> |
using namespace llvm; |
-/// These are manifest constants used by the bitcode writer. They do not need to |
-/// be kept in sync with the reader, but need to be consistent within this file. |
+/// These are manifest constants used by the bitcode writer. They do |
+/// not need to be kept in sync with the reader, but need to be |
+/// consistent within this file. |
+/// |
+/// Note that for each block type GROUP, the last entry should be of |
+/// the form: |
+/// |
+/// GROUP_MAX_ABBREV = GROUP_LAST_ABBREV, |
+/// |
+/// where GROUP_LAST_ABBREV is the last defined abbreviation. See |
+/// include file "llvm/Bitcode/NaCl/NaClBitCodes.h" for more |
+/// information on how groups should be defined. |
enum { |
// VALUE_SYMTAB_BLOCK abbrev id's. |
VST_ENTRY_8_ABBREV = naclbitc::FIRST_APPLICATION_ABBREV, |
VST_ENTRY_7_ABBREV, |
VST_ENTRY_6_ABBREV, |
VST_BBENTRY_6_ABBREV, |
+ VST_MAX_ABBREV = VST_BBENTRY_6_ABBREV, |
// CONSTANTS_BLOCK abbrev id's. |
CONSTANTS_SETTYPE_ABBREV = naclbitc::FIRST_APPLICATION_ABBREV, |
CONSTANTS_INTEGER_ABBREV, |
CONSTANTS_CE_CAST_Abbrev, |
CONSTANTS_NULL_Abbrev, |
+ CONSTANTS_MAX_ABBREV = CONSTANTS_NULL_Abbrev, |
+ |
+ // CONSTANTS_BLOCK abbrev id's when global (extends list above). |
+ CST_CONSTANTS_AGGREGATE_ABBREV = CONSTANTS_MAX_ABBREV+1, |
+ CST_CONSTANTS_STRING_ABBREV, |
+ CST_CONSTANTS_CSTRING_7_ABBREV, |
+ CST_CONSTANTS_CSTRING_6_ABBREV, |
+ CST_CONSTANTS_MAX_ABBREV = CST_CONSTANTS_CSTRING_6_ABBREV, |
// FUNCTION_BLOCK abbrev id's. |
FUNCTION_INST_LOAD_ABBREV = naclbitc::FIRST_APPLICATION_ABBREV, |
@@ -55,6 +77,24 @@ enum { |
FUNCTION_INST_RET_VOID_ABBREV, |
FUNCTION_INST_RET_VAL_ABBREV, |
FUNCTION_INST_UNREACHABLE_ABBREV, |
+ FUNCTION_INST_MAX_ABBREV = FUNCTION_INST_UNREACHABLE_ABBREV, |
+ |
+ // TYPE_BLOCK_ID_NEW abbrev id's. |
+ TYPE_POINTER_ABBREV = naclbitc::FIRST_APPLICATION_ABBREV, |
+ TYPE_FUNCTION_ABBREV, |
+ TYPE_STRUCT_ANON_ABBREV, |
+ TYPE_STRUCT_NAME_ABBREV, |
+ TYPE_STRUCT_NAMED_ABBREV, |
+ TYPE_ARRAY_ABBREV, |
+ TYPE_MAX_ABBREV = TYPE_ARRAY_ABBREV, |
+ |
+ // META_DATA_BLOCK abbrev id's. |
+ METADATA_STRING_ABBREV = naclbitc::FIRST_APPLICATION_ABBREV, |
+ METADATA_MAX_ABBREV = METADATA_STRING_ABBREV, |
+ |
+ // MODULE_BLOCK abbrev id's. |
+ MODULE_GLOBALVAR_ABBREV = naclbitc::FIRST_APPLICATION_ABBREV, |
+ MODULE_MAX_ABBREV = MODULE_GLOBALVAR_ABBREV, |
// SwitchInst Magic |
SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex |
@@ -160,8 +200,9 @@ static void WriteAttributeGroupTable(const NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups(); |
if (AttrGrps.empty()) return; |
+ DEBUG(dbgs() << "-> WriteAbbributeGroupTable\n"); |
- Stream.EnterSubblock(naclbitc::PARAMATTR_GROUP_BLOCK_ID, 3); |
+ Stream.EnterSubblock(naclbitc::PARAMATTR_GROUP_BLOCK_ID); |
SmallVector<uint64_t, 64> Record; |
for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) { |
@@ -202,14 +243,16 @@ static void WriteAttributeGroupTable(const NaClValueEnumerator &VE, |
} |
Stream.ExitBlock(); |
+ DEBUG(dbgs() << "<- WriteAbbributeGroupTable\n"); |
} |
static void WriteAttributeTable(const NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
const std::vector<AttributeSet> &Attrs = VE.getAttributes(); |
if (Attrs.empty()) return; |
+ DEBUG(dbgs() << "-> WriteAttributeTable\n"); |
- Stream.EnterSubblock(naclbitc::PARAMATTR_BLOCK_ID, 3); |
+ Stream.EnterSubblock(naclbitc::PARAMATTR_BLOCK_ID); |
SmallVector<uint64_t, 64> Record; |
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { |
@@ -222,23 +265,26 @@ static void WriteAttributeTable(const NaClValueEnumerator &VE, |
} |
Stream.ExitBlock(); |
+ DEBUG(dbgs() << "<- WriteAttributeTable\n"); |
} |
/// WriteTypeTable - Write out the type table for a module. |
static void WriteTypeTable(const NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
+ DEBUG(dbgs() << "-> WriteTypeTable\n"); |
const NaClValueEnumerator::TypeList &TypeList = VE.getTypes(); |
- Stream.EnterSubblock(naclbitc::TYPE_BLOCK_ID_NEW, |
- 4 /*count from # abbrevs */); |
+ Stream.EnterSubblock(naclbitc::TYPE_BLOCK_ID_NEW, TYPE_MAX_ABBREV); |
+ |
SmallVector<uint64_t, 64> TypeVals; |
+ |
// Note: modify to use maximum number of bits if under cutoff. Otherwise, |
// use VBR to take advantage that frequently referenced types have |
// small IDs. |
// |
// Note: Cutoff chosen based on experiments on pnacl-translate.pexe. |
- uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1); |
+ uint64_t NumBits = NaClBitsNeededForValue(VE.getTypes().size()); |
static const uint64_t TypeVBRCutoff = 6; |
uint64_t TypeIdNumBits = (NumBits <= TypeVBRCutoff ? NumBits : TypeVBRCutoff); |
NaClBitCodeAbbrevOp::Encoding TypeIdEncoding = |
@@ -250,49 +296,51 @@ static void WriteTypeTable(const NaClValueEnumerator &VE, |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::TYPE_CODE_POINTER)); |
Abbv->Add(NaClBitCodeAbbrevOp(TypeIdEncoding, TypeIdNumBits)); |
Abbv->Add(NaClBitCodeAbbrevOp(0)); // Addrspace = 0 |
- unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv); |
+ if (TYPE_POINTER_ABBREV != Stream.EmitAbbrev(Abbv)) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
// Abbrev for TYPE_CODE_FUNCTION. |
Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::TYPE_CODE_FUNCTION)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 1)); // isvararg |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
- Abbv->Add(NaClBitCodeAbbrevOp(TypeIdEncoding, TypeIdNumBits)); |
- |
- unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv); |
+ Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, NumBits)); |
+ if (TYPE_FUNCTION_ABBREV != Stream.EmitAbbrev(Abbv)) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
// Abbrev for TYPE_CODE_STRUCT_ANON. |
Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::TYPE_CODE_STRUCT_ANON)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 1)); // ispacked |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
- Abbv->Add(NaClBitCodeAbbrevOp(TypeIdEncoding, TypeIdNumBits)); |
- |
- unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv); |
+ Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, NumBits)); |
+ if (TYPE_STRUCT_ANON_ABBREV != Stream.EmitAbbrev(Abbv)) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
// Abbrev for TYPE_CODE_STRUCT_NAME. |
Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::TYPE_CODE_STRUCT_NAME)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); |
- unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv); |
+ if (TYPE_STRUCT_NAME_ABBREV != Stream.EmitAbbrev(Abbv)) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
// Abbrev for TYPE_CODE_STRUCT_NAMED. |
Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::TYPE_CODE_STRUCT_NAMED)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 1)); // ispacked |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
- Abbv->Add(NaClBitCodeAbbrevOp(TypeIdEncoding, TypeIdNumBits)); |
- |
- unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv); |
+ Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, NumBits)); |
+ if (TYPE_STRUCT_NAMED_ABBREV != Stream.EmitAbbrev(Abbv)) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
// Abbrev for TYPE_CODE_ARRAY. |
Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::TYPE_CODE_ARRAY)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); // size |
- Abbv->Add(NaClBitCodeAbbrevOp(TypeIdEncoding, TypeIdNumBits)); |
- |
- unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv); |
+ Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, NumBits)); |
+ if (TYPE_ARRAY_ABBREV != Stream.EmitAbbrev(Abbv)) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
// Emit an entry count so the reader can reserve space. |
TypeVals.push_back(TypeList.size()); |
@@ -329,7 +377,7 @@ static void WriteTypeTable(const NaClValueEnumerator &VE, |
TypeVals.push_back(VE.getTypeID(PTy->getElementType())); |
unsigned AddressSpace = PTy->getAddressSpace(); |
TypeVals.push_back(AddressSpace); |
- if (AddressSpace == 0) AbbrevToUse = PtrAbbrev; |
+ if (AddressSpace == 0) AbbrevToUse = TYPE_POINTER_ABBREV; |
break; |
} |
case Type::FunctionTyID: { |
@@ -340,7 +388,7 @@ static void WriteTypeTable(const NaClValueEnumerator &VE, |
TypeVals.push_back(VE.getTypeID(FT->getReturnType())); |
for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) |
TypeVals.push_back(VE.getTypeID(FT->getParamType(i))); |
- AbbrevToUse = FunctionAbbrev; |
+ AbbrevToUse = TYPE_FUNCTION_ABBREV; |
break; |
} |
case Type::StructTyID: { |
@@ -354,19 +402,19 @@ static void WriteTypeTable(const NaClValueEnumerator &VE, |
if (ST->isLiteral()) { |
Code = naclbitc::TYPE_CODE_STRUCT_ANON; |
- AbbrevToUse = StructAnonAbbrev; |
+ AbbrevToUse = TYPE_STRUCT_ANON_ABBREV; |
} else { |
if (ST->isOpaque()) { |
Code = naclbitc::TYPE_CODE_OPAQUE; |
} else { |
Code = naclbitc::TYPE_CODE_STRUCT_NAMED; |
- AbbrevToUse = StructNamedAbbrev; |
+ AbbrevToUse = TYPE_STRUCT_NAMED_ABBREV; |
} |
// Emit the name if it is present. |
if (!ST->getName().empty()) |
WriteStringRecord(naclbitc::TYPE_CODE_STRUCT_NAME, ST->getName(), |
- StructNameAbbrev, Stream); |
+ TYPE_STRUCT_NAME_ABBREV, Stream); |
} |
break; |
} |
@@ -376,7 +424,7 @@ static void WriteTypeTable(const NaClValueEnumerator &VE, |
Code = naclbitc::TYPE_CODE_ARRAY; |
TypeVals.push_back(AT->getNumElements()); |
TypeVals.push_back(VE.getTypeID(AT->getElementType())); |
- AbbrevToUse = ArrayAbbrev; |
+ AbbrevToUse = TYPE_ARRAY_ABBREV; |
break; |
} |
case Type::VectorTyID: { |
@@ -395,6 +443,7 @@ static void WriteTypeTable(const NaClValueEnumerator &VE, |
} |
Stream.ExitBlock(); |
+ DEBUG(dbgs() << "<- WriteTypeTable\n"); |
} |
static unsigned getEncodedLinkage(const GlobalValue *GV) { |
@@ -443,6 +492,7 @@ static unsigned getEncodedThreadLocalMode(const GlobalVariable *GV) { |
// descriptors for global variables, and function prototype info. |
static void WriteModuleInfo(const Module *M, const NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
+ DEBUG(dbgs() << "-> WriteModuleInfo\n"); |
// Emit various pieces of data attached to a module. |
if (!M->getTargetTriple().empty()) |
WriteStringRecord(naclbitc::MODULE_CODE_TRIPLE, M->getTargetTriple(), |
@@ -497,13 +547,13 @@ static void WriteModuleInfo(const Module *M, const NaClValueEnumerator &VE, |
} |
// Emit abbrev for globals, now that we know # sections and max alignment. |
- unsigned SimpleGVarAbbrev = 0; |
- if (!M->global_empty()) { |
- // Add an abbrev for common globals with no visibility or thread localness. |
+ // Add an abbrev for common globals with no visibility or thread localness. |
+ // Don't bother emitting vis + thread local abbreviation. |
+ { |
NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::MODULE_CODE_GLOBALVAR)); |
- Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, |
- Log2_32_Ceil(MaxGlobalType+1))); |
+ Abbv->Add(NaClBitCodeAbbrevOp( |
+ NaClBitCodeAbbrevOp::Fixed, NaClBitsNeededForValue(MaxGlobalType))); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 1)); // Constant. |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); // Initializer. |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 4)); // Linkage. |
@@ -512,15 +562,15 @@ static void WriteModuleInfo(const Module *M, const NaClValueEnumerator &VE, |
else { |
unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1; |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, |
- Log2_32_Ceil(MaxEncAlignment+1))); |
+ NaClBitsNeededForValue(MaxEncAlignment))); |
} |
if (SectionMap.empty()) // Section. |
Abbv->Add(NaClBitCodeAbbrevOp(0)); |
else |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, |
- Log2_32_Ceil(SectionMap.size()+1))); |
- // Don't bother emitting vis + thread local. |
- SimpleGVarAbbrev = Stream.EmitAbbrev(Abbv); |
+ NaClBitsNeededForValue(SectionMap.size()))); |
+ if (MODULE_GLOBALVAR_ABBREV != Stream.EmitAbbrev(Abbv)) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
} |
// Emit the global variable information. |
@@ -547,7 +597,7 @@ static void WriteModuleInfo(const Module *M, const NaClValueEnumerator &VE, |
Vals.push_back(GV->hasUnnamedAddr()); |
Vals.push_back(GV->isExternallyInitialized()); |
} else { |
- AbbrevToUse = SimpleGVarAbbrev; |
+ AbbrevToUse = MODULE_GLOBALVAR_ABBREV; |
} |
Stream.EmitRecord(naclbitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse); |
@@ -586,6 +636,7 @@ static void WriteModuleInfo(const Module *M, const NaClValueEnumerator &VE, |
Stream.EmitRecord(naclbitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse); |
Vals.clear(); |
} |
+ DEBUG(dbgs() << "<- WriteModuleInfo\n"); |
} |
static uint64_t GetOptimizationFlags(const Value *V) { |
@@ -640,30 +691,23 @@ static void WriteMDNode(const MDNode *N, |
static void WriteModuleMetadata(const Module *M, |
const NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
+ DEBUG(dbgs() << "-> WriteModuleMetadata\n"); |
const NaClValueEnumerator::ValueList &Vals = VE.getMDValues(); |
bool StartedMetadataBlock = false; |
- unsigned MDSAbbrev = 0; |
SmallVector<uint64_t, 64> Record; |
for (unsigned i = 0, e = Vals.size(); i != e; ++i) { |
if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) { |
if (!N->isFunctionLocal() || !N->getFunction()) { |
if (!StartedMetadataBlock) { |
- Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID, 3); |
+ Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID); |
StartedMetadataBlock = true; |
} |
WriteMDNode(N, VE, Stream, Record); |
} |
} else if (const MDString *MDS = dyn_cast<MDString>(Vals[i].first)) { |
if (!StartedMetadataBlock) { |
- Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID, 3); |
- |
- // Abbrev for METADATA_STRING. |
- NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); |
- Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::METADATA_STRING)); |
- Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
- Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 8)); |
- MDSAbbrev = Stream.EmitAbbrev(Abbv); |
+ Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID); |
StartedMetadataBlock = true; |
} |
@@ -671,7 +715,8 @@ static void WriteModuleMetadata(const Module *M, |
Record.append(MDS->begin(), MDS->end()); |
// Emit the finished record. |
- Stream.EmitRecord(naclbitc::METADATA_STRING, Record, MDSAbbrev); |
+ Stream.EmitRecord(naclbitc::METADATA_STRING, Record, |
+ METADATA_STRING_ABBREV); |
Record.clear(); |
} |
} |
@@ -681,7 +726,7 @@ static void WriteModuleMetadata(const Module *M, |
E = M->named_metadata_end(); I != E; ++I) { |
const NamedMDNode *NMD = I; |
if (!StartedMetadataBlock) { |
- Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID, 3); |
+ Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID); |
StartedMetadataBlock = true; |
} |
@@ -701,11 +746,14 @@ static void WriteModuleMetadata(const Module *M, |
if (StartedMetadataBlock) |
Stream.ExitBlock(); |
+ |
+ DEBUG(dbgs() << "<- WriteModuleMetadata\n"); |
} |
static void WriteFunctionLocalMetadata(const Function &F, |
const NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
+ DEBUG(dbgs() << "-> WriteFunctionLocalMetadata\n"); |
bool StartedMetadataBlock = false; |
SmallVector<uint64_t, 64> Record; |
const SmallVector<const MDNode *, 8> &Vals = VE.getFunctionLocalMDValues(); |
@@ -713,7 +761,7 @@ static void WriteFunctionLocalMetadata(const Function &F, |
if (const MDNode *N = Vals[i]) |
if (N->isFunctionLocal() && N->getFunction() == &F) { |
if (!StartedMetadataBlock) { |
- Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID, 3); |
+ Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID); |
StartedMetadataBlock = true; |
} |
WriteMDNode(N, VE, Stream, Record); |
@@ -721,12 +769,13 @@ static void WriteFunctionLocalMetadata(const Function &F, |
if (StartedMetadataBlock) |
Stream.ExitBlock(); |
+ DEBUG(dbgs() << "<- WriteFunctionLocalMetadata\n"); |
} |
static void WriteMetadataAttachment(const Function &F, |
const NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
- Stream.EnterSubblock(naclbitc::METADATA_ATTACHMENT_ID, 3); |
+ Stream.EnterSubblock(naclbitc::METADATA_ATTACHMENT_ID); |
SmallVector<uint64_t, 64> Record; |
@@ -767,7 +816,7 @@ static void WriteModuleMetadataStore(const Module *M, |
if (Names.empty()) return; |
- Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID, 3); |
+ Stream.EnterSubblock(naclbitc::METADATA_BLOCK_ID); |
for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) { |
Record.push_back(MDKindID); |
@@ -782,10 +831,7 @@ static void WriteModuleMetadataStore(const Module *M, |
} |
static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) { |
- if ((int64_t)V >= 0) |
- Vals.push_back(V << 1); |
- else |
- Vals.push_back((-V << 1) | 1); |
+ Vals.push_back(NaClEncodeSignRotatedValue((int64_t)V)); |
} |
static void EmitAPInt(SmallVectorImpl<uint64_t> &Vals, |
@@ -821,21 +867,29 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, |
NaClBitstreamWriter &Stream, bool isGlobal) { |
if (FirstVal == LastVal) return; |
- Stream.EnterSubblock(naclbitc::CONSTANTS_BLOCK_ID, 4); |
+ Stream.EnterSubblock(naclbitc::CONSTANTS_BLOCK_ID, |
+ (isGlobal |
+ ? CST_CONSTANTS_MAX_ABBREV |
+ : CONSTANTS_MAX_ABBREV)); |
unsigned AggregateAbbrev = 0; |
unsigned String8Abbrev = 0; |
unsigned CString7Abbrev = 0; |
unsigned CString6Abbrev = 0; |
// If this is a constant pool for the module, emit module-specific abbrevs. |
+ // Note: These abbreviations are size specific (to LastVal), and hence, |
+ // can be more efficient if LastVal is known (rather then generating |
+ // up-front for all constant sections). |
if (isGlobal) { |
// Abbrev for CST_CODE_AGGREGATE. |
NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::CST_CODE_AGGREGATE)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, |
- Log2_32_Ceil(LastVal+1))); |
+ NaClBitsNeededForValue(LastVal))); |
AggregateAbbrev = Stream.EmitAbbrev(Abbv); |
+ if (CST_CONSTANTS_AGGREGATE_ABBREV != AggregateAbbrev) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
// Abbrev for CST_CODE_STRING. |
Abbv = new NaClBitCodeAbbrev(); |
@@ -843,20 +897,31 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 8)); |
String8Abbrev = Stream.EmitAbbrev(Abbv); |
+ if (CST_CONSTANTS_STRING_ABBREV != String8Abbrev) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
+ |
// Abbrev for CST_CODE_CSTRING. |
Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::CST_CODE_CSTRING)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 7)); |
CString7Abbrev = Stream.EmitAbbrev(Abbv); |
+ if (CST_CONSTANTS_CSTRING_7_ABBREV != CString7Abbrev) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
+ |
// Abbrev for CST_CODE_CSTRING. |
Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::CST_CODE_CSTRING)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); |
CString6Abbrev = Stream.EmitAbbrev(Abbv); |
+ if (CST_CONSTANTS_CSTRING_6_ABBREV != CString6Abbrev) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
+ |
+ DEBUG(dbgs() << "-- emitted abbreviations\n"); |
} |
+ |
SmallVector<uint64_t, 64> Record; |
const NaClValueEnumerator::ValueList &Vals = VE.getValues(); |
@@ -1062,6 +1127,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, |
} |
Stream.ExitBlock(); |
+ DEBUG(dbgs() << "<- WriteConstants\n"); |
} |
static void WriteModuleConstants(const NaClValueEnumerator &VE, |
@@ -1486,7 +1552,7 @@ static void WriteValueSymbolTable(const ValueSymbolTable &VST, |
const NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
if (VST.empty()) return; |
- Stream.EnterSubblock(naclbitc::VALUE_SYMTAB_BLOCK_ID, 4); |
+ Stream.EnterSubblock(naclbitc::VALUE_SYMTAB_BLOCK_ID); |
// FIXME: Set up the abbrev, we know how many values there are! |
// FIXME: We know if the type names can use 7-bit ascii. |
@@ -1542,7 +1608,7 @@ static void WriteValueSymbolTable(const ValueSymbolTable &VST, |
/// WriteFunction - Emit a function body to the module stream. |
static void WriteFunction(const Function &F, NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
- Stream.EnterSubblock(naclbitc::FUNCTION_BLOCK_ID, 4); |
+ Stream.EnterSubblock(naclbitc::FUNCTION_BLOCK_ID); |
VE.incorporateFunction(F); |
SmallVector<unsigned, 64> Vals; |
@@ -1615,9 +1681,10 @@ static void WriteFunction(const Function &F, NaClValueEnumerator &VE, |
static void WriteBlockInfo(const NaClValueEnumerator &VE, |
NaClBitstreamWriter &Stream) { |
// We only want to emit block info records for blocks that have multiple |
- // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK. |
+ // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK, |
+ // and METADATA_BLOCK_ID. |
// Other blocks can define their abbrevs inline. |
- Stream.EnterBlockInfoBlock(2); |
+ Stream.EnterBlockInfoBlock(); |
{ // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings. |
NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); |
@@ -1666,8 +1733,9 @@ static void WriteBlockInfo(const NaClValueEnumerator &VE, |
{ // SETTYPE abbrev for CONSTANTS_BLOCK. |
NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::CST_CODE_SETTYPE)); |
- Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, |
- Log2_32_Ceil(VE.getTypes().size()+1))); |
+ Abbv->Add(NaClBitCodeAbbrevOp( |
+ NaClBitCodeAbbrevOp::Fixed, |
+ NaClBitsNeededForValue(VE.getTypes().size()))); |
if (Stream.EmitBlockInfoAbbrev(naclbitc::CONSTANTS_BLOCK_ID, |
Abbv) != CONSTANTS_SETTYPE_ABBREV) |
llvm_unreachable("Unexpected abbrev ordering!"); |
@@ -1686,8 +1754,9 @@ static void WriteBlockInfo(const NaClValueEnumerator &VE, |
NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::CST_CODE_CE_CAST)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 4)); // cast opc |
- Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, // typeid |
- Log2_32_Ceil(VE.getTypes().size()+1))); |
+ Abbv->Add(NaClBitCodeAbbrevOp( |
+ NaClBitCodeAbbrevOp::Fixed, // typeid |
+ NaClBitsNeededForValue(VE.getTypes().size()))); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); // value id |
if (Stream.EmitBlockInfoAbbrev(naclbitc::CONSTANTS_BLOCK_ID, |
@@ -1739,8 +1808,9 @@ static void WriteBlockInfo(const NaClValueEnumerator &VE, |
NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); |
Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::FUNC_CODE_INST_CAST)); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); // OpVal |
- Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, // dest ty |
- Log2_32_Ceil(VE.getTypes().size()+1))); |
+ Abbv->Add(NaClBitCodeAbbrevOp( |
+ NaClBitCodeAbbrevOp::Fixed, // dest ty |
+ NaClBitsNeededForValue(VE.getTypes().size()))); |
Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 4)); // opc |
if (Stream.EmitBlockInfoAbbrev(naclbitc::FUNCTION_BLOCK_ID, |
Abbv) != FUNCTION_INST_CAST_ABBREV) |
@@ -1770,12 +1840,23 @@ static void WriteBlockInfo(const NaClValueEnumerator &VE, |
llvm_unreachable("Unexpected abbrev ordering!"); |
} |
+ { // Abbrev for METADATA_STRING. |
+ NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); |
+ Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::METADATA_STRING)); |
+ Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
+ Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 8)); |
+ if (Stream.EmitBlockInfoAbbrev(naclbitc::METADATA_BLOCK_ID, |
+ Abbv) != METADATA_STRING_ABBREV) |
+ llvm_unreachable("Unexpected abbrev ordering!"); |
+ } |
+ |
Stream.ExitBlock(); |
} |
/// WriteModule - Emit the specified module to the bitstream. |
static void WriteModule(const Module *M, NaClBitstreamWriter &Stream) { |
- Stream.EnterSubblock(naclbitc::MODULE_BLOCK_ID, 3); |
+ DEBUG(dbgs() << "-> WriteModule\n"); |
+ Stream.EnterSubblock(naclbitc::MODULE_BLOCK_ID, MODULE_MAX_ABBREV); |
SmallVector<unsigned, 1> Vals; |
unsigned CurVersion = 1; |
@@ -1819,6 +1900,7 @@ static void WriteModule(const Module *M, NaClBitstreamWriter &Stream) { |
WriteFunction(*F, VE, Stream); |
Stream.ExitBlock(); |
+ DEBUG(dbgs() << "<- WriteModule\n"); |
} |
/// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a |