diff options
Diffstat (limited to 'lib/Bitcode/Writer/BitcodeWriter.cpp')
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 128 |
1 files changed, 68 insertions, 60 deletions
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 60c657ae6d..ffe95d8f27 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -12,22 +12,22 @@ //===----------------------------------------------------------------------===// #include "llvm/Bitcode/ReaderWriter.h" +#include "ValueEnumerator.h" +#include "llvm/ADT/Triple.h" #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Bitcode/LLVMBitCodes.h" -#include "ValueEnumerator.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Operator.h" -#include "llvm/ValueSymbolTable.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Program.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/ValueSymbolTable.h" #include <cctype> #include <map> using namespace llvm; @@ -61,7 +61,7 @@ enum { FUNCTION_INST_RET_VOID_ABBREV, FUNCTION_INST_RET_VAL_ABBREV, FUNCTION_INST_UNREACHABLE_ABBREV, - + // SwitchInst Magic SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex }; @@ -164,14 +164,14 @@ static void WriteStringRecord(unsigned Code, StringRef Str, // Emit information about parameter attributes. static void WriteAttributeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { - const std::vector<AttrListPtr> &Attrs = VE.getAttributes(); + const std::vector<AttributeSet> &Attrs = VE.getAttributes(); if (Attrs.empty()) return; Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3); SmallVector<uint64_t, 64> Record; for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { - const AttrListPtr &A = Attrs[i]; + const AttributeSet &A = Attrs[i]; for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) { const AttributeWithIndex &PAWI = A.getSlot(i); Record.push_back(PAWI.Index); @@ -234,7 +234,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv); - + // Abbrev for TYPE_CODE_ARRAY. Abbv = new BitCodeAbbrev(); Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY)); @@ -256,16 +256,16 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { switch (T->getTypeID()) { default: llvm_unreachable("Unknown type!"); - case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; - case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break; - case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; - case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; - case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; - case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; + case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; + case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break; + case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; + case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; + case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; + case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break; - case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; - case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; - case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; + case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; + case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; + case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; case Type::IntegerTyID: // INTEGER: [width] Code = bitc::TYPE_CODE_INTEGER; @@ -300,7 +300,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { for (StructType::element_iterator I = ST->element_begin(), E = ST->element_end(); I != E; ++I) TypeVals.push_back(VE.getTypeID(*I)); - + if (ST->isLiteral()) { Code = bitc::TYPE_CODE_STRUCT_ANON; AbbrevToUse = StructAnonAbbrev; @@ -392,10 +392,6 @@ static unsigned getEncodedThreadLocalMode(const GlobalVariable *GV) { // descriptors for global variables, and function prototype info. static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, BitstreamWriter &Stream) { - // Emit the list of dependent libraries for the Module. - for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I) - WriteStringRecord(bitc::MODULE_CODE_DEPLIB, *I, 0/*TODO*/, Stream); - // Emit various pieces of data attached to a module. if (!M->getTargetTriple().empty()) WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(), @@ -553,6 +549,18 @@ static uint64_t GetOptimizationFlags(const Value *V) { dyn_cast<PossiblyExactOperator>(V)) { if (PEO->isExact()) Flags |= 1 << bitc::PEO_EXACT; + } else if (const FPMathOperator *FPMO = + dyn_cast<const FPMathOperator>(V)) { + if (FPMO->hasUnsafeAlgebra()) + Flags |= FastMathFlags::UnsafeAlgebra; + if (FPMO->hasNoNaNs()) + Flags |= FastMathFlags::NoNaNs; + if (FPMO->hasNoInfs()) + Flags |= FastMathFlags::NoInfs; + if (FPMO->hasNoSignedZeros()) + Flags |= FastMathFlags::NoSignedZeros; + if (FPMO->hasAllowReciprocal()) + Flags |= FastMathFlags::AllowReciprocal; } return Flags; @@ -658,7 +666,7 @@ static void WriteFunctionLocalMetadata(const Function &F, } WriteMDNode(N, VE, Stream, Record); } - + if (StartedMetadataBlock) Stream.ExitBlock(); } @@ -673,18 +681,18 @@ static void WriteMetadataAttachment(const Function &F, // Write metadata attachments // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] SmallVector<std::pair<unsigned, MDNode*>, 4> MDs; - + for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { MDs.clear(); I->getAllMetadataOtherThanDebugLoc(MDs); - + // If no metadata, ignore instruction. if (MDs.empty()) continue; Record.push_back(VE.getInstructionID(I)); - + for (unsigned i = 0, e = MDs.size(); i != e; ++i) { Record.push_back(MDs[i].first); Record.push_back(VE.getValueID(MDs[i].second)); @@ -701,18 +709,18 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) { // Write metadata kinds // METADATA_KIND - [n x [id, name]] - SmallVector<StringRef, 4> Names; + SmallVector<StringRef, 8> Names; M->getMDKindNames(Names); - + if (Names.empty()) return; Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); - + for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) { Record.push_back(MDKindID); StringRef KName = Names[MDKindID]; Record.append(KName.begin(), KName.end()); - + Stream.EmitRecord(bitc::METADATA_KIND, Record, 0); Record.clear(); } @@ -743,10 +751,10 @@ static void EmitAPInt(SmallVectorImpl<uint64_t> &Vals, // format it is likely that the high bits are going to be zero. // So, we only write the number of active words. unsigned NWords = Val.getActiveWords(); - + if (EmitSizeForWideNumbers) Vals.push_back(NWords); - + const uint64_t *RawWords = Val.getRawData(); for (unsigned i = 0; i != NWords; ++i) { emitSignedInt64(Vals, RawWords[i]); @@ -881,12 +889,12 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, if (isCStrChar6) isCStrChar6 = BitCodeAbbrevOp::isChar6(V); } - + if (isCStrChar6) AbbrevToUse = CString6Abbrev; else if (isCStr7) AbbrevToUse = CString7Abbrev; - } else if (const ConstantDataSequential *CDS = + } else if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(C)) { Code = bitc::CST_CODE_DATA; Type *EltTy = CDS->getType()->getElementType(); @@ -1179,13 +1187,13 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, // Redefine Vals, since here we need to use 64 bit values // explicitly to store large APInt numbers. SmallVector<uint64_t, 128> Vals64; - + Code = bitc::FUNC_CODE_INST_SWITCH; SwitchInst &SI = cast<SwitchInst>(I); - - uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16); - Vals64.push_back(SwitchRecordHeader); - + + uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16); + Vals64.push_back(SwitchRecordHeader); + Vals64.push_back(VE.getTypeID(SI.getCondition()->getType())); pushValue64(SI.getCondition(), InstID, Vals64, VE); Vals64.push_back(VE.getValueID(SI.getDefaultDest())); @@ -1194,21 +1202,21 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, i != e; ++i) { IntegersSubset& CaseRanges = i.getCaseValueEx(); unsigned Code, Abbrev; // will unused. - + if (CaseRanges.isSingleNumber()) { Vals64.push_back(1/*NumItems = 1*/); Vals64.push_back(true/*IsSingleNumber = true*/); EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true); } else { - + Vals64.push_back(CaseRanges.getNumItems()); - + if (CaseRanges.isSingleNumbersOnly()) { for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) { - + Vals64.push_back(true/*IsSingleNumber = true*/); - + EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(ri), true); } @@ -1217,9 +1225,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, ri != rn; ++ri) { IntegersSubset::Range r = CaseRanges.getItem(ri); bool IsSingleNumber = CaseRanges.isSingleNumber(ri); - + Vals64.push_back(IsSingleNumber); - + EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true); if (!IsSingleNumber) EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true); @@ -1227,9 +1235,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, } Vals64.push_back(VE.getValueID(i.getCaseSuccessor())); } - + Stream.EmitRecord(Code, Vals64, AbbrevToUse); - + // Also do expected action - clear external Vals collection: Vals.clear(); return; @@ -1243,7 +1251,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) Vals.push_back(VE.getValueID(I.getOperand(i))); break; - + case Instruction::Invoke: { const InvokeInst *II = cast<InvokeInst>(&I); const Value *Callee(II->getCalledValue()); @@ -1502,21 +1510,21 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, unsigned InstID = CstEnd; bool NeedsMetadataAttachment = false; - + DebugLoc LastDL; - + // Finally, emit all the instructions, in order. for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { WriteInstruction(*I, InstID, VE, Stream, Vals); - + if (!I->getType()->isVoidTy()) ++InstID; - + // If the instruction has metadata, write a metadata attachment later. NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc(); - + // If the instruction has a debug location, emit it. DebugLoc DL = I->getDebugLoc(); if (DL.isUnknown()) { @@ -1527,14 +1535,14 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, } else { MDNode *Scope, *IA; DL.getScopeAndInlinedAt(Scope, IA, I->getContext()); - + Vals.push_back(DL.getLine()); Vals.push_back(DL.getCol()); Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0); Vals.push_back(IA ? VE.getValueID(IA)+1 : 0); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); Vals.clear(); - + LastDL = DL; } } @@ -1709,7 +1717,7 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { Stream.ExitBlock(); } -// Sort the Users based on the order in which the reader parses the bitcode +// Sort the Users based on the order in which the reader parses the bitcode // file. static bool bitcodereader_order(const User *lhs, const User *rhs) { // TODO: Implement. @@ -1778,9 +1786,9 @@ static void WriteModuleUseLists(const Module *M, ValueEnumerator &VE, for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) I->removeDeadConstantUsers(); - + // Write the global variables. - for (Module::const_global_iterator GI = M->global_begin(), + for (Module::const_global_iterator GI = M->global_begin(), GE = M->global_end(); GI != GE; ++GI) { WriteUseList(GI, VE, Stream); @@ -1931,7 +1939,7 @@ static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer, /// WriteBitcodeToFile - Write the specified module to the specified output /// stream. void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) { - SmallVector<char, 1024> Buffer; + SmallVector<char, 0> Buffer; Buffer.reserve(256*1024); // If this is darwin or another generic macho target, reserve space for the |