aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-07-27 23:34:35 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-10-23 18:26:01 +0000
commit0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583 (patch)
tree6cf5ab1f05330c6773b1f3f64799d56a9c7a1faa /contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
parent6b9f7133aba44189d9625c352bc2c2a59baf18ef (diff)
parentac9a064cb179f3425b310fa2847f8764ac970a4d (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp459
1 files changed, 329 insertions, 130 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index a5fc267b1883..324dcbca8137 100644
--- a/contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -33,6 +33,7 @@
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Comdat.h"
#include "llvm/IR/Constant.h"
+#include "llvm/IR/ConstantRangeList.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
@@ -99,6 +100,9 @@ namespace llvm {
extern FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold;
}
+extern bool WriteNewDbgInfoFormatToBitcode;
+extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
+
namespace {
/// These are manifest constants used by the bitcode writer. They do not need to
@@ -128,6 +132,7 @@ enum {
FUNCTION_INST_RET_VAL_ABBREV,
FUNCTION_INST_UNREACHABLE_ABBREV,
FUNCTION_INST_GEP_ABBREV,
+ FUNCTION_DEBUG_RECORD_VALUE_ABBREV,
};
/// Abstract class to manage the bitcode writing, subclassed for each bitcode
@@ -199,7 +204,7 @@ public:
for (const auto &GUIDSummaryLists : *Index)
// Examine all summaries for this GUID.
for (auto &Summary : GUIDSummaryLists.second.SummaryList)
- if (auto FS = dyn_cast<FunctionSummary>(Summary.get()))
+ if (auto FS = dyn_cast<FunctionSummary>(Summary.get())) {
// For each call in the function summary, see if the call
// is to a GUID (which means it is for an indirect call,
// otherwise we would have a Value for it). If so, synthesize
@@ -207,6 +212,15 @@ public:
for (auto &CallEdge : FS->calls())
if (!CallEdge.first.haveGVs() || !CallEdge.first.getValue())
assignValueId(CallEdge.first.getGUID());
+
+ // For each referenced variables in the function summary, see if the
+ // variable is represented by a GUID (as opposed to a symbol to
+ // declarations or definitions in the module). If so, synthesize a
+ // value id.
+ for (auto &RefEdge : FS->refs())
+ if (!RefEdge.haveGVs() || !RefEdge.getValue())
+ assignValueId(RefEdge.getGUID());
+ }
}
protected:
@@ -247,9 +261,6 @@ private:
/// Class to manage the bitcode writing for a module.
class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {
- /// Pointer to the buffer allocated by caller for bitcode writing.
- const SmallVectorImpl<char> &Buffer;
-
/// True if a module hash record should be written.
bool GenerateHash;
@@ -265,14 +276,13 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {
public:
/// Constructs a ModuleBitcodeWriter object for the given Module,
/// writing to the provided \p Buffer.
- ModuleBitcodeWriter(const Module &M, SmallVectorImpl<char> &Buffer,
- StringTableBuilder &StrtabBuilder,
+ ModuleBitcodeWriter(const Module &M, StringTableBuilder &StrtabBuilder,
BitstreamWriter &Stream, bool ShouldPreserveUseListOrder,
const ModuleSummaryIndex *Index, bool GenerateHash,
ModuleHash *ModHash = nullptr)
: ModuleBitcodeWriterBase(M, StrtabBuilder, Stream,
ShouldPreserveUseListOrder, Index),
- Buffer(Buffer), GenerateHash(GenerateHash), ModHash(ModHash),
+ GenerateHash(GenerateHash), ModHash(ModHash),
BitcodeStartBit(Stream.GetCurrentBitNo()) {}
/// Emit the current module to the bitstream.
@@ -401,7 +411,7 @@ private:
writeFunction(const Function &F,
DenseMap<const Function *, uint64_t> &FunctionToBitcodeIndex);
void writeBlockInfo();
- void writeModuleHash(size_t BlockStartPos);
+ void writeModuleHash(StringRef View);
unsigned getEncodedSyncScopeID(SyncScope::ID SSID) {
return unsigned(SSID);
@@ -415,6 +425,11 @@ class IndexBitcodeWriter : public BitcodeWriterBase {
/// The combined index to write to bitcode.
const ModuleSummaryIndex &Index;
+ /// When writing combined summaries, provides the set of global value
+ /// summaries for which the value (function, function alias, etc) should be
+ /// imported as a declaration.
+ const GVSummaryPtrSet *DecSummaries = nullptr;
+
/// When writing a subset of the index for distributed backends, client
/// provides a map of modules to the corresponding GUIDs/summaries to write.
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex;
@@ -423,10 +438,14 @@ class IndexBitcodeWriter : public BitcodeWriterBase {
/// index and a value id generated by this class to use in references.
std::map<GlobalValue::GUID, unsigned> GUIDToValueIdMap;
- // The sorted stack id indices actually used in the summary entries being
- // written, which will be a subset of those in the full index in the case of
- // distributed indexes.
- std::vector<unsigned> StackIdIndices;
+ // The stack ids used by this index, which will be a subset of those in
+ // the full index in the case of distributed indexes.
+ std::vector<uint64_t> StackIds;
+
+ // Keep a map of the stack id indices used by records being written for this
+ // index to the index of the corresponding stack id in the above StackIds
+ // vector. Ensures we write each referenced stack id once.
+ DenseMap<unsigned, unsigned> StackIdIndicesToIndex;
/// Tracks the last value id recorded in the GUIDToValueMap.
unsigned GlobalValueId = 0;
@@ -439,12 +458,30 @@ public:
/// Constructs a IndexBitcodeWriter object for the given combined index,
/// writing to the provided \p Buffer. When writing a subset of the index
/// for a distributed backend, provide a \p ModuleToSummariesForIndex map.
+ /// If provided, \p DecSummaries specifies the set of summaries for which
+ /// the corresponding functions or aliased functions should be imported as a
+ /// declaration (but not definition) for each module.
IndexBitcodeWriter(BitstreamWriter &Stream, StringTableBuilder &StrtabBuilder,
const ModuleSummaryIndex &Index,
+ const GVSummaryPtrSet *DecSummaries = nullptr,
const std::map<std::string, GVSummaryMapTy>
*ModuleToSummariesForIndex = nullptr)
: BitcodeWriterBase(Stream, StrtabBuilder), Index(Index),
+ DecSummaries(DecSummaries),
ModuleToSummariesForIndex(ModuleToSummariesForIndex) {
+
+ // See if the StackIdIndex was already added to the StackId map and
+ // vector. If not, record it.
+ auto RecordStackIdReference = [&](unsigned StackIdIndex) {
+ // If the StackIdIndex is not yet in the map, the below insert ensures
+ // that it will point to the new StackIds vector entry we push to just
+ // below.
+ auto Inserted =
+ StackIdIndicesToIndex.insert({StackIdIndex, StackIds.size()});
+ if (Inserted.second)
+ StackIds.push_back(Index.getStackIdAtIndex(StackIdIndex));
+ };
+
// Assign unique value ids to all summaries to be written, for use
// in writing out the call graph edges. Save the mapping from GUID
// to the new global value id to use when writing those edges, which
@@ -475,17 +512,13 @@ public:
continue;
}
for (auto Idx : CI.StackIdIndices)
- StackIdIndices.push_back(Idx);
+ RecordStackIdReference(Idx);
}
for (auto &AI : FS->allocs())
for (auto &MIB : AI.MIBs)
for (auto Idx : MIB.StackIdIndices)
- StackIdIndices.push_back(Idx);
+ RecordStackIdReference(Idx);
});
- llvm::sort(StackIdIndices);
- StackIdIndices.erase(
- std::unique(StackIdIndices.begin(), StackIdIndices.end()),
- StackIdIndices.end());
}
/// The below iterator returns the GUID and associated summary.
@@ -694,6 +727,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_HOT;
case Attribute::ElementType:
return bitc::ATTR_KIND_ELEMENTTYPE;
+ case Attribute::HybridPatchable:
+ return bitc::ATTR_KIND_HYBRID_PATCHABLE;
case Attribute::InlineHint:
return bitc::ATTR_KIND_INLINE_HINT;
case Attribute::InReg:
@@ -806,6 +841,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_SANITIZE_THREAD;
case Attribute::SanitizeMemory:
return bitc::ATTR_KIND_SANITIZE_MEMORY;
+ case Attribute::SanitizeNumericalStability:
+ return bitc::ATTR_KIND_SANITIZE_NUMERICAL_STABILITY;
case Attribute::SpeculativeLoadHardening:
return bitc::ATTR_KIND_SPECULATIVE_LOAD_HARDENING;
case Attribute::SwiftError:
@@ -844,6 +881,10 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_CORO_ONLY_DESTROY_WHEN_COMPLETE;
case Attribute::DeadOnUnwind:
return bitc::ATTR_KIND_DEAD_ON_UNWIND;
+ case Attribute::Range:
+ return bitc::ATTR_KIND_RANGE;
+ case Attribute::Initializes:
+ return bitc::ATTR_KIND_INITIALIZES;
case Attribute::EndAttrKinds:
llvm_unreachable("Can not encode end-attribute kinds marker.");
case Attribute::None:
@@ -856,6 +897,40 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
llvm_unreachable("Trying to encode unknown attribute");
}
+static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) {
+ if ((int64_t)V >= 0)
+ Vals.push_back(V << 1);
+ else
+ Vals.push_back((-V << 1) | 1);
+}
+
+static void emitWideAPInt(SmallVectorImpl<uint64_t> &Vals, const APInt &A) {
+ // We have an arbitrary precision integer value to write whose
+ // bit width is > 64. However, in canonical unsigned integer
+ // format it is likely that the high bits are going to be zero.
+ // So, we only write the number of active words.
+ unsigned NumWords = A.getActiveWords();
+ const uint64_t *RawData = A.getRawData();
+ for (unsigned i = 0; i < NumWords; i++)
+ emitSignedInt64(Vals, RawData[i]);
+}
+
+static void emitConstantRange(SmallVectorImpl<uint64_t> &Record,
+ const ConstantRange &CR, bool EmitBitWidth) {
+ unsigned BitWidth = CR.getBitWidth();
+ if (EmitBitWidth)
+ Record.push_back(BitWidth);
+ if (BitWidth > 64) {
+ Record.push_back(CR.getLower().getActiveWords() |
+ (uint64_t(CR.getUpper().getActiveWords()) << 32));
+ emitWideAPInt(Record, CR.getLower());
+ emitWideAPInt(Record, CR.getUpper());
+ } else {
+ emitSignedInt64(Record, CR.getLower().getSExtValue());
+ emitSignedInt64(Record, CR.getUpper().getSExtValue());
+ }
+}
+
void ModuleBitcodeWriter::writeAttributeGroupTable() {
const std::vector<ValueEnumerator::IndexAndAttrSet> &AttrGrps =
VE.getAttributeGroups();
@@ -889,13 +964,26 @@ void ModuleBitcodeWriter::writeAttributeGroupTable() {
Record.append(Val.begin(), Val.end());
Record.push_back(0);
}
- } else {
- assert(Attr.isTypeAttribute());
+ } else if (Attr.isTypeAttribute()) {
Type *Ty = Attr.getValueAsType();
Record.push_back(Ty ? 6 : 5);
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
if (Ty)
Record.push_back(VE.getTypeID(Attr.getValueAsType()));
+ } else if (Attr.isConstantRangeAttribute()) {
+ Record.push_back(7);
+ Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
+ emitConstantRange(Record, Attr.getValueAsConstantRange(),
+ /*EmitBitWidth=*/true);
+ } else {
+ assert(Attr.isConstantRangeListAttribute());
+ Record.push_back(8);
+ Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
+ ArrayRef<ConstantRange> Val = Attr.getValueAsConstantRangeList();
+ Record.push_back(Val.size());
+ Record.push_back(Val[0].getBitWidth());
+ for (auto &CR : Val)
+ emitConstantRange(Record, CR, /*EmitBitWidth=*/false);
}
}
@@ -934,7 +1022,7 @@ void ModuleBitcodeWriter::writeTypeTable() {
Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */);
SmallVector<uint64_t, 64> TypeVals;
- uint64_t NumBits = VE.computeBitsRequiredForTypeIndicies();
+ uint64_t NumBits = VE.computeBitsRequiredForTypeIndices();
// Abbrev for TYPE_CODE_OPAQUE_POINTER.
auto Abbv = std::make_shared<BitCodeAbbrev>();
@@ -1150,7 +1238,8 @@ static uint64_t getEncodedFFlags(FunctionSummary::FFlags Flags) {
// Decode the flags for GlobalValue in the summary. See getDecodedGVSummaryFlags
// in BitcodeReader.cpp.
-static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
+static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags,
+ bool ImportAsDecl = false) {
uint64_t RawFlags = 0;
RawFlags |= Flags.NotEligibleToImport; // bool
@@ -1165,6 +1254,9 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
RawFlags |= (Flags.Visibility << 8); // 2 bits
+ unsigned ImportType = Flags.ImportType | ImportAsDecl;
+ RawFlags |= (ImportType << 10); // 1 bit
+
return RawFlags;
}
@@ -1597,6 +1689,18 @@ static uint64_t getOptimizationFlags(const Value *V) {
} else if (const auto *NNI = dyn_cast<PossiblyNonNegInst>(V)) {
if (NNI->hasNonNeg())
Flags |= 1 << bitc::PNNI_NON_NEG;
+ } else if (const auto *TI = dyn_cast<TruncInst>(V)) {
+ if (TI->hasNoSignedWrap())
+ Flags |= 1 << bitc::TIO_NO_SIGNED_WRAP;
+ if (TI->hasNoUnsignedWrap())
+ Flags |= 1 << bitc::TIO_NO_UNSIGNED_WRAP;
+ } else if (const auto *GEP = dyn_cast<GEPOperator>(V)) {
+ if (GEP->isInBounds())
+ Flags |= 1 << bitc::GEP_INBOUNDS;
+ if (GEP->hasNoUnsignedSignedWrap())
+ Flags |= 1 << bitc::GEP_NUSW;
+ if (GEP->hasNoUnsignedWrap())
+ Flags |= 1 << bitc::GEP_NUW;
}
return Flags;
@@ -1615,8 +1719,8 @@ void ModuleBitcodeWriter::writeValueAsMetadata(
void ModuleBitcodeWriter::writeMDTuple(const MDTuple *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- Metadata *MD = N->getOperand(i);
+ for (const MDOperand &MDO : N->operands()) {
+ Metadata *MD = MDO;
assert(!(MD && isa<LocalAsMetadata>(MD)) &&
"Unexpected function-local metadata");
Record.push_back(VE.getMetadataOrNullID(MD));
@@ -1716,24 +1820,6 @@ void ModuleBitcodeWriter::writeDIGenericSubrange(
Record.clear();
}
-static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) {
- if ((int64_t)V >= 0)
- Vals.push_back(V << 1);
- else
- Vals.push_back((-V << 1) | 1);
-}
-
-static void emitWideAPInt(SmallVectorImpl<uint64_t> &Vals, const APInt &A) {
- // We have an arbitrary precision integer value to write whose
- // bit width is > 64. However, in canonical unsigned integer
- // format it is likely that the high bits are going to be zero.
- // So, we only write the number of active words.
- unsigned NumWords = A.getActiveWords();
- const uint64_t *RawData = A.getRawData();
- for (unsigned i = 0; i < NumWords; i++)
- emitSignedInt64(Vals, RawData[i]);
-}
-
void ModuleBitcodeWriter::writeDIEnumerator(const DIEnumerator *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
@@ -1804,6 +1890,11 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get()));
+ if (auto PtrAuthData = N->getPtrAuthData())
+ Record.push_back(PtrAuthData->RawData);
+ else
+ Record.push_back(0);
+
Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev);
Record.clear();
}
@@ -2624,7 +2715,7 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
}
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
Code = bitc::CST_CODE_FLOAT;
- Type *Ty = CFP->getType();
+ Type *Ty = CFP->getType()->getScalarType();
if (Ty->isHalfTy() || Ty->isBFloatTy() || Ty->isFloatTy() ||
Ty->isDoubleTy()) {
Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
@@ -2721,11 +2812,11 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
Code = bitc::CST_CODE_CE_GEP;
const auto *GO = cast<GEPOperator>(C);
Record.push_back(VE.getTypeID(GO->getSourceElementType()));
- if (std::optional<unsigned> Idx = GO->getInRangeIndex()) {
- Code = bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX;
- Record.push_back((*Idx << 1) | GO->isInBounds());
- } else if (GO->isInBounds())
- Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
+ Record.push_back(getOptimizationFlags(GO));
+ if (std::optional<ConstantRange> Range = GO->getInRange()) {
+ Code = bitc::CST_CODE_CE_GEP_WITH_INRANGE;
+ emitConstantRange(Record, *Range, /*EmitBitWidth=*/true);
+ }
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
Record.push_back(VE.getValueID(C->getOperand(i)));
@@ -2761,14 +2852,6 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
Record.push_back(VE.getValueID(C->getOperand(1)));
Record.push_back(VE.getValueID(CE->getShuffleMaskForBitcode()));
break;
- case Instruction::ICmp:
- case Instruction::FCmp:
- Code = bitc::CST_CODE_CE_CMP;
- Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
- Record.push_back(VE.getValueID(C->getOperand(0)));
- Record.push_back(VE.getValueID(C->getOperand(1)));
- Record.push_back(CE->getPredicate());
- break;
}
} else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
Code = bitc::CST_CODE_BLOCKADDRESS;
@@ -2783,6 +2866,12 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
Code = bitc::CST_CODE_NO_CFI_VALUE;
Record.push_back(VE.getTypeID(NC->getGlobalValue()->getType()));
Record.push_back(VE.getValueID(NC->getGlobalValue()));
+ } else if (const auto *CPA = dyn_cast<ConstantPtrAuth>(C)) {
+ Code = bitc::CST_CODE_PTRAUTH;
+ Record.push_back(VE.getValueID(CPA->getPointer()));
+ Record.push_back(VE.getValueID(CPA->getKey()));
+ Record.push_back(VE.getValueID(CPA->getDiscriminator()));
+ Record.push_back(VE.getValueID(CPA->getAddrDiscriminator()));
} else {
#ifndef NDEBUG
C->dump();
@@ -2914,7 +3003,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
Code = bitc::FUNC_CODE_INST_GEP;
AbbrevToUse = FUNCTION_INST_GEP_ABBREV;
auto &GEPInst = cast<GetElementPtrInst>(I);
- Vals.push_back(GEPInst.isInBounds());
+ Vals.push_back(getOptimizationFlags(&I));
Vals.push_back(VE.getTypeID(GEPInst.getSourceElementType()));
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
pushValueAndType(I.getOperand(i), InstID, Vals);
@@ -3491,25 +3580,96 @@ void ModuleBitcodeWriter::writeFunction(
NeedsMetadataAttachment |= I.hasMetadataOtherThanDebugLoc();
// If the instruction has a debug location, emit it.
- DILocation *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);
- continue;
+ if (DILocation *DL = I.getDebugLoc()) {
+ if (DL == LastDL) {
+ // Just repeat the same debug loc as last time.
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
+ } else {
+ Vals.push_back(DL->getLine());
+ Vals.push_back(DL->getColumn());
+ Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
+ Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
+ Vals.push_back(DL->isImplicitCode());
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
+ Vals.clear();
+ LastDL = DL;
+ }
}
- Vals.push_back(DL->getLine());
- Vals.push_back(DL->getColumn());
- Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
- Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
- Vals.push_back(DL->isImplicitCode());
- Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
- Vals.clear();
-
- LastDL = DL;
+ // If the instruction has DbgRecords attached to it, emit them. Note that
+ // they come after the instruction so that it's easy to attach them again
+ // when reading the bitcode, even though conceptually the debug locations
+ // start "before" the instruction.
+ if (I.hasDbgRecords() && WriteNewDbgInfoFormatToBitcode) {
+ /// Try to push the value only (unwrapped), otherwise push the
+ /// metadata wrapped value. Returns true if the value was pushed
+ /// without the ValueAsMetadata wrapper.
+ auto PushValueOrMetadata = [&Vals, InstID,
+ this](Metadata *RawLocation) {
+ assert(RawLocation &&
+ "RawLocation unexpectedly null in DbgVariableRecord");
+ if (ValueAsMetadata *VAM = dyn_cast<ValueAsMetadata>(RawLocation)) {
+ SmallVector<unsigned, 2> ValAndType;
+ // If the value is a fwd-ref the type is also pushed. We don't
+ // want the type, so fwd-refs are kept wrapped (pushValueAndType
+ // returns false if the value is pushed without type).
+ if (!pushValueAndType(VAM->getValue(), InstID, ValAndType)) {
+ Vals.push_back(ValAndType[0]);
+ return true;
+ }
+ }
+ // The metadata is a DIArgList, or ValueAsMetadata wrapping a
+ // fwd-ref. Push the metadata ID.
+ Vals.push_back(VE.getMetadataID(RawLocation));
+ return false;
+ };
+
+ // Write out non-instruction debug information attached to this
+ // instruction. Write it after the instruction so that it's easy to
+ // re-attach to the instruction reading the records in.
+ for (DbgRecord &DR : I.DebugMarker->getDbgRecordRange()) {
+ if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) {
+ Vals.push_back(VE.getMetadataID(&*DLR->getDebugLoc()));
+ Vals.push_back(VE.getMetadataID(DLR->getLabel()));
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_LABEL, Vals);
+ Vals.clear();
+ continue;
+ }
+
+ // First 3 fields are common to all kinds:
+ // DILocation, DILocalVariable, DIExpression
+ // dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE)
+ // ..., LocationMetadata
+ // dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE - abbrev'd)
+ // ..., Value
+ // dbg_declare (FUNC_CODE_DEBUG_RECORD_DECLARE)
+ // ..., LocationMetadata
+ // dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN)
+ // ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata
+ DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR);
+ Vals.push_back(VE.getMetadataID(&*DVR.getDebugLoc()));
+ Vals.push_back(VE.getMetadataID(DVR.getVariable()));
+ Vals.push_back(VE.getMetadataID(DVR.getExpression()));
+ if (DVR.isDbgValue()) {
+ if (PushValueOrMetadata(DVR.getRawLocation()))
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE, Vals,
+ FUNCTION_DEBUG_RECORD_VALUE_ABBREV);
+ else
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE, Vals);
+ } else if (DVR.isDbgDeclare()) {
+ Vals.push_back(VE.getMetadataID(DVR.getRawLocation()));
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_DECLARE, Vals);
+ } else {
+ assert(DVR.isDbgAssign() && "Unexpected DbgRecord kind");
+ Vals.push_back(VE.getMetadataID(DVR.getRawLocation()));
+ Vals.push_back(VE.getMetadataID(DVR.getAssignID()));
+ Vals.push_back(VE.getMetadataID(DVR.getAddressExpression()));
+ Vals.push_back(VE.getMetadataID(DVR.getRawAddress()));
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN, Vals);
+ }
+ Vals.clear();
+ }
+ }
}
if (BlockAddress *BA = BlockAddress::lookup(&BB)) {
@@ -3603,7 +3763,7 @@ void ModuleBitcodeWriter::writeBlockInfo() {
auto Abbv = std::make_shared<BitCodeAbbrev>();
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- VE.computeBitsRequiredForTypeIndicies()));
+ VE.computeBitsRequiredForTypeIndices()));
if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, Abbv) !=
CONSTANTS_SETTYPE_ABBREV)
llvm_unreachable("Unexpected abbrev ordering!");
@@ -3623,7 +3783,7 @@ void ModuleBitcodeWriter::writeBlockInfo() {
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CE_CAST));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // cast opc
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // typeid
- VE.computeBitsRequiredForTypeIndicies()));
+ VE.computeBitsRequiredForTypeIndices()));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id
if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, Abbv) !=
@@ -3645,7 +3805,7 @@ void ModuleBitcodeWriter::writeBlockInfo() {
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
- VE.computeBitsRequiredForTypeIndicies()));
+ VE.computeBitsRequiredForTypeIndices()));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
@@ -3697,7 +3857,7 @@ void ModuleBitcodeWriter::writeBlockInfo() {
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpVal
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
- VE.computeBitsRequiredForTypeIndicies()));
+ VE.computeBitsRequiredForTypeIndices()));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
FUNCTION_INST_CAST_ABBREV)
@@ -3708,7 +3868,7 @@ void ModuleBitcodeWriter::writeBlockInfo() {
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpVal
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
- VE.computeBitsRequiredForTypeIndicies()));
+ VE.computeBitsRequiredForTypeIndices()));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); // flags
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
@@ -3741,7 +3901,7 @@ void ModuleBitcodeWriter::writeBlockInfo() {
{
auto Abbv = std::make_shared<BitCodeAbbrev>();
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_GEP));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
Log2_32_Ceil(VE.getTypes().size() + 1)));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
@@ -3750,7 +3910,17 @@ void ModuleBitcodeWriter::writeBlockInfo() {
FUNCTION_INST_GEP_ABBREV)
llvm_unreachable("Unexpected abbrev ordering!");
}
-
+ {
+ auto Abbv = std::make_shared<BitCodeAbbrev>();
+ Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // dbgloc
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // var
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // expr
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // val
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
+ FUNCTION_DEBUG_RECORD_VALUE_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering! 1");
+ }
Stream.ExitBlock();
}
@@ -4021,10 +4191,9 @@ static void writeFunctionHeapProfileRecords(
// Per module alloc versions should always have a single entry of
// value 0.
assert(!PerModule || (AI.Versions.size() == 1 && AI.Versions[0] == 0));
- if (!PerModule) {
- Record.push_back(AI.MIBs.size());
+ Record.push_back(AI.MIBs.size());
+ if (!PerModule)
Record.push_back(AI.Versions.size());
- }
for (auto &MIB : AI.MIBs) {
Record.push_back((uint8_t)MIB.AllocType);
Record.push_back(MIB.StackIdIndices.size());
@@ -4035,6 +4204,11 @@ static void writeFunctionHeapProfileRecords(
for (auto V : AI.Versions)
Record.push_back(V);
}
+ assert(AI.TotalSizes.empty() || AI.TotalSizes.size() == AI.MIBs.size());
+ if (!AI.TotalSizes.empty()) {
+ for (auto Size : AI.TotalSizes)
+ Record.push_back(Size);
+ }
Stream.EmitRecord(PerModule ? bitc::FS_PERMODULE_ALLOC_INFO
: bitc::FS_COMBINED_ALLOC_INFO,
Record, AllocAbbrev);
@@ -4071,7 +4245,7 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(
NameVals.push_back(SpecialRefCnts.second); // worefcnt
for (auto &RI : FS->refs())
- NameVals.push_back(VE.getValueID(RI.getValue()));
+ NameVals.push_back(getValueId(RI));
const bool UseRelBFRecord =
WriteRelBFToSummary && !F.hasProfileData() &&
@@ -4264,7 +4438,9 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {
Abbv = std::make_shared<BitCodeAbbrev>();
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_ALLOC_INFO));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // nummib
// n x (alloc type, numstackids, numstackids x stackidindex)
+ // optional: nummib x total size
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv));
@@ -4344,18 +4520,15 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
ArrayRef<uint64_t>{GVI.second, GVI.first});
}
- if (!StackIdIndices.empty()) {
+ // Write the stack ids used by this index, which will be a subset of those in
+ // the full index in the case of distributed indexes.
+ if (!StackIds.empty()) {
auto StackIdAbbv = std::make_shared<BitCodeAbbrev>();
StackIdAbbv->Add(BitCodeAbbrevOp(bitc::FS_STACK_IDS));
// numids x stackid
StackIdAbbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
StackIdAbbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned StackIdAbbvId = Stream.EmitAbbrev(std::move(StackIdAbbv));
- // Write the stack ids used by this index, which will be a subset of those in
- // the full index in the case of distributed indexes.
- std::vector<uint64_t> StackIds;
- for (auto &I : StackIdIndices)
- StackIds.push_back(Index.getStackIdAtIndex(I));
Stream.EmitRecord(bitc::FS_STACK_IDS, StackIds, StackIdAbbvId);
}
@@ -4411,10 +4584,17 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numver
// nummib x (alloc type, numstackids, numstackids x stackidindex),
// numver x version
+ // optional: nummib x total size
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv));
+ auto shouldImportValueAsDecl = [&](GlobalValueSummary *GVS) -> bool {
+ if (DecSummaries == nullptr)
+ return false;
+ return DecSummaries->count(GVS);
+ };
+
// The aliases are emitted as a post-pass, and will point to the value
// id of the aliasee. Save them in a vector for post-processing.
SmallVector<AliasSummary *, 64> Aliases;
@@ -4504,7 +4684,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
writeFunctionHeapProfileRecords(
Stream, FS, CallsiteAbbrev, AllocAbbrev,
/*PerModule*/ false,
- /*GetValueId*/ [&](const ValueInfo &VI) -> unsigned {
+ /*GetValueId*/
+ [&](const ValueInfo &VI) -> unsigned {
std::optional<unsigned> ValueID = GetValueId(VI);
// This can happen in shared index files for distributed ThinLTO if
// the callee function summary is not included. Record 0 which we
@@ -4514,18 +4695,20 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
return 0;
return *ValueID;
},
- /*GetStackIndex*/ [&](unsigned I) {
- // Get the corresponding index into the list of StackIdIndices
- // actually being written for this combined index (which may be a
- // subset in the case of distributed indexes).
- auto Lower = llvm::lower_bound(StackIdIndices, I);
- return std::distance(StackIdIndices.begin(), Lower);
+ /*GetStackIndex*/
+ [&](unsigned I) {
+ // Get the corresponding index into the list of StackIds actually
+ // being written for this combined index (which may be a subset in
+ // the case of distributed indexes).
+ assert(StackIdIndicesToIndex.contains(I));
+ return StackIdIndicesToIndex[I];
});
NameVals.push_back(*ValueId);
assert(ModuleIdMap.count(FS->modulePath()));
NameVals.push_back(ModuleIdMap[FS->modulePath()]);
- NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
+ NameVals.push_back(
+ getEncodedGVSummaryFlags(FS->flags(), shouldImportValueAsDecl(FS)));
NameVals.push_back(FS->instCount());
NameVals.push_back(getEncodedFFlags(FS->fflags()));
NameVals.push_back(FS->entryCount());
@@ -4574,7 +4757,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
NameVals.push_back(AliasValueId);
assert(ModuleIdMap.count(AS->modulePath()));
NameVals.push_back(ModuleIdMap[AS->modulePath()]);
- NameVals.push_back(getEncodedGVSummaryFlags(AS->flags()));
+ NameVals.push_back(
+ getEncodedGVSummaryFlags(AS->flags(), shouldImportValueAsDecl(AS)));
auto AliaseeValueId = SummaryToValueIdMap[&AS->getAliasee()];
assert(AliaseeValueId);
NameVals.push_back(AliaseeValueId);
@@ -4659,13 +4843,13 @@ static void writeIdentificationBlock(BitstreamWriter &Stream) {
Stream.ExitBlock();
}
-void ModuleBitcodeWriter::writeModuleHash(size_t BlockStartPos) {
+void ModuleBitcodeWriter::writeModuleHash(StringRef View) {
// Emit the module's hash.
// MODULE_CODE_HASH: [5*i32]
if (GenerateHash) {
uint32_t Vals[5];
- Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&(Buffer)[BlockStartPos],
- Buffer.size() - BlockStartPos));
+ Hasher.update(ArrayRef<uint8_t>(
+ reinterpret_cast<const uint8_t *>(View.data()), View.size()));
std::array<uint8_t, 20> Hash = Hasher.result();
for (int Pos = 0; Pos < 20; Pos += 4) {
Vals[Pos / 4] = support::endian::read32be(Hash.data() + Pos);
@@ -4684,7 +4868,9 @@ void ModuleBitcodeWriter::write() {
writeIdentificationBlock(Stream);
Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
- size_t BlockStartPos = Buffer.size();
+ // We will want to write the module hash at this point. Block any flushing so
+ // we can have access to the whole underlying data later.
+ Stream.markAndBlockFlushing();
writeModuleVersion();
@@ -4735,7 +4921,7 @@ void ModuleBitcodeWriter::write() {
writeGlobalValueSymbolTable(FunctionToBitcodeIndex);
- writeModuleHash(BlockStartPos);
+ writeModuleHash(Stream.getMarkedBufferAndResumeFlushing());
Stream.ExitBlock();
}
@@ -4816,8 +5002,13 @@ static void writeBitcodeHeader(BitstreamWriter &Stream) {
Stream.Emit(0xD, 4);
}
-BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer, raw_fd_stream *FS)
- : Buffer(Buffer), Stream(new BitstreamWriter(Buffer, FS, FlushThreshold)) {
+BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer)
+ : Stream(new BitstreamWriter(Buffer)) {
+ writeBitcodeHeader(*Stream);
+}
+
+BitcodeWriter::BitcodeWriter(raw_ostream &FS)
+ : Stream(new BitstreamWriter(FS, FlushThreshold)) {
writeBitcodeHeader(*Stream);
}
@@ -4900,7 +5091,7 @@ void BitcodeWriter::writeModule(const Module &M,
assert(M.isMaterialized());
Mods.push_back(const_cast<Module *>(&M));
- ModuleBitcodeWriter ModuleWriter(M, Buffer, StrtabBuilder, *Stream,
+ ModuleBitcodeWriter ModuleWriter(M, StrtabBuilder, *Stream,
ShouldPreserveUseListOrder, Index,
GenerateHash, ModHash);
ModuleWriter.write();
@@ -4908,8 +5099,9 @@ void BitcodeWriter::writeModule(const Module &M,
void BitcodeWriter::writeIndex(
const ModuleSummaryIndex *Index,
- const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex) {
- IndexBitcodeWriter IndexWriter(*Stream, StrtabBuilder, *Index,
+ const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
+ const GVSummaryPtrSet *DecSummaries) {
+ IndexBitcodeWriter IndexWriter(*Stream, StrtabBuilder, *Index, DecSummaries,
ModuleToSummariesForIndex);
IndexWriter.write();
}
@@ -4919,27 +5111,29 @@ void llvm::WriteBitcodeToFile(const Module &M, raw_ostream &Out,
bool ShouldPreserveUseListOrder,
const ModuleSummaryIndex *Index,
bool GenerateHash, ModuleHash *ModHash) {
- SmallVector<char, 0> Buffer;
- Buffer.reserve(256*1024);
-
- // If this is darwin or another generic macho target, reserve space for the
- // header.
+ auto Write = [&](BitcodeWriter &Writer) {
+ Writer.writeModule(M, ShouldPreserveUseListOrder, Index, GenerateHash,
+ ModHash);
+ Writer.writeSymtab();
+ Writer.writeStrtab();
+ };
Triple TT(M.getTargetTriple());
- if (TT.isOSDarwin() || TT.isOSBinFormatMachO())
+ if (TT.isOSDarwin() || TT.isOSBinFormatMachO()) {
+ // If this is darwin or another generic macho target, reserve space for the
+ // header. Note that the header is computed *after* the output is known, so
+ // we currently explicitly use a buffer, write to it, and then subsequently
+ // flush to Out.
+ SmallVector<char, 0> Buffer;
+ Buffer.reserve(256 * 1024);
Buffer.insert(Buffer.begin(), BWH_HeaderSize, 0);
-
- BitcodeWriter Writer(Buffer, dyn_cast<raw_fd_stream>(&Out));
- Writer.writeModule(M, ShouldPreserveUseListOrder, Index, GenerateHash,
- ModHash);
- Writer.writeSymtab();
- Writer.writeStrtab();
-
- if (TT.isOSDarwin() || TT.isOSBinFormatMachO())
+ BitcodeWriter Writer(Buffer);
+ Write(Writer);
emitDarwinBCHeaderAndTrailer(Buffer, TT);
-
- // Write the generated bitstream to "Out".
- if (!Buffer.empty())
- Out.write((char *)&Buffer.front(), Buffer.size());
+ Out.write(Buffer.data(), Buffer.size());
+ } else {
+ BitcodeWriter Writer(Out);
+ Write(Writer);
+ }
}
void IndexBitcodeWriter::write() {
@@ -4962,12 +5156,13 @@ void IndexBitcodeWriter::write() {
// index for a distributed backend, provide a \p ModuleToSummariesForIndex map.
void llvm::writeIndexToFile(
const ModuleSummaryIndex &Index, raw_ostream &Out,
- const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex) {
+ const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
+ const GVSummaryPtrSet *DecSummaries) {
SmallVector<char, 0> Buffer;
Buffer.reserve(256 * 1024);
BitcodeWriter Writer(Buffer);
- Writer.writeIndex(&Index, ModuleToSummariesForIndex);
+ Writer.writeIndex(&Index, ModuleToSummariesForIndex, DecSummaries);
Writer.writeStrtab();
Out.write((char *)&Buffer.front(), Buffer.size());
@@ -5147,6 +5342,8 @@ static const char *getSectionNameForBitcode(const Triple &T) {
llvm_unreachable("GOFF is not yet implemented");
break;
case Triple::SPIRV:
+ if (T.getVendor() == Triple::AMD)
+ return ".llvmbc";
llvm_unreachable("SPIRV is not yet implemented");
break;
case Triple::XCOFF:
@@ -5172,6 +5369,8 @@ static const char *getSectionNameForCommandline(const Triple &T) {
llvm_unreachable("GOFF is not yet implemented");
break;
case Triple::SPIRV:
+ if (T.getVendor() == Triple::AMD)
+ return ".llvmcmd";
llvm_unreachable("SPIRV is not yet implemented");
break;
case Triple::XCOFF: