diff options
Diffstat (limited to 'llvm/lib/Bitcode/Writer')
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 69 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 127 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.h | 4 |
3 files changed, 166 insertions, 34 deletions
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 37ecb9992e44..0a202c376981 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -335,6 +335,8 @@ private: unsigned Abbrev); void writeDIMacroFile(const DIMacroFile *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); + void writeDIArgList(const DIArgList *N, SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev); void writeDIModule(const DIModule *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); void writeDITemplateTypeParameter(const DITemplateTypeParameter *N, @@ -628,6 +630,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_COLD; case Attribute::Hot: return bitc::ATTR_KIND_HOT; + case Attribute::ElementType: + return bitc::ATTR_KIND_ELEMENTTYPE; case Attribute::InaccessibleMemOnly: return bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY; case Attribute::InaccessibleMemOrArgMemOnly: @@ -684,6 +688,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_NO_PROFILE; case Attribute::NoUnwind: return bitc::ATTR_KIND_NO_UNWIND; + case Attribute::NoSanitizeCoverage: + return bitc::ATTR_KIND_NO_SANITIZE_COVERAGE; case Attribute::NullPointerIsValid: return bitc::ATTR_KIND_NULL_POINTER_IS_VALID; case Attribute::OptForFuzzing: @@ -734,8 +740,12 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_SWIFT_ERROR; case Attribute::SwiftSelf: return bitc::ATTR_KIND_SWIFT_SELF; + case Attribute::SwiftAsync: + return bitc::ATTR_KIND_SWIFT_ASYNC; case Attribute::UWTable: return bitc::ATTR_KIND_UW_TABLE; + case Attribute::VScaleRange: + return bitc::ATTR_KIND_VSCALE_RANGE; case Attribute::WillReturn: return bitc::ATTR_KIND_WILLRETURN; case Attribute::WriteOnly: @@ -854,6 +864,12 @@ void ModuleBitcodeWriter::writeTypeTable() { Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0 unsigned PtrAbbrev = Stream.EmitAbbrev(std::move(Abbv)); + // Abbrev for TYPE_CODE_OPAQUE_POINTER. + Abbv = std::make_shared<BitCodeAbbrev>(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_OPAQUE_POINTER)); + Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0 + unsigned OpaquePtrAbbrev = Stream.EmitAbbrev(std::move(Abbv)); + // Abbrev for TYPE_CODE_FUNCTION. Abbv = std::make_shared<BitCodeAbbrev>(); Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION)); @@ -924,12 +940,21 @@ void ModuleBitcodeWriter::writeTypeTable() { break; case Type::PointerTyID: { PointerType *PTy = cast<PointerType>(T); - // POINTER: [pointee type, address space] - Code = bitc::TYPE_CODE_POINTER; - TypeVals.push_back(VE.getTypeID(PTy->getElementType())); unsigned AddressSpace = PTy->getAddressSpace(); - TypeVals.push_back(AddressSpace); - if (AddressSpace == 0) AbbrevToUse = PtrAbbrev; + if (PTy->isOpaque()) { + // OPAQUE_POINTER: [address space] + Code = bitc::TYPE_CODE_OPAQUE_POINTER; + TypeVals.push_back(AddressSpace); + if (AddressSpace == 0) + AbbrevToUse = OpaquePtrAbbrev; + } else { + // POINTER: [pointee type, address space] + Code = bitc::TYPE_CODE_POINTER; + TypeVals.push_back(VE.getTypeID(PTy->getElementType())); + TypeVals.push_back(AddressSpace); + if (AddressSpace == 0) + AbbrevToUse = PtrAbbrev; + } break; } case Type::FunctionTyID: { @@ -1044,7 +1069,8 @@ static uint64_t getEncodedFFlags(FunctionSummary::FFlags Flags) { return RawFlags; } -// Decode the flags for GlobalValue in the summary +// Decode the flags for GlobalValue in the summary. See getDecodedGVSummaryFlags +// in BitcodeReader.cpp. static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) { uint64_t RawFlags = 0; @@ -1058,6 +1084,8 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) { // account here as well. RawFlags = (RawFlags << 4) | Flags.Linkage; // 4 bits + RawFlags |= (Flags.Visibility << 8); // 2 bits + return RawFlags; } @@ -1104,7 +1132,7 @@ static unsigned getEncodedComdatSelectionKind(const Comdat &C) { return bitc::COMDAT_SELECTION_KIND_EXACT_MATCH; case Comdat::Largest: return bitc::COMDAT_SELECTION_KIND_LARGEST; - case Comdat::NoDuplicates: + case Comdat::NoDeduplicate: return bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES; case Comdat::SameSize: return bitc::COMDAT_SELECTION_KIND_SAME_SIZE; @@ -1864,6 +1892,17 @@ void ModuleBitcodeWriter::writeDIMacroFile(const DIMacroFile *N, Record.clear(); } +void ModuleBitcodeWriter::writeDIArgList(const DIArgList *N, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.reserve(N->getArgs().size()); + for (ValueAsMetadata *MD : N->getArgs()) + Record.push_back(VE.getMetadataID(MD)); + + Stream.EmitRecord(bitc::METADATA_ARG_LIST, Record, Abbrev); + Record.clear(); +} + void ModuleBitcodeWriter::writeDIModule(const DIModule *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { @@ -2411,9 +2450,9 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, } if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) { - Record.push_back(unsigned(IA->hasSideEffects()) | - unsigned(IA->isAlignStack()) << 1 | - unsigned(IA->getDialect()&1) << 2); + Record.push_back( + unsigned(IA->hasSideEffects()) | unsigned(IA->isAlignStack()) << 1 | + unsigned(IA->getDialect() & 1) << 2 | unsigned(IA->canThrow()) << 3); // Add the asm string. const std::string &AsmStr = IA->getAsmString(); @@ -2606,6 +2645,10 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, Record.push_back(VE.getTypeID(BA->getFunction()->getType())); Record.push_back(VE.getValueID(BA->getFunction())); Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock())); + } else if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(C)) { + Code = bitc::CST_CODE_DSO_LOCAL_EQUIVALENT; + Record.push_back(VE.getTypeID(Equiv->getGlobalValue()->getType())); + Record.push_back(VE.getValueID(Equiv->getGlobalValue())); } else { #ifndef NDEBUG C->dump(); @@ -3057,17 +3100,19 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, Vals.push_back( getEncodedOrdering(cast<AtomicCmpXchgInst>(I).getFailureOrdering())); Vals.push_back(cast<AtomicCmpXchgInst>(I).isWeak()); + Vals.push_back(getEncodedAlign(cast<AtomicCmpXchgInst>(I).getAlign())); break; case Instruction::AtomicRMW: Code = bitc::FUNC_CODE_INST_ATOMICRMW; pushValueAndType(I.getOperand(0), InstID, Vals); // ptrty + ptr - pushValue(I.getOperand(1), InstID, Vals); // val. + pushValueAndType(I.getOperand(1), InstID, Vals); // valty + val Vals.push_back( getEncodedRMWOperation(cast<AtomicRMWInst>(I).getOperation())); Vals.push_back(cast<AtomicRMWInst>(I).isVolatile()); Vals.push_back(getEncodedOrdering(cast<AtomicRMWInst>(I).getOrdering())); Vals.push_back( getEncodedSyncScopeID(cast<AtomicRMWInst>(I).getSyncScopeID())); + Vals.push_back(getEncodedAlign(cast<AtomicRMWInst>(I).getAlign())); break; case Instruction::Fence: Code = bitc::FUNC_CODE_INST_FENCE; @@ -4846,7 +4891,7 @@ void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf, const std::vector<uint8_t> &CmdArgs) { // Save llvm.compiler.used and remove it. SmallVector<Constant *, 2> UsedArray; - SmallPtrSet<GlobalValue *, 4> UsedGlobals; + SmallVector<GlobalValue *, 4> UsedGlobals; Type *UsedElementType = Type::getInt8Ty(M.getContext())->getPointerTo(0); GlobalVariable *Used = collectUsedGlobalVariables(M, UsedGlobals, true); for (auto *GV : UsedGlobals) { diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index bbee8b324954..d86db61ee1f4 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -28,6 +28,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" #include "llvm/IR/User.h" @@ -78,16 +79,6 @@ struct OrderMap { } // end anonymous namespace -/// Look for a value that might be wrapped as metadata, e.g. a value in a -/// metadata operand. Returns nullptr for a non-wrapped input value if -/// OnlyWrapped is true, or it returns the input value as-is if false. -static const Value *skipMetadataWrapper(const Value *V, bool OnlyWrapped) { - if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) - if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata())) - return VAM->getValue(); - return OnlyWrapped ? nullptr : V; -} - static void orderValue(const Value *V, OrderMap &OM) { if (OM.lookup(V).first) return; @@ -139,16 +130,25 @@ static OrderMap orderModule(const Module &M) { // these before global values, as these will be read before setting the // global values' initializers. The latter matters for constants which have // uses towards other constants that are used as initializers. + auto orderConstantValue = [&OM](const Value *V) { + if ((isa<Constant>(V) && !isa<GlobalValue>(V)) || isa<InlineAsm>(V)) + orderValue(V, OM); + }; for (const Function &F : M) { if (F.isDeclaration()) continue; for (const BasicBlock &BB : F) for (const Instruction &I : BB) for (const Value *V : I.operands()) { - if (const Value *Op = skipMetadataWrapper(V, true)) { - if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) || - isa<InlineAsm>(*Op)) - orderValue(Op, OM); + if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) { + if (const auto *VAM = + dyn_cast<ValueAsMetadata>(MAV->getMetadata())) { + orderConstantValue(VAM->getValue()); + } else if (const auto *AL = + dyn_cast<DIArgList>(MAV->getMetadata())) { + for (const auto *VAM : AL->getArgs()) + orderConstantValue(VAM->getValue()); + } } } } @@ -365,18 +365,23 @@ ValueEnumerator::ValueEnumerator(const Module &M, UseListOrders = predictUseListOrder(M); // Enumerate the global variables. - for (const GlobalVariable &GV : M.globals()) + for (const GlobalVariable &GV : M.globals()) { EnumerateValue(&GV); + EnumerateType(GV.getValueType()); + } // Enumerate the functions. for (const Function & F : M) { EnumerateValue(&F); + EnumerateType(F.getValueType()); EnumerateAttributes(F.getAttributes()); } // Enumerate the aliases. - for (const GlobalAlias &GA : M.aliases()) + for (const GlobalAlias &GA : M.aliases()) { EnumerateValue(&GA); + EnumerateType(GA.getValueType()); + } // Enumerate the ifuncs. for (const GlobalIFunc &GIF : M.ifuncs()) @@ -448,17 +453,31 @@ ValueEnumerator::ValueEnumerator(const Module &M, continue; } - // Local metadata is enumerated during function-incorporation. + // Local metadata is enumerated during function-incorporation, but + // any ConstantAsMetadata arguments in a DIArgList should be examined + // now. if (isa<LocalAsMetadata>(MD->getMetadata())) continue; + if (auto *AL = dyn_cast<DIArgList>(MD->getMetadata())) { + for (auto *VAM : AL->getArgs()) + if (isa<ConstantAsMetadata>(VAM)) + EnumerateMetadata(&F, VAM); + continue; + } EnumerateMetadata(&F, MD->getMetadata()); } if (auto *SVI = dyn_cast<ShuffleVectorInst>(&I)) EnumerateType(SVI->getShuffleMaskForBitcode()->getType()); + if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) + EnumerateType(GEP->getSourceElementType()); + if (auto *AI = dyn_cast<AllocaInst>(&I)) + EnumerateType(AI->getAllocatedType()); EnumerateType(I.getType()); - if (const auto *Call = dyn_cast<CallBase>(&I)) + if (const auto *Call = dyn_cast<CallBase>(&I)) { EnumerateAttributes(Call->getAttributes()); + EnumerateType(Call->getFunctionType()); + } // Enumerate metadata attached with this instruction. MDs.clear(); @@ -619,6 +638,11 @@ void ValueEnumerator::EnumerateFunctionLocalMetadata( EnumerateFunctionLocalMetadata(getMetadataFunctionID(&F), Local); } +void ValueEnumerator::EnumerateFunctionLocalListMetadata( + const Function &F, const DIArgList *ArgList) { + EnumerateFunctionLocalListMetadata(getMetadataFunctionID(&F), ArgList); +} + void ValueEnumerator::dropFunctionFromMetadata( MetadataMapType::value_type &FirstMD) { SmallVector<const MDNode *, 64> Worklist; @@ -729,7 +753,7 @@ const MDNode *ValueEnumerator::enumerateMetadataImpl(unsigned F, const Metadata return nullptr; } -/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata +/// EnumerateFunctionLocalMetadata - Incorporate function-local metadata /// information reachable from the metadata. void ValueEnumerator::EnumerateFunctionLocalMetadata( unsigned F, const LocalAsMetadata *Local) { @@ -749,6 +773,39 @@ void ValueEnumerator::EnumerateFunctionLocalMetadata( EnumerateValue(Local->getValue()); } +/// EnumerateFunctionLocalListMetadata - Incorporate function-local metadata +/// information reachable from the metadata. +void ValueEnumerator::EnumerateFunctionLocalListMetadata( + unsigned F, const DIArgList *ArgList) { + assert(F && "Expected a function"); + + // Check to see if it's already in! + MDIndex &Index = MetadataMap[ArgList]; + if (Index.ID) { + assert(Index.F == F && "Expected the same function"); + return; + } + + for (ValueAsMetadata *VAM : ArgList->getArgs()) { + if (isa<LocalAsMetadata>(VAM)) { + assert(MetadataMap.count(VAM) && + "LocalAsMetadata should be enumerated before DIArgList"); + assert(MetadataMap[VAM].F == F && + "Expected LocalAsMetadata in the same function"); + } else { + assert(isa<ConstantAsMetadata>(VAM) && + "Expected LocalAsMetadata or ConstantAsMetadata"); + assert(ValueMap.count(VAM->getValue()) && + "Constant should be enumerated beforeDIArgList"); + EnumerateMetadata(F, VAM); + } + } + + MDs.push_back(ArgList); + Index.F = F; + Index.ID = MDs.size(); +} + static unsigned getMetadataTypeOrder(const Metadata *MD) { // Strings are emitted in bulk and must come first. if (isa<MDString>(MD)) @@ -959,9 +1016,12 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) { EnumerateOperandType(Op); } - if (auto *CE = dyn_cast<ConstantExpr>(C)) + if (auto *CE = dyn_cast<ConstantExpr>(C)) { if (CE->getOpcode() == Instruction::ShuffleVector) EnumerateOperandType(CE->getShuffleMaskForBitcode()); + if (CE->getOpcode() == Instruction::GetElementPtr) + EnumerateType(cast<GEPOperator>(CE)->getSourceElementType()); + } } void ValueEnumerator::EnumerateAttributes(AttributeList PAL) { @@ -985,6 +1045,11 @@ void ValueEnumerator::EnumerateAttributes(AttributeList PAL) { if (Entry == 0) { AttributeGroups.push_back(Pair); Entry = AttributeGroups.size(); + + for (Attribute Attr : AS) { + if (Attr.isTypeAttribute()) + EnumerateType(Attr.getValueAsType()); + } } } } @@ -1004,6 +1069,8 @@ void ValueEnumerator::incorporateFunction(const Function &F) { EnumerateType(I.getParamByValType()); else if (I.hasAttribute(Attribute::StructRet)) EnumerateType(I.getParamStructRetType()); + else if (I.hasAttribute(Attribute::ByRef)) + EnumerateType(I.getParamByRefType()); } FirstFuncConstantID = Values.size(); @@ -1031,14 +1098,26 @@ void ValueEnumerator::incorporateFunction(const Function &F) { FirstInstID = Values.size(); SmallVector<LocalAsMetadata *, 8> FnLocalMDVector; + SmallVector<DIArgList *, 8> ArgListMDVector; // Add all of the instructions. for (const BasicBlock &BB : F) { for (const Instruction &I : BB) { for (const Use &OI : I.operands()) { - if (auto *MD = dyn_cast<MetadataAsValue>(&OI)) - if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata())) + if (auto *MD = dyn_cast<MetadataAsValue>(&OI)) { + if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata())) { // Enumerate metadata after the instructions they might refer to. FnLocalMDVector.push_back(Local); + } else if (auto *ArgList = dyn_cast<DIArgList>(MD->getMetadata())) { + ArgListMDVector.push_back(ArgList); + for (ValueAsMetadata *VMD : ArgList->getArgs()) { + if (auto *Local = dyn_cast<LocalAsMetadata>(VMD)) { + // Enumerate metadata after the instructions they might refer + // to. + FnLocalMDVector.push_back(Local); + } + } + } + } } if (!I.getType()->isVoidTy()) @@ -1054,6 +1133,10 @@ void ValueEnumerator::incorporateFunction(const Function &F) { "Missing value for metadata operand"); EnumerateFunctionLocalMetadata(F, FnLocalMDVector[i]); } + // DIArgList entries must come after function-local metadata, as it is not + // possible to forward-reference them. + for (const DIArgList *ArgList : ArgListMDVector) + EnumerateFunctionLocalListMetadata(F, ArgList); } void ValueEnumerator::purgeFunction() { diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h index 3c3bd0d9fdc7..6c3f6d4ff61e 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -27,6 +27,7 @@ namespace llvm { class BasicBlock; class Comdat; +class DIArgList; class Function; class Instruction; class LocalAsMetadata; @@ -286,6 +287,9 @@ private: void EnumerateFunctionLocalMetadata(const Function &F, const LocalAsMetadata *Local); void EnumerateFunctionLocalMetadata(unsigned F, const LocalAsMetadata *Local); + void EnumerateFunctionLocalListMetadata(const Function &F, + const DIArgList *ArgList); + void EnumerateFunctionLocalListMetadata(unsigned F, const DIArgList *Arglist); void EnumerateNamedMDNode(const NamedMDNode *NMD); void EnumerateValue(const Value *V); void EnumerateType(Type *T); |