Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===--- Bitcode/Writer/BitcodeWriter.cpp - Bitcode Writer ----------------===// | 1 //===--- Bitcode/PNaCl/Writer/PNaClBitcodeWriter.cpp - Bitcode Writer -----===// |
|
jvoung (off chromium)
2013/04/25 17:49:06
PNaCl -> NaCl (from the directory move)
Karl
2013/04/25 20:48:17
Done.
| |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // Bitcode writer implementation. | 10 // Bitcode writer implementation. |
| 11 // | 11 // |
| 12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
| 13 | 13 |
| 14 #include "llvm/Bitcode/ReaderWriter.h" | 14 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
| 15 #include "ValueEnumerator.h" | 15 #include "NaClValueEnumerator.h" |
| 16 #include "llvm/ADT/Triple.h" | 16 #include "llvm/ADT/Triple.h" |
| 17 #include "llvm/Bitcode/BitstreamWriter.h" | 17 #include "llvm/Bitcode/NaCl/NaClBitstreamWriter.h" |
| 18 #include "llvm/Bitcode/LLVMBitCodes.h" | 18 #include "llvm/Bitcode/LLVMBitCodes.h" |
| 19 #include "llvm/IR/Constants.h" | 19 #include "llvm/IR/Constants.h" |
| 20 #include "llvm/IR/DerivedTypes.h" | 20 #include "llvm/IR/DerivedTypes.h" |
| 21 #include "llvm/IR/InlineAsm.h" | 21 #include "llvm/IR/InlineAsm.h" |
| 22 #include "llvm/IR/Instructions.h" | 22 #include "llvm/IR/Instructions.h" |
| 23 #include "llvm/IR/Module.h" | 23 #include "llvm/IR/Module.h" |
| 24 #include "llvm/IR/Operator.h" | 24 #include "llvm/IR/Operator.h" |
| 25 #include "llvm/IR/ValueSymbolTable.h" | 25 #include "llvm/IR/ValueSymbolTable.h" |
| 26 #include "llvm/Support/CommandLine.h" | 26 #include "llvm/Support/CommandLine.h" |
| 27 #include "llvm/Support/ErrorHandling.h" | 27 #include "llvm/Support/ErrorHandling.h" |
| 28 #include "llvm/Support/MathExtras.h" | 28 #include "llvm/Support/MathExtras.h" |
| 29 #include "llvm/Support/Program.h" | 29 #include "llvm/Support/Program.h" |
| 30 #include "llvm/Support/raw_ostream.h" | 30 #include "llvm/Support/raw_ostream.h" |
| 31 #include <cctype> | 31 #include <cctype> |
| 32 #include <map> | 32 #include <map> |
| 33 using namespace llvm; | 33 using namespace llvm; |
| 34 | 34 |
| 35 static cl::opt<bool> | |
| 36 EnablePreserveUseListOrdering("enable-bc-uselist-preserve", | |
| 37 cl::desc("Turn on experimental support for " | |
| 38 "use-list order preservation."), | |
| 39 cl::init(false), cl::Hidden); | |
| 40 | |
| 41 /// These are manifest constants used by the bitcode writer. They do not need to | 35 /// These are manifest constants used by the bitcode writer. They do not need to |
| 42 /// be kept in sync with the reader, but need to be consistent within this file. | 36 /// be kept in sync with the reader, but need to be consistent within this file. |
| 43 enum { | 37 enum { |
| 44 // VALUE_SYMTAB_BLOCK abbrev id's. | 38 // VALUE_SYMTAB_BLOCK abbrev id's. |
| 45 VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV, | 39 VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV, |
| 46 VST_ENTRY_7_ABBREV, | 40 VST_ENTRY_7_ABBREV, |
| 47 VST_ENTRY_6_ABBREV, | 41 VST_ENTRY_6_ABBREV, |
| 48 VST_BBENTRY_6_ABBREV, | 42 VST_BBENTRY_6_ABBREV, |
| 49 | 43 |
| 50 // CONSTANTS_BLOCK abbrev id's. | 44 // CONSTANTS_BLOCK abbrev id's. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 | 134 |
| 141 static unsigned GetEncodedSynchScope(SynchronizationScope SynchScope) { | 135 static unsigned GetEncodedSynchScope(SynchronizationScope SynchScope) { |
| 142 switch (SynchScope) { | 136 switch (SynchScope) { |
| 143 case SingleThread: return bitc::SYNCHSCOPE_SINGLETHREAD; | 137 case SingleThread: return bitc::SYNCHSCOPE_SINGLETHREAD; |
| 144 case CrossThread: return bitc::SYNCHSCOPE_CROSSTHREAD; | 138 case CrossThread: return bitc::SYNCHSCOPE_CROSSTHREAD; |
| 145 } | 139 } |
| 146 llvm_unreachable("Invalid synch scope"); | 140 llvm_unreachable("Invalid synch scope"); |
| 147 } | 141 } |
| 148 | 142 |
| 149 static void WriteStringRecord(unsigned Code, StringRef Str, | 143 static void WriteStringRecord(unsigned Code, StringRef Str, |
| 150 unsigned AbbrevToUse, BitstreamWriter &Stream) { | 144 unsigned AbbrevToUse, PNaClBitstreamWriter &Stream ) { |
|
Karl
2013/04/25 20:48:17
File replaced all occurrences: PNaCl -> NaCl
| |
| 151 SmallVector<unsigned, 64> Vals; | 145 SmallVector<unsigned, 64> Vals; |
| 152 | 146 |
| 153 // Code: [strchar x N] | 147 // Code: [strchar x N] |
| 154 for (unsigned i = 0, e = Str.size(); i != e; ++i) { | 148 for (unsigned i = 0, e = Str.size(); i != e; ++i) { |
| 155 if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i])) | 149 if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i])) |
| 156 AbbrevToUse = 0; | 150 AbbrevToUse = 0; |
| 157 Vals.push_back(Str[i]); | 151 Vals.push_back(Str[i]); |
| 158 } | 152 } |
| 159 | 153 |
| 160 // Emit the finished record. | 154 // Emit the finished record. |
| 161 Stream.EmitRecord(Code, Vals, AbbrevToUse); | 155 Stream.EmitRecord(Code, Vals, AbbrevToUse); |
| 162 } | 156 } |
| 163 | 157 |
| 164 static void WriteAttributeGroupTable(const ValueEnumerator &VE, | 158 static void WriteAttributeGroupTable(const PNaClValueEnumerator &VE, |
| 165 BitstreamWriter &Stream) { | 159 PNaClBitstreamWriter &Stream) { |
| 166 const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups(); | 160 const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups(); |
| 167 if (AttrGrps.empty()) return; | 161 if (AttrGrps.empty()) return; |
| 168 | 162 |
| 169 Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3); | 163 Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3); |
| 170 | 164 |
| 171 SmallVector<uint64_t, 64> Record; | 165 SmallVector<uint64_t, 64> Record; |
| 172 for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) { | 166 for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) { |
| 173 AttributeSet AS = AttrGrps[i]; | 167 AttributeSet AS = AttrGrps[i]; |
| 174 for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) { | 168 for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) { |
| 175 AttributeSet A = AS.getSlotAttributes(i); | 169 AttributeSet A = AS.getSlotAttributes(i); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 202 } | 196 } |
| 203 | 197 |
| 204 Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record); | 198 Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record); |
| 205 Record.clear(); | 199 Record.clear(); |
| 206 } | 200 } |
| 207 } | 201 } |
| 208 | 202 |
| 209 Stream.ExitBlock(); | 203 Stream.ExitBlock(); |
| 210 } | 204 } |
| 211 | 205 |
| 212 static void WriteAttributeTable(const ValueEnumerator &VE, | 206 static void WriteAttributeTable(const PNaClValueEnumerator &VE, |
| 213 BitstreamWriter &Stream) { | 207 PNaClBitstreamWriter &Stream) { |
| 214 const std::vector<AttributeSet> &Attrs = VE.getAttributes(); | 208 const std::vector<AttributeSet> &Attrs = VE.getAttributes(); |
| 215 if (Attrs.empty()) return; | 209 if (Attrs.empty()) return; |
| 216 | 210 |
| 217 Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3); | 211 Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3); |
| 218 | 212 |
| 219 SmallVector<uint64_t, 64> Record; | 213 SmallVector<uint64_t, 64> Record; |
| 220 for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { | 214 for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { |
| 221 const AttributeSet &A = Attrs[i]; | 215 const AttributeSet &A = Attrs[i]; |
| 222 for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) | 216 for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) |
| 223 Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i))); | 217 Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i))); |
| 224 | 218 |
| 225 Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); | 219 Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); |
| 226 Record.clear(); | 220 Record.clear(); |
| 227 } | 221 } |
| 228 | 222 |
| 229 Stream.ExitBlock(); | 223 Stream.ExitBlock(); |
| 230 } | 224 } |
| 231 | 225 |
| 232 /// WriteTypeTable - Write out the type table for a module. | 226 /// WriteTypeTable - Write out the type table for a module. |
| 233 static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { | 227 static void WriteTypeTable(const PNaClValueEnumerator &VE, |
| 234 const ValueEnumerator::TypeList &TypeList = VE.getTypes(); | 228 » » » PNaClBitstreamWriter &Stream) { |
| 229 const PNaClValueEnumerator::TypeList &TypeList = VE.getTypes(); | |
| 235 | 230 |
| 236 Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */); | 231 Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */); |
| 237 SmallVector<uint64_t, 64> TypeVals; | 232 SmallVector<uint64_t, 64> TypeVals; |
| 238 | 233 |
| 239 uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1); | 234 uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1); |
| 240 | 235 |
| 241 // Abbrev for TYPE_CODE_POINTER. | 236 // Abbrev for TYPE_CODE_POINTER. |
| 242 BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 237 BitCodeAbbrev *Abbv = new BitCodeAbbrev(); |
| 243 Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER)); | 238 Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER)); |
| 244 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); | 239 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 case GlobalVariable::GeneralDynamicTLSModel: return 1; | 422 case GlobalVariable::GeneralDynamicTLSModel: return 1; |
| 428 case GlobalVariable::LocalDynamicTLSModel: return 2; | 423 case GlobalVariable::LocalDynamicTLSModel: return 2; |
| 429 case GlobalVariable::InitialExecTLSModel: return 3; | 424 case GlobalVariable::InitialExecTLSModel: return 3; |
| 430 case GlobalVariable::LocalExecTLSModel: return 4; | 425 case GlobalVariable::LocalExecTLSModel: return 4; |
| 431 } | 426 } |
| 432 llvm_unreachable("Invalid TLS model"); | 427 llvm_unreachable("Invalid TLS model"); |
| 433 } | 428 } |
| 434 | 429 |
| 435 // Emit top-level description of module, including target triple, inline asm, | 430 // Emit top-level description of module, including target triple, inline asm, |
| 436 // descriptors for global variables, and function prototype info. | 431 // descriptors for global variables, and function prototype info. |
| 437 static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, | 432 static void WriteModuleInfo(const Module *M, const PNaClValueEnumerator &VE, |
| 438 BitstreamWriter &Stream) { | 433 PNaClBitstreamWriter &Stream) { |
| 439 // Emit various pieces of data attached to a module. | 434 // Emit various pieces of data attached to a module. |
| 440 if (!M->getTargetTriple().empty()) | 435 if (!M->getTargetTriple().empty()) |
| 441 WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(), | 436 WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(), |
| 442 0/*TODO*/, Stream); | 437 0/*TODO*/, Stream); |
| 443 if (!M->getDataLayout().empty()) | 438 if (!M->getDataLayout().empty()) |
| 444 WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, M->getDataLayout(), | 439 WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, M->getDataLayout(), |
| 445 0/*TODO*/, Stream); | 440 0/*TODO*/, Stream); |
| 446 if (!M->getModuleInlineAsm().empty()) | 441 if (!M->getModuleInlineAsm().empty()) |
| 447 WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(), | 442 WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(), |
| 448 0/*TODO*/, Stream); | 443 0/*TODO*/, Stream); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 605 if (FPMO->hasNoSignedZeros()) | 600 if (FPMO->hasNoSignedZeros()) |
| 606 Flags |= FastMathFlags::NoSignedZeros; | 601 Flags |= FastMathFlags::NoSignedZeros; |
| 607 if (FPMO->hasAllowReciprocal()) | 602 if (FPMO->hasAllowReciprocal()) |
| 608 Flags |= FastMathFlags::AllowReciprocal; | 603 Flags |= FastMathFlags::AllowReciprocal; |
| 609 } | 604 } |
| 610 | 605 |
| 611 return Flags; | 606 return Flags; |
| 612 } | 607 } |
| 613 | 608 |
| 614 static void WriteMDNode(const MDNode *N, | 609 static void WriteMDNode(const MDNode *N, |
| 615 const ValueEnumerator &VE, | 610 const PNaClValueEnumerator &VE, |
| 616 BitstreamWriter &Stream, | 611 PNaClBitstreamWriter &Stream, |
| 617 SmallVector<uint64_t, 64> &Record) { | 612 SmallVector<uint64_t, 64> &Record) { |
| 618 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { | 613 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { |
| 619 if (N->getOperand(i)) { | 614 if (N->getOperand(i)) { |
| 620 Record.push_back(VE.getTypeID(N->getOperand(i)->getType())); | 615 Record.push_back(VE.getTypeID(N->getOperand(i)->getType())); |
| 621 Record.push_back(VE.getValueID(N->getOperand(i))); | 616 Record.push_back(VE.getValueID(N->getOperand(i))); |
| 622 } else { | 617 } else { |
| 623 Record.push_back(VE.getTypeID(Type::getVoidTy(N->getContext()))); | 618 Record.push_back(VE.getTypeID(Type::getVoidTy(N->getContext()))); |
| 624 Record.push_back(0); | 619 Record.push_back(0); |
| 625 } | 620 } |
| 626 } | 621 } |
| 627 unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE : | 622 unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE : |
| 628 bitc::METADATA_NODE; | 623 bitc::METADATA_NODE; |
| 629 Stream.EmitRecord(MDCode, Record, 0); | 624 Stream.EmitRecord(MDCode, Record, 0); |
| 630 Record.clear(); | 625 Record.clear(); |
| 631 } | 626 } |
| 632 | 627 |
| 633 static void WriteModuleMetadata(const Module *M, | 628 static void WriteModuleMetadata(const Module *M, |
| 634 const ValueEnumerator &VE, | 629 const PNaClValueEnumerator &VE, |
| 635 BitstreamWriter &Stream) { | 630 PNaClBitstreamWriter &Stream) { |
| 636 const ValueEnumerator::ValueList &Vals = VE.getMDValues(); | 631 const PNaClValueEnumerator::ValueList &Vals = VE.getMDValues(); |
| 637 bool StartedMetadataBlock = false; | 632 bool StartedMetadataBlock = false; |
| 638 unsigned MDSAbbrev = 0; | 633 unsigned MDSAbbrev = 0; |
| 639 SmallVector<uint64_t, 64> Record; | 634 SmallVector<uint64_t, 64> Record; |
| 640 for (unsigned i = 0, e = Vals.size(); i != e; ++i) { | 635 for (unsigned i = 0, e = Vals.size(); i != e; ++i) { |
| 641 | 636 |
| 642 if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) { | 637 if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) { |
| 643 if (!N->isFunctionLocal() || !N->getFunction()) { | 638 if (!N->isFunctionLocal() || !N->getFunction()) { |
| 644 if (!StartedMetadataBlock) { | 639 if (!StartedMetadataBlock) { |
| 645 Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); | 640 Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); |
| 646 StartedMetadataBlock = true; | 641 StartedMetadataBlock = true; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 690 Record.push_back(VE.getValueID(NMD->getOperand(i))); | 685 Record.push_back(VE.getValueID(NMD->getOperand(i))); |
| 691 Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0); | 686 Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0); |
| 692 Record.clear(); | 687 Record.clear(); |
| 693 } | 688 } |
| 694 | 689 |
| 695 if (StartedMetadataBlock) | 690 if (StartedMetadataBlock) |
| 696 Stream.ExitBlock(); | 691 Stream.ExitBlock(); |
| 697 } | 692 } |
| 698 | 693 |
| 699 static void WriteFunctionLocalMetadata(const Function &F, | 694 static void WriteFunctionLocalMetadata(const Function &F, |
| 700 const ValueEnumerator &VE, | 695 const PNaClValueEnumerator &VE, |
| 701 BitstreamWriter &Stream) { | 696 PNaClBitstreamWriter &Stream) { |
| 702 bool StartedMetadataBlock = false; | 697 bool StartedMetadataBlock = false; |
| 703 SmallVector<uint64_t, 64> Record; | 698 SmallVector<uint64_t, 64> Record; |
| 704 const SmallVector<const MDNode *, 8> &Vals = VE.getFunctionLocalMDValues(); | 699 const SmallVector<const MDNode *, 8> &Vals = VE.getFunctionLocalMDValues(); |
| 705 for (unsigned i = 0, e = Vals.size(); i != e; ++i) | 700 for (unsigned i = 0, e = Vals.size(); i != e; ++i) |
| 706 if (const MDNode *N = Vals[i]) | 701 if (const MDNode *N = Vals[i]) |
| 707 if (N->isFunctionLocal() && N->getFunction() == &F) { | 702 if (N->isFunctionLocal() && N->getFunction() == &F) { |
| 708 if (!StartedMetadataBlock) { | 703 if (!StartedMetadataBlock) { |
| 709 Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); | 704 Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); |
| 710 StartedMetadataBlock = true; | 705 StartedMetadataBlock = true; |
| 711 } | 706 } |
| 712 WriteMDNode(N, VE, Stream, Record); | 707 WriteMDNode(N, VE, Stream, Record); |
| 713 } | 708 } |
| 714 | 709 |
| 715 if (StartedMetadataBlock) | 710 if (StartedMetadataBlock) |
| 716 Stream.ExitBlock(); | 711 Stream.ExitBlock(); |
| 717 } | 712 } |
| 718 | 713 |
| 719 static void WriteMetadataAttachment(const Function &F, | 714 static void WriteMetadataAttachment(const Function &F, |
| 720 const ValueEnumerator &VE, | 715 const PNaClValueEnumerator &VE, |
| 721 BitstreamWriter &Stream) { | 716 PNaClBitstreamWriter &Stream) { |
| 722 Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3); | 717 Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3); |
| 723 | 718 |
| 724 SmallVector<uint64_t, 64> Record; | 719 SmallVector<uint64_t, 64> Record; |
| 725 | 720 |
| 726 // Write metadata attachments | 721 // Write metadata attachments |
| 727 // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] | 722 // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] |
| 728 SmallVector<std::pair<unsigned, MDNode*>, 4> MDs; | 723 SmallVector<std::pair<unsigned, MDNode*>, 4> MDs; |
| 729 | 724 |
| 730 for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) | 725 for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) |
| 731 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); | 726 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 742 Record.push_back(MDs[i].first); | 737 Record.push_back(MDs[i].first); |
| 743 Record.push_back(VE.getValueID(MDs[i].second)); | 738 Record.push_back(VE.getValueID(MDs[i].second)); |
| 744 } | 739 } |
| 745 Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); | 740 Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); |
| 746 Record.clear(); | 741 Record.clear(); |
| 747 } | 742 } |
| 748 | 743 |
| 749 Stream.ExitBlock(); | 744 Stream.ExitBlock(); |
| 750 } | 745 } |
| 751 | 746 |
| 752 static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) { | 747 static void WriteModuleMetadataStore(const Module *M, PNaClBitstreamWriter &Stre am) { |
| 753 SmallVector<uint64_t, 64> Record; | 748 SmallVector<uint64_t, 64> Record; |
| 754 | 749 |
| 755 // Write metadata kinds | 750 // Write metadata kinds |
| 756 // METADATA_KIND - [n x [id, name]] | 751 // METADATA_KIND - [n x [id, name]] |
| 757 SmallVector<StringRef, 8> Names; | 752 SmallVector<StringRef, 8> Names; |
| 758 M->getMDKindNames(Names); | 753 M->getMDKindNames(Names); |
| 759 | 754 |
| 760 if (Names.empty()) return; | 755 if (Names.empty()) return; |
| 761 | 756 |
| 762 Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); | 757 Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 802 | 797 |
| 803 const uint64_t *RawWords = Val.getRawData(); | 798 const uint64_t *RawWords = Val.getRawData(); |
| 804 for (unsigned i = 0; i != NWords; ++i) { | 799 for (unsigned i = 0; i != NWords; ++i) { |
| 805 emitSignedInt64(Vals, RawWords[i]); | 800 emitSignedInt64(Vals, RawWords[i]); |
| 806 } | 801 } |
| 807 Code = bitc::CST_CODE_WIDE_INTEGER; | 802 Code = bitc::CST_CODE_WIDE_INTEGER; |
| 808 } | 803 } |
| 809 } | 804 } |
| 810 | 805 |
| 811 static void WriteConstants(unsigned FirstVal, unsigned LastVal, | 806 static void WriteConstants(unsigned FirstVal, unsigned LastVal, |
| 812 const ValueEnumerator &VE, | 807 const PNaClValueEnumerator &VE, |
| 813 BitstreamWriter &Stream, bool isGlobal) { | 808 PNaClBitstreamWriter &Stream, bool isGlobal) { |
| 814 if (FirstVal == LastVal) return; | 809 if (FirstVal == LastVal) return; |
| 815 | 810 |
| 816 Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4); | 811 Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4); |
| 817 | 812 |
| 818 unsigned AggregateAbbrev = 0; | 813 unsigned AggregateAbbrev = 0; |
| 819 unsigned String8Abbrev = 0; | 814 unsigned String8Abbrev = 0; |
| 820 unsigned CString7Abbrev = 0; | 815 unsigned CString7Abbrev = 0; |
| 821 unsigned CString6Abbrev = 0; | 816 unsigned CString6Abbrev = 0; |
| 822 // If this is a constant pool for the module, emit module-specific abbrevs. | 817 // If this is a constant pool for the module, emit module-specific abbrevs. |
| 823 if (isGlobal) { | 818 if (isGlobal) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 843 // Abbrev for CST_CODE_CSTRING. | 838 // Abbrev for CST_CODE_CSTRING. |
| 844 Abbv = new BitCodeAbbrev(); | 839 Abbv = new BitCodeAbbrev(); |
| 845 Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING)); | 840 Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING)); |
| 846 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 841 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); |
| 847 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); | 842 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); |
| 848 CString6Abbrev = Stream.EmitAbbrev(Abbv); | 843 CString6Abbrev = Stream.EmitAbbrev(Abbv); |
| 849 } | 844 } |
| 850 | 845 |
| 851 SmallVector<uint64_t, 64> Record; | 846 SmallVector<uint64_t, 64> Record; |
| 852 | 847 |
| 853 const ValueEnumerator::ValueList &Vals = VE.getValues(); | 848 const PNaClValueEnumerator::ValueList &Vals = VE.getValues(); |
| 854 Type *LastTy = 0; | 849 Type *LastTy = 0; |
| 855 for (unsigned i = FirstVal; i != LastVal; ++i) { | 850 for (unsigned i = FirstVal; i != LastVal; ++i) { |
| 856 const Value *V = Vals[i].first; | 851 const Value *V = Vals[i].first; |
| 857 // If we need to switch types, do so now. | 852 // If we need to switch types, do so now. |
| 858 if (V->getType() != LastTy) { | 853 if (V->getType() != LastTy) { |
| 859 LastTy = V->getType(); | 854 LastTy = V->getType(); |
| 860 Record.push_back(VE.getTypeID(LastTy)); | 855 Record.push_back(VE.getTypeID(LastTy)); |
| 861 Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record, | 856 Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record, |
| 862 CONSTANTS_SETTYPE_ABBREV); | 857 CONSTANTS_SETTYPE_ABBREV); |
| 863 Record.clear(); | 858 Record.clear(); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1048 #endif | 1043 #endif |
| 1049 llvm_unreachable("Unknown constant!"); | 1044 llvm_unreachable("Unknown constant!"); |
| 1050 } | 1045 } |
| 1051 Stream.EmitRecord(Code, Record, AbbrevToUse); | 1046 Stream.EmitRecord(Code, Record, AbbrevToUse); |
| 1052 Record.clear(); | 1047 Record.clear(); |
| 1053 } | 1048 } |
| 1054 | 1049 |
| 1055 Stream.ExitBlock(); | 1050 Stream.ExitBlock(); |
| 1056 } | 1051 } |
| 1057 | 1052 |
| 1058 static void WriteModuleConstants(const ValueEnumerator &VE, | 1053 static void WriteModuleConstants(const PNaClValueEnumerator &VE, |
| 1059 BitstreamWriter &Stream) { | 1054 PNaClBitstreamWriter &Stream) { |
| 1060 const ValueEnumerator::ValueList &Vals = VE.getValues(); | 1055 const PNaClValueEnumerator::ValueList &Vals = VE.getValues(); |
| 1061 | 1056 |
| 1062 // Find the first constant to emit, which is the first non-globalvalue value. | 1057 // Find the first constant to emit, which is the first non-globalvalue value. |
| 1063 // We know globalvalues have been emitted by WriteModuleInfo. | 1058 // We know globalvalues have been emitted by WriteModuleInfo. |
| 1064 for (unsigned i = 0, e = Vals.size(); i != e; ++i) { | 1059 for (unsigned i = 0, e = Vals.size(); i != e; ++i) { |
| 1065 if (!isa<GlobalValue>(Vals[i].first)) { | 1060 if (!isa<GlobalValue>(Vals[i].first)) { |
| 1066 WriteConstants(i, Vals.size(), VE, Stream, true); | 1061 WriteConstants(i, Vals.size(), VE, Stream, true); |
| 1067 return; | 1062 return; |
| 1068 } | 1063 } |
| 1069 } | 1064 } |
| 1070 } | 1065 } |
| 1071 | 1066 |
| 1072 /// PushValueAndType - The file has to encode both the value and type id for | 1067 /// PushValueAndType - The file has to encode both the value and type id for |
| 1073 /// many values, because we need to know what type to create for forward | 1068 /// many values, because we need to know what type to create for forward |
| 1074 /// references. However, most operands are not forward references, so this type | 1069 /// references. However, most operands are not forward references, so this type |
| 1075 /// field is not needed. | 1070 /// field is not needed. |
| 1076 /// | 1071 /// |
| 1077 /// This function adds V's value ID to Vals. If the value ID is higher than the | 1072 /// This function adds V's value ID to Vals. If the value ID is higher than the |
| 1078 /// instruction ID, then it is a forward reference, and it also includes the | 1073 /// instruction ID, then it is a forward reference, and it also includes the |
| 1079 /// type ID. The value ID that is written is encoded relative to the InstID. | 1074 /// type ID. The value ID that is written is encoded relative to the InstID. |
| 1080 static bool PushValueAndType(const Value *V, unsigned InstID, | 1075 static bool PushValueAndType(const Value *V, unsigned InstID, |
| 1081 SmallVector<unsigned, 64> &Vals, | 1076 SmallVector<unsigned, 64> &Vals, |
| 1082 ValueEnumerator &VE) { | 1077 PNaClValueEnumerator &VE) { |
| 1083 unsigned ValID = VE.getValueID(V); | 1078 unsigned ValID = VE.getValueID(V); |
| 1084 // Make encoding relative to the InstID. | 1079 // Make encoding relative to the InstID. |
| 1085 Vals.push_back(InstID - ValID); | 1080 Vals.push_back(InstID - ValID); |
| 1086 if (ValID >= InstID) { | 1081 if (ValID >= InstID) { |
| 1087 Vals.push_back(VE.getTypeID(V->getType())); | 1082 Vals.push_back(VE.getTypeID(V->getType())); |
| 1088 return true; | 1083 return true; |
| 1089 } | 1084 } |
| 1090 return false; | 1085 return false; |
| 1091 } | 1086 } |
| 1092 | 1087 |
| 1093 /// pushValue - Like PushValueAndType, but where the type of the value is | 1088 /// pushValue - Like PushValueAndType, but where the type of the value is |
| 1094 /// omitted (perhaps it was already encoded in an earlier operand). | 1089 /// omitted (perhaps it was already encoded in an earlier operand). |
| 1095 static void pushValue(const Value *V, unsigned InstID, | 1090 static void pushValue(const Value *V, unsigned InstID, |
| 1096 SmallVector<unsigned, 64> &Vals, | 1091 SmallVector<unsigned, 64> &Vals, |
| 1097 ValueEnumerator &VE) { | 1092 PNaClValueEnumerator &VE) { |
| 1098 unsigned ValID = VE.getValueID(V); | 1093 unsigned ValID = VE.getValueID(V); |
| 1099 Vals.push_back(InstID - ValID); | 1094 Vals.push_back(InstID - ValID); |
| 1100 } | 1095 } |
| 1101 | 1096 |
| 1102 static void pushValue64(const Value *V, unsigned InstID, | 1097 static void pushValue64(const Value *V, unsigned InstID, |
| 1103 SmallVector<uint64_t, 128> &Vals, | 1098 SmallVector<uint64_t, 128> &Vals, |
| 1104 ValueEnumerator &VE) { | 1099 PNaClValueEnumerator &VE) { |
| 1105 uint64_t ValID = VE.getValueID(V); | 1100 uint64_t ValID = VE.getValueID(V); |
| 1106 Vals.push_back(InstID - ValID); | 1101 Vals.push_back(InstID - ValID); |
| 1107 } | 1102 } |
| 1108 | 1103 |
| 1109 static void pushValueSigned(const Value *V, unsigned InstID, | 1104 static void pushValueSigned(const Value *V, unsigned InstID, |
| 1110 SmallVector<uint64_t, 128> &Vals, | 1105 SmallVector<uint64_t, 128> &Vals, |
| 1111 ValueEnumerator &VE) { | 1106 PNaClValueEnumerator &VE) { |
| 1112 unsigned ValID = VE.getValueID(V); | 1107 unsigned ValID = VE.getValueID(V); |
| 1113 int64_t diff = ((int32_t)InstID - (int32_t)ValID); | 1108 int64_t diff = ((int32_t)InstID - (int32_t)ValID); |
| 1114 emitSignedInt64(Vals, diff); | 1109 emitSignedInt64(Vals, diff); |
| 1115 } | 1110 } |
| 1116 | 1111 |
| 1117 /// WriteInstruction - Emit an instruction to the specified stream. | 1112 /// WriteInstruction - Emit an instruction to the specified stream. |
| 1118 static void WriteInstruction(const Instruction &I, unsigned InstID, | 1113 static void WriteInstruction(const Instruction &I, unsigned InstID, |
| 1119 ValueEnumerator &VE, BitstreamWriter &Stream, | 1114 PNaClValueEnumerator &VE, PNaClBitstreamWriter &Str eam, |
| 1120 SmallVector<unsigned, 64> &Vals) { | 1115 SmallVector<unsigned, 64> &Vals) { |
| 1121 unsigned Code = 0; | 1116 unsigned Code = 0; |
| 1122 unsigned AbbrevToUse = 0; | 1117 unsigned AbbrevToUse = 0; |
| 1123 VE.setInstructionID(&I); | 1118 VE.setInstructionID(&I); |
| 1124 switch (I.getOpcode()) { | 1119 switch (I.getOpcode()) { |
| 1125 default: | 1120 default: |
| 1126 if (Instruction::isCast(I.getOpcode())) { | 1121 if (Instruction::isCast(I.getOpcode())) { |
| 1127 Code = bitc::FUNC_CODE_INST_CAST; | 1122 Code = bitc::FUNC_CODE_INST_CAST; |
| 1128 if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) | 1123 if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) |
| 1129 AbbrevToUse = FUNCTION_INST_CAST_ABBREV; | 1124 AbbrevToUse = FUNCTION_INST_CAST_ABBREV; |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1466 Vals.push_back(VE.getTypeID(I.getType())); // restype. | 1461 Vals.push_back(VE.getTypeID(I.getType())); // restype. |
| 1467 break; | 1462 break; |
| 1468 } | 1463 } |
| 1469 | 1464 |
| 1470 Stream.EmitRecord(Code, Vals, AbbrevToUse); | 1465 Stream.EmitRecord(Code, Vals, AbbrevToUse); |
| 1471 Vals.clear(); | 1466 Vals.clear(); |
| 1472 } | 1467 } |
| 1473 | 1468 |
| 1474 // Emit names for globals/functions etc. | 1469 // Emit names for globals/functions etc. |
| 1475 static void WriteValueSymbolTable(const ValueSymbolTable &VST, | 1470 static void WriteValueSymbolTable(const ValueSymbolTable &VST, |
| 1476 const ValueEnumerator &VE, | 1471 const PNaClValueEnumerator &VE, |
| 1477 BitstreamWriter &Stream) { | 1472 PNaClBitstreamWriter &Stream) { |
| 1478 if (VST.empty()) return; | 1473 if (VST.empty()) return; |
| 1479 Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4); | 1474 Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4); |
| 1480 | 1475 |
| 1481 // FIXME: Set up the abbrev, we know how many values there are! | 1476 // FIXME: Set up the abbrev, we know how many values there are! |
| 1482 // FIXME: We know if the type names can use 7-bit ascii. | 1477 // FIXME: We know if the type names can use 7-bit ascii. |
| 1483 SmallVector<unsigned, 64> NameVals; | 1478 SmallVector<unsigned, 64> NameVals; |
| 1484 | 1479 |
| 1485 for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end(); | 1480 for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end(); |
| 1486 SI != SE; ++SI) { | 1481 SI != SE; ++SI) { |
| 1487 | 1482 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1523 NameVals.push_back((unsigned char)*P); | 1518 NameVals.push_back((unsigned char)*P); |
| 1524 | 1519 |
| 1525 // Emit the finished record. | 1520 // Emit the finished record. |
| 1526 Stream.EmitRecord(Code, NameVals, AbbrevToUse); | 1521 Stream.EmitRecord(Code, NameVals, AbbrevToUse); |
| 1527 NameVals.clear(); | 1522 NameVals.clear(); |
| 1528 } | 1523 } |
| 1529 Stream.ExitBlock(); | 1524 Stream.ExitBlock(); |
| 1530 } | 1525 } |
| 1531 | 1526 |
| 1532 /// WriteFunction - Emit a function body to the module stream. | 1527 /// WriteFunction - Emit a function body to the module stream. |
| 1533 static void WriteFunction(const Function &F, ValueEnumerator &VE, | 1528 static void WriteFunction(const Function &F, PNaClValueEnumerator &VE, |
| 1534 BitstreamWriter &Stream) { | 1529 PNaClBitstreamWriter &Stream) { |
| 1535 Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4); | 1530 Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4); |
| 1536 VE.incorporateFunction(F); | 1531 VE.incorporateFunction(F); |
| 1537 | 1532 |
| 1538 SmallVector<unsigned, 64> Vals; | 1533 SmallVector<unsigned, 64> Vals; |
| 1539 | 1534 |
| 1540 // Emit the number of basic blocks, so the reader can create them ahead of | 1535 // Emit the number of basic blocks, so the reader can create them ahead of |
| 1541 // time. | 1536 // time. |
| 1542 Vals.push_back(VE.getBasicBlocks().size()); | 1537 Vals.push_back(VE.getBasicBlocks().size()); |
| 1543 Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals); | 1538 Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals); |
| 1544 Vals.clear(); | 1539 Vals.clear(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1595 // Emit names for all the instructions etc. | 1590 // Emit names for all the instructions etc. |
| 1596 WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream); | 1591 WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream); |
| 1597 | 1592 |
| 1598 if (NeedsMetadataAttachment) | 1593 if (NeedsMetadataAttachment) |
| 1599 WriteMetadataAttachment(F, VE, Stream); | 1594 WriteMetadataAttachment(F, VE, Stream); |
| 1600 VE.purgeFunction(); | 1595 VE.purgeFunction(); |
| 1601 Stream.ExitBlock(); | 1596 Stream.ExitBlock(); |
| 1602 } | 1597 } |
| 1603 | 1598 |
| 1604 // Emit blockinfo, which defines the standard abbreviations etc. | 1599 // Emit blockinfo, which defines the standard abbreviations etc. |
| 1605 static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { | 1600 static void WriteBlockInfo(const PNaClValueEnumerator &VE, PNaClBitstreamWriter &Stream) { |
| 1606 // We only want to emit block info records for blocks that have multiple | 1601 // We only want to emit block info records for blocks that have multiple |
| 1607 // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK. | 1602 // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK. |
| 1608 // Other blocks can define their abbrevs inline. | 1603 // Other blocks can define their abbrevs inline. |
| 1609 Stream.EnterBlockInfoBlock(2); | 1604 Stream.EnterBlockInfoBlock(2); |
| 1610 | 1605 |
| 1611 { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings. | 1606 { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings. |
| 1612 BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 1607 BitCodeAbbrev *Abbv = new BitCodeAbbrev(); |
| 1613 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); | 1608 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); |
| 1614 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); | 1609 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); |
| 1615 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 1610 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1755 BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 1750 BitCodeAbbrev *Abbv = new BitCodeAbbrev(); |
| 1756 Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE)); | 1751 Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE)); |
| 1757 if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, | 1752 if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, |
| 1758 Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV) | 1753 Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV) |
| 1759 llvm_unreachable("Unexpected abbrev ordering!"); | 1754 llvm_unreachable("Unexpected abbrev ordering!"); |
| 1760 } | 1755 } |
| 1761 | 1756 |
| 1762 Stream.ExitBlock(); | 1757 Stream.ExitBlock(); |
| 1763 } | 1758 } |
| 1764 | 1759 |
| 1765 // Sort the Users based on the order in which the reader parses the bitcode | |
| 1766 // file. | |
| 1767 static bool bitcodereader_order(const User *lhs, const User *rhs) { | |
| 1768 // TODO: Implement. | |
| 1769 return true; | |
| 1770 } | |
| 1771 | |
| 1772 static void WriteUseList(const Value *V, const ValueEnumerator &VE, | |
| 1773 BitstreamWriter &Stream) { | |
| 1774 | |
| 1775 // One or zero uses can't get out of order. | |
| 1776 if (V->use_empty() || V->hasNUses(1)) | |
| 1777 return; | |
| 1778 | |
| 1779 // Make a copy of the in-memory use-list for sorting. | |
| 1780 unsigned UseListSize = std::distance(V->use_begin(), V->use_end()); | |
| 1781 SmallVector<const User*, 8> UseList; | |
| 1782 UseList.reserve(UseListSize); | |
| 1783 for (Value::const_use_iterator I = V->use_begin(), E = V->use_end(); | |
| 1784 I != E; ++I) { | |
| 1785 const User *U = *I; | |
| 1786 UseList.push_back(U); | |
| 1787 } | |
| 1788 | |
| 1789 // Sort the copy based on the order read by the BitcodeReader. | |
| 1790 std::sort(UseList.begin(), UseList.end(), bitcodereader_order); | |
| 1791 | |
| 1792 // TODO: Generate a diff between the BitcodeWriter in-memory use-list and the | |
| 1793 // sorted list (i.e., the expected BitcodeReader in-memory use-list). | |
| 1794 | |
| 1795 // TODO: Emit the USELIST_CODE_ENTRYs. | |
| 1796 } | |
| 1797 | |
| 1798 static void WriteFunctionUseList(const Function *F, ValueEnumerator &VE, | |
| 1799 BitstreamWriter &Stream) { | |
| 1800 VE.incorporateFunction(*F); | |
| 1801 | |
| 1802 for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); | |
| 1803 AI != AE; ++AI) | |
| 1804 WriteUseList(AI, VE, Stream); | |
| 1805 for (Function::const_iterator BB = F->begin(), FE = F->end(); BB != FE; | |
| 1806 ++BB) { | |
| 1807 WriteUseList(BB, VE, Stream); | |
| 1808 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE; | |
| 1809 ++II) { | |
| 1810 WriteUseList(II, VE, Stream); | |
| 1811 for (User::const_op_iterator OI = II->op_begin(), E = II->op_end(); | |
| 1812 OI != E; ++OI) { | |
| 1813 if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) || | |
| 1814 isa<InlineAsm>(*OI)) | |
| 1815 WriteUseList(*OI, VE, Stream); | |
| 1816 } | |
| 1817 } | |
| 1818 } | |
| 1819 VE.purgeFunction(); | |
| 1820 } | |
| 1821 | |
| 1822 // Emit use-lists. | |
| 1823 static void WriteModuleUseLists(const Module *M, ValueEnumerator &VE, | |
| 1824 BitstreamWriter &Stream) { | |
| 1825 Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3); | |
| 1826 | |
| 1827 // XXX: this modifies the module, but in a way that should never change the | |
| 1828 // behavior of any pass or codegen in LLVM. The problem is that GVs may | |
| 1829 // contain entries in the use_list that do not exist in the Module and are | |
| 1830 // not stored in the .bc file. | |
| 1831 for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); | |
| 1832 I != E; ++I) | |
| 1833 I->removeDeadConstantUsers(); | |
| 1834 | |
| 1835 // Write the global variables. | |
| 1836 for (Module::const_global_iterator GI = M->global_begin(), | |
| 1837 GE = M->global_end(); GI != GE; ++GI) { | |
| 1838 WriteUseList(GI, VE, Stream); | |
| 1839 | |
| 1840 // Write the global variable initializers. | |
| 1841 if (GI->hasInitializer()) | |
| 1842 WriteUseList(GI->getInitializer(), VE, Stream); | |
| 1843 } | |
| 1844 | |
| 1845 // Write the functions. | |
| 1846 for (Module::const_iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) { | |
| 1847 WriteUseList(FI, VE, Stream); | |
| 1848 if (!FI->isDeclaration()) | |
| 1849 WriteFunctionUseList(FI, VE, Stream); | |
| 1850 } | |
| 1851 | |
| 1852 // Write the aliases. | |
| 1853 for (Module::const_alias_iterator AI = M->alias_begin(), AE = M->alias_end(); | |
| 1854 AI != AE; ++AI) { | |
| 1855 WriteUseList(AI, VE, Stream); | |
| 1856 WriteUseList(AI->getAliasee(), VE, Stream); | |
| 1857 } | |
| 1858 | |
| 1859 Stream.ExitBlock(); | |
| 1860 } | |
| 1861 | |
| 1862 /// WriteModule - Emit the specified module to the bitstream. | 1760 /// WriteModule - Emit the specified module to the bitstream. |
| 1863 static void WriteModule(const Module *M, BitstreamWriter &Stream) { | 1761 static void WriteModule(const Module *M, PNaClBitstreamWriter &Stream) { |
| 1864 Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3); | 1762 Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3); |
| 1865 | 1763 |
| 1866 SmallVector<unsigned, 1> Vals; | 1764 SmallVector<unsigned, 1> Vals; |
| 1867 unsigned CurVersion = 1; | 1765 unsigned CurVersion = 1; |
| 1868 Vals.push_back(CurVersion); | 1766 Vals.push_back(CurVersion); |
| 1869 Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals); | 1767 Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals); |
| 1870 | 1768 |
| 1871 // Analyze the module, enumerating globals, functions, etc. | 1769 // Analyze the module, enumerating globals, functions, etc. |
| 1872 ValueEnumerator VE(M); | 1770 PNaClValueEnumerator VE(M); |
| 1873 | 1771 |
| 1874 // Emit blockinfo, which defines the standard abbreviations etc. | 1772 // Emit blockinfo, which defines the standard abbreviations etc. |
| 1875 WriteBlockInfo(VE, Stream); | 1773 WriteBlockInfo(VE, Stream); |
| 1876 | 1774 |
| 1877 // Emit information about attribute groups. | 1775 // Emit information about attribute groups. |
| 1878 WriteAttributeGroupTable(VE, Stream); | 1776 WriteAttributeGroupTable(VE, Stream); |
| 1879 | 1777 |
| 1880 // Emit information about parameter attributes. | 1778 // Emit information about parameter attributes. |
| 1881 WriteAttributeTable(VE, Stream); | 1779 WriteAttributeTable(VE, Stream); |
| 1882 | 1780 |
| 1883 // Emit information describing all of the types in the module. | 1781 // Emit information describing all of the types in the module. |
| 1884 WriteTypeTable(VE, Stream); | 1782 WriteTypeTable(VE, Stream); |
| 1885 | 1783 |
| 1886 // Emit top-level description of module, including target triple, inline asm, | 1784 // Emit top-level description of module, including target triple, inline asm, |
| 1887 // descriptors for global variables, and function prototype info. | 1785 // descriptors for global variables, and function prototype info. |
| 1888 WriteModuleInfo(M, VE, Stream); | 1786 WriteModuleInfo(M, VE, Stream); |
| 1889 | 1787 |
| 1890 // Emit constants. | 1788 // Emit constants. |
| 1891 WriteModuleConstants(VE, Stream); | 1789 WriteModuleConstants(VE, Stream); |
| 1892 | 1790 |
| 1893 // Emit metadata. | 1791 // Emit metadata. |
| 1894 WriteModuleMetadata(M, VE, Stream); | 1792 WriteModuleMetadata(M, VE, Stream); |
| 1895 | 1793 |
| 1896 // Emit metadata. | 1794 // Emit metadata. |
| 1897 WriteModuleMetadataStore(M, Stream); | 1795 WriteModuleMetadataStore(M, Stream); |
| 1898 | 1796 |
| 1899 // Emit names for globals/functions etc. | 1797 // Emit names for globals/functions etc. |
| 1900 WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream); | 1798 WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream); |
| 1901 | 1799 |
| 1902 // Emit use-lists. | |
| 1903 if (EnablePreserveUseListOrdering) | |
| 1904 WriteModuleUseLists(M, VE, Stream); | |
| 1905 | |
| 1906 // Emit function bodies. | 1800 // Emit function bodies. |
| 1907 for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) | 1801 for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) |
| 1908 if (!F->isDeclaration()) | 1802 if (!F->isDeclaration()) |
| 1909 WriteFunction(*F, VE, Stream); | 1803 WriteFunction(*F, VE, Stream); |
| 1910 | 1804 |
| 1911 Stream.ExitBlock(); | 1805 Stream.ExitBlock(); |
| 1912 } | 1806 } |
| 1913 | 1807 |
| 1914 /// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a | 1808 /// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a |
| 1915 /// header and trailer to make it compatible with the system archiver. To do | 1809 /// header and trailer to make it compatible with the system archiver. To do |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1979 WriteInt32ToBuffer(BCSize , Buffer, Position); | 1873 WriteInt32ToBuffer(BCSize , Buffer, Position); |
| 1980 WriteInt32ToBuffer(CPUType , Buffer, Position); | 1874 WriteInt32ToBuffer(CPUType , Buffer, Position); |
| 1981 | 1875 |
| 1982 // If the file is not a multiple of 16 bytes, insert dummy padding. | 1876 // If the file is not a multiple of 16 bytes, insert dummy padding. |
| 1983 while (Buffer.size() & 15) | 1877 while (Buffer.size() & 15) |
| 1984 Buffer.push_back(0); | 1878 Buffer.push_back(0); |
| 1985 } | 1879 } |
| 1986 | 1880 |
| 1987 /// WriteBitcodeToFile - Write the specified module to the specified output | 1881 /// WriteBitcodeToFile - Write the specified module to the specified output |
| 1988 /// stream. | 1882 /// stream. |
| 1989 void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) { | 1883 void llvm::PNaClWriteBitcodeToFile(const Module *M, raw_ostream &Out) { |
| 1990 SmallVector<char, 0> Buffer; | 1884 SmallVector<char, 0> Buffer; |
| 1991 Buffer.reserve(256*1024); | 1885 Buffer.reserve(256*1024); |
| 1992 | 1886 |
| 1993 // Convert Deplib info to metadata | 1887 // Convert Deplib info to metadata |
| 1994 M->convertLibraryListToMetadata(); // @LOCALMOD | 1888 M->convertLibraryListToMetadata(); // @LOCALMOD |
| 1995 | 1889 |
| 1996 // If this is darwin or another generic macho target, reserve space for the | 1890 // If this is darwin or another generic macho target, reserve space for the |
| 1997 // header. | 1891 // header. |
| 1998 Triple TT(M->getTargetTriple()); | 1892 Triple TT(M->getTargetTriple()); |
| 1999 if (TT.isOSDarwin()) | 1893 if (TT.isOSDarwin()) |
| 2000 Buffer.insert(Buffer.begin(), DarwinBCHeaderSize, 0); | 1894 Buffer.insert(Buffer.begin(), DarwinBCHeaderSize, 0); |
| 2001 | 1895 |
| 2002 // Emit the module into the buffer. | 1896 // Emit the module into the buffer. |
| 2003 { | 1897 { |
| 2004 BitstreamWriter Stream(Buffer); | 1898 PNaClBitstreamWriter Stream(Buffer); |
| 2005 | 1899 |
| 2006 // Emit the file header. | 1900 // Emit the file header. |
| 2007 Stream.Emit((unsigned)'B', 8); | 1901 Stream.Emit((unsigned)'B', 8); |
| 2008 Stream.Emit((unsigned)'C', 8); | 1902 Stream.Emit((unsigned)'C', 8); |
| 2009 Stream.Emit(0x0, 4); | 1903 Stream.Emit(0x0, 4); |
| 2010 Stream.Emit(0xC, 4); | 1904 Stream.Emit(0xC, 4); |
| 2011 Stream.Emit(0xE, 4); | 1905 Stream.Emit(0xE, 4); |
| 2012 Stream.Emit(0xD, 4); | 1906 Stream.Emit(0xD, 4); |
| 2013 | 1907 |
| 2014 // Emit the module. | 1908 // Emit the module. |
| 2015 WriteModule(M, Stream); | 1909 WriteModule(M, Stream); |
| 2016 } | 1910 } |
| 2017 | 1911 |
| 2018 if (TT.isOSDarwin()) | 1912 if (TT.isOSDarwin()) |
| 2019 EmitDarwinBCHeaderAndTrailer(Buffer, TT); | 1913 EmitDarwinBCHeaderAndTrailer(Buffer, TT); |
| 2020 | 1914 |
| 2021 // Write the generated bitstream to "Out". | 1915 // Write the generated bitstream to "Out". |
| 2022 Out.write((char*)&Buffer.front(), Buffer.size()); | 1916 Out.write((char*)&Buffer.front(), Buffer.size()); |
| 2023 } | 1917 } |
| OLD | NEW |