aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Writer
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode/Writer')
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp69
-rw-r--r--llvm/lib/Bitcode/Writer/ValueEnumerator.cpp127
-rw-r--r--llvm/lib/Bitcode/Writer/ValueEnumerator.h4
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);