diff options
Diffstat (limited to 'lib/Bitcode')
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 42 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 78 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriterPass.cpp | 16 | ||||
-rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.cpp | 20 | ||||
-rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.h | 5 |
5 files changed, 96 insertions, 65 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 84753ff..5366f5f 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -16,6 +16,7 @@ #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DiagnosticPrinter.h" @@ -218,6 +219,8 @@ class BitcodeReader : public GVMaterializer { /// True if any Metadata block has been materialized. bool IsMetadataMaterialized; + bool StripDebugInfo = false; + public: std::error_code Error(BitcodeError E, const Twine &Message); std::error_code Error(BitcodeError E); @@ -227,7 +230,7 @@ public: DiagnosticHandlerFunction DiagnosticHandler); explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C, DiagnosticHandlerFunction DiagnosticHandler); - ~BitcodeReader() { FreeState(); } + ~BitcodeReader() override { FreeState(); } std::error_code materializeForwardReferencedFunctions(); @@ -255,6 +258,8 @@ public: /// Materialize any deferred Metadata block. std::error_code materializeMetadata() override; + void setStripDebugInfo() override; + private: std::vector<StructType *> IdentifiedStructTypes; StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); @@ -1093,6 +1098,8 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) { return Attribute::NonNull; case bitc::ATTR_KIND_DEREFERENCEABLE: return Attribute::Dereferenceable; + case bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL: + return Attribute::DereferenceableOrNull; case bitc::ATTR_KIND_NO_RED_ZONE: return Attribute::NoRedZone; case bitc::ATTR_KIND_NO_RETURN: @@ -1209,6 +1216,8 @@ std::error_code BitcodeReader::ParseAttributeGroupBlock() { B.addStackAlignmentAttr(Record[++i]); else if (Kind == Attribute::Dereferenceable) B.addDereferenceableAttr(Record[++i]); + else if (Kind == Attribute::DereferenceableOrNull) + B.addDereferenceableOrNullAttr(Record[++i]); } else { // String attribute assert((Record[i] == 3 || Record[i] == 4) && "Invalid attribute group entry"); @@ -1906,7 +1915,8 @@ std::error_code BitcodeReader::ParseMetadata() { break; } case bitc::METADATA_LOCAL_VAR: { - if (Record.size() != 10) + // 10th field is for the obseleted 'inlinedAt:' field. + if (Record.size() != 9 && Record.size() != 10) return Error("Invalid record"); MDValueList.AssignValue( @@ -1914,7 +1924,7 @@ std::error_code BitcodeReader::ParseMetadata() { (Context, Record[1], getMDOrNull(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getMDOrNull(Record[6]), Record[7], - Record[8], getMDOrNull(Record[9]))), + Record[8])), NextMDValueNo++); break; } @@ -2308,14 +2318,17 @@ std::error_code BitcodeReader::ParseConstants() { Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); } - ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); - V = ConstantExpr::getGetElementPtr(Elts[0], Indices, - BitCode == - bitc::CST_CODE_CE_INBOUNDS_GEP); if (PointeeType && - PointeeType != cast<GEPOperator>(V)->getSourceElementType()) + PointeeType != + cast<SequentialType>(Elts[0]->getType()->getScalarType()) + ->getElementType()) return Error("Explicit gep operator type does not match pointee type " "of pointer operand"); + + ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); + V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices, + BitCode == + bitc::CST_CODE_CE_INBOUNDS_GEP); break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] @@ -2609,6 +2622,8 @@ std::error_code BitcodeReader::materializeMetadata() { return std::error_code(); } +void BitcodeReader::setStripDebugInfo() { StripDebugInfo = true; } + /// RememberAndSkipFunctionBody - When we see the block for a function body, /// remember where it is and then skip it. This lets us lazily deserialize the /// functions. @@ -3053,8 +3068,12 @@ std::error_code BitcodeReader::ParseBitcodeInto(Module *M, // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (1) { - if (Stream.AtEndOfStream()) - return std::error_code(); + if (Stream.AtEndOfStream()) { + if (TheModule) + return std::error_code(); + // We didn't really read a proper Module. + return Error("Malformed IR file"); + } BitstreamEntry Entry = Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); @@ -4305,6 +4324,9 @@ std::error_code BitcodeReader::materialize(GlobalValue *GV) { return EC; F->setIsMaterializable(false); + if (StripDebugInfo) + stripDebugInfo(*F); + // Upgrade any old intrinsic calls in the function. for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(), E = UpgradedIntrinsics.end(); I != E; ++I) { diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 0123fb2..aa4a6a4 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -200,6 +200,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_NON_NULL; case Attribute::Dereferenceable: return bitc::ATTR_KIND_DEREFERENCEABLE; + case Attribute::DereferenceableOrNull: + return bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL; case Attribute::NoRedZone: return bitc::ATTR_KIND_NO_RED_ZONE; case Attribute::NoReturn: @@ -821,7 +823,7 @@ static void WriteMDSubrange(const MDSubrange *N, const ValueEnumerator &, unsigned Abbrev) { Record.push_back(N->isDistinct()); Record.push_back(N->getCount()); - Record.push_back(rotateSign(N->getLo())); + Record.push_back(rotateSign(N->getLowerBound())); Stream.EmitRecord(bitc::METADATA_SUBRANGE, Record, Abbrev); Record.clear(); @@ -892,10 +894,10 @@ static void WriteMDCompositeType(const MDCompositeType *N, Record.push_back(N->getAlignInBits()); Record.push_back(N->getOffsetInBits()); Record.push_back(N->getFlags()); - Record.push_back(VE.getMetadataOrNullID(N->getElements())); + Record.push_back(VE.getMetadataOrNullID(N->getElements().get())); Record.push_back(N->getRuntimeLang()); Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder())); - Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams())); + Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get())); Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier())); Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev); @@ -909,7 +911,7 @@ static void WriteMDSubroutineType(const MDSubroutineType *N, unsigned Abbrev) { Record.push_back(N->isDistinct()); Record.push_back(N->getFlags()); - Record.push_back(VE.getMetadataOrNullID(N->getTypeArray())); + Record.push_back(VE.getMetadataOrNullID(N->getTypeArray().get())); Stream.EmitRecord(bitc::METADATA_SUBROUTINE_TYPE, Record, Abbrev); Record.clear(); @@ -940,11 +942,11 @@ static void WriteMDCompileUnit(const MDCompileUnit *N, Record.push_back(N->getRuntimeVersion()); Record.push_back(VE.getMetadataOrNullID(N->getRawSplitDebugFilename())); Record.push_back(N->getEmissionKind()); - Record.push_back(VE.getMetadataOrNullID(N->getEnumTypes())); - Record.push_back(VE.getMetadataOrNullID(N->getRetainedTypes())); - Record.push_back(VE.getMetadataOrNullID(N->getSubprograms())); - Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables())); - Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities())); + Record.push_back(VE.getMetadataOrNullID(N->getEnumTypes().get())); + Record.push_back(VE.getMetadataOrNullID(N->getRetainedTypes().get())); + Record.push_back(VE.getMetadataOrNullID(N->getSubprograms().get())); + Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables().get())); + Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities().get())); Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); Record.clear(); @@ -970,10 +972,10 @@ static void WriteMDSubprogram(const MDSubprogram *N, Record.push_back(N->getVirtualIndex()); Record.push_back(N->getFlags()); Record.push_back(N->isOptimized()); - Record.push_back(VE.getMetadataOrNullID(N->getFunction())); - Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams())); + Record.push_back(VE.getMetadataOrNullID(N->getRawFunction())); + Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get())); Record.push_back(VE.getMetadataOrNullID(N->getDeclaration())); - Record.push_back(VE.getMetadataOrNullID(N->getVariables())); + Record.push_back(VE.getMetadataOrNullID(N->getVariables().get())); Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev); Record.clear(); @@ -1064,7 +1066,7 @@ static void WriteMDGlobalVariable(const MDGlobalVariable *N, Record.push_back(VE.getMetadataOrNullID(N->getType())); Record.push_back(N->isLocalToUnit()); Record.push_back(N->isDefinition()); - Record.push_back(VE.getMetadataOrNullID(N->getVariable())); + Record.push_back(VE.getMetadataOrNullID(N->getRawVariable())); Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration())); Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev); @@ -1085,7 +1087,6 @@ static void WriteMDLocalVariable(const MDLocalVariable *N, Record.push_back(VE.getMetadataOrNullID(N->getType())); Record.push_back(N->getArg()); Record.push_back(N->getFlags()); - Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt())); Stream.EmitRecord(bitc::METADATA_LOCAL_VAR, Record, Abbrev); Record.clear(); @@ -2047,6 +2048,9 @@ static void WriteUseList(ValueEnumerator &VE, UseListOrder &&Order, static void WriteUseListBlock(const Function *F, ValueEnumerator &VE, BitstreamWriter &Stream) { + assert(VE.shouldPreserveUseListOrder() && + "Expected to be preserving use-list order"); + auto hasMore = [&]() { return !VE.UseListOrders.empty() && VE.UseListOrders.back().F == F; }; @@ -2089,7 +2093,7 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, bool NeedsMetadataAttachment = false; - DebugLoc LastDL; + MDLocation *LastDL = nullptr; // Finally, emit all the instructions, in order. for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) @@ -2104,26 +2108,22 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc(); // If the instruction has a debug location, emit it. - DebugLoc DL = I->getDebugLoc(); - if (DL.isUnknown()) { - // nothing todo. - } else if (DL == LastDL) { + MDLocation *DL = I->getDebugLoc(); + if (!DL) + continue; + + if (DL == LastDL) { // Just repeat the same debug loc as last time. Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals); - } else { - MDNode *Scope, *IA; - DL.getScopeAndInlinedAt(Scope, IA, I->getContext()); - assert(Scope && "Expected valid scope"); - - Vals.push_back(DL.getLine()); - Vals.push_back(DL.getCol()); - Vals.push_back(VE.getMetadataOrNullID(Scope)); - Vals.push_back(VE.getMetadataOrNullID(IA)); - Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); - Vals.clear(); - - LastDL = DL; + continue; } + + Vals.push_back(DL->getLine()); + Vals.push_back(DL->getColumn()); + Vals.push_back(VE.getMetadataOrNullID(DL->getScope())); + Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt())); + Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); + Vals.clear(); } // Emit names for all the instructions etc. @@ -2131,7 +2131,7 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, if (NeedsMetadataAttachment) WriteMetadataAttachment(F, VE, Stream); - if (shouldPreserveBitcodeUseListOrder()) + if (VE.shouldPreserveUseListOrder()) WriteUseListBlock(&F, VE, Stream); VE.purgeFunction(); Stream.ExitBlock(); @@ -2313,7 +2313,8 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { } /// WriteModule - Emit the specified module to the bitstream. -static void WriteModule(const Module *M, BitstreamWriter &Stream) { +static void WriteModule(const Module *M, BitstreamWriter &Stream, + bool ShouldPreserveUseListOrder) { Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3); SmallVector<unsigned, 1> Vals; @@ -2322,7 +2323,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals); // Analyze the module, enumerating globals, functions, etc. - ValueEnumerator VE(*M); + ValueEnumerator VE(*M, ShouldPreserveUseListOrder); // Emit blockinfo, which defines the standard abbreviations etc. WriteBlockInfo(VE, Stream); @@ -2355,7 +2356,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream); // Emit module-level use-lists. - if (shouldPreserveBitcodeUseListOrder()) + if (VE.shouldPreserveUseListOrder()) WriteUseListBlock(nullptr, VE, Stream); // Emit function bodies. @@ -2441,7 +2442,8 @@ 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) { +void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out, + bool ShouldPreserveUseListOrder) { SmallVector<char, 0> Buffer; Buffer.reserve(256*1024); @@ -2464,7 +2466,7 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) { Stream.Emit(0xD, 4); // Emit the module. - WriteModule(M, Stream); + WriteModule(M, Stream, ShouldPreserveUseListOrder); } if (TT.isOSDarwin()) diff --git a/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/lib/Bitcode/Writer/BitcodeWriterPass.cpp index 25456a4..3165743 100644 --- a/lib/Bitcode/Writer/BitcodeWriterPass.cpp +++ b/lib/Bitcode/Writer/BitcodeWriterPass.cpp @@ -19,22 +19,25 @@ using namespace llvm; PreservedAnalyses BitcodeWriterPass::run(Module &M) { - WriteBitcodeToFile(&M, OS); + WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder); return PreservedAnalyses::all(); } namespace { class WriteBitcodePass : public ModulePass { raw_ostream &OS; // raw_ostream to print on + bool ShouldPreserveUseListOrder; + public: static char ID; // Pass identification, replacement for typeid - explicit WriteBitcodePass(raw_ostream &o) - : ModulePass(ID), OS(o) {} + explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder) + : ModulePass(ID), OS(o), + ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {} const char *getPassName() const override { return "Bitcode Writer"; } bool runOnModule(Module &M) override { - WriteBitcodeToFile(&M, OS); + WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder); return false; } }; @@ -42,6 +45,7 @@ namespace { char WriteBitcodePass::ID = 0; -ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str) { - return new WriteBitcodePass(Str); +ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str, + bool ShouldPreserveUseListOrder) { + return new WriteBitcodePass(Str, ShouldPreserveUseListOrder); } diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 549e94f..7f576d7 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -283,9 +283,11 @@ static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) { return V.first->getType()->isIntOrIntVectorTy(); } -ValueEnumerator::ValueEnumerator(const Module &M) - : HasMDString(false), HasMDLocation(false), HasGenericDebugNode(false) { - if (shouldPreserveBitcodeUseListOrder()) +ValueEnumerator::ValueEnumerator(const Module &M, + bool ShouldPreserveUseListOrder) + : HasMDString(false), HasMDLocation(false), HasGenericDebugNode(false), + ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) { + if (ShouldPreserveUseListOrder) UseListOrders = predictUseListOrder(M); // Enumerate the global variables. @@ -373,12 +375,10 @@ ValueEnumerator::ValueEnumerator(const Module &M) for (unsigned i = 0, e = MDs.size(); i != e; ++i) EnumerateMetadata(MDs[i].second); - if (!I.getDebugLoc().isUnknown()) { - MDNode *Scope, *IA; - I.getDebugLoc().getScopeAndInlinedAt(Scope, IA, I.getContext()); - if (Scope) EnumerateMetadata(Scope); - if (IA) EnumerateMetadata(IA); - } + // Don't enumerate the location directly -- it has a special record + // type -- but enumerate its operands. + if (MDLocation *L = I.getDebugLoc()) + EnumerateMDNodeOperands(L); } } @@ -463,7 +463,7 @@ void ValueEnumerator::print(raw_ostream &OS, const MetadataMapType &Map, void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) { if (CstStart == CstEnd || CstStart+1 == CstEnd) return; - if (shouldPreserveBitcodeUseListOrder()) + if (ShouldPreserveUseListOrder) // Optimizing constants makes the use-list order difficult to predict. // Disable it for now when trying to preserve the order. return; diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h index b94c370..ba245a3 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.h +++ b/lib/Bitcode/Writer/ValueEnumerator.h @@ -67,6 +67,7 @@ private: bool HasMDString; bool HasMDLocation; bool HasGenericDebugNode; + bool ShouldPreserveUseListOrder; typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType; AttributeGroupMapType AttributeGroupMap; @@ -102,7 +103,7 @@ private: ValueEnumerator(const ValueEnumerator &) = delete; void operator=(const ValueEnumerator &) = delete; public: - ValueEnumerator(const Module &M); + ValueEnumerator(const Module &M, bool ShouldPreserveUseListOrder); void dump() const; void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const; @@ -123,6 +124,8 @@ public: bool hasMDLocation() const { return HasMDLocation; } bool hasGenericDebugNode() const { return HasGenericDebugNode; } + bool shouldPreserveUseListOrder() const { return ShouldPreserveUseListOrder; } + unsigned getTypeID(Type *T) const { TypeMapType::const_iterator I = TypeMap.find(T); assert(I != TypeMap.end() && "Type not in ValueEnumerator!"); |