38 unsigned Idx = FileNumber - 1;
40 return Files[
Idx].Assigned;
50 Filename = FilenameOffset.first;
51 unsigned Idx = FileNumber - 1;
58 if (Files[
Idx].Assigned)
62 Filename = FilenameOffset.first;
63 unsigned Offset = FilenameOffset.second;
65 auto ChecksumOffsetSymbol =
66 OS.getContext().createTempSymbol(
"checksum_offset",
false);
68 Files[
Idx].ChecksumTableOffset = ChecksumOffsetSymbol;
69 Files[
Idx].Assigned =
true;
70 Files[
Idx].Checksum = ChecksumBytes;
71 Files[
Idx].ChecksumKind = ChecksumKind;
77 if (
FuncId >= Functions.size())
79 if (Functions[
FuncId].isUnallocatedFunctionInfo())
85 if (
FuncId >= Functions.size())
86 Functions.resize(
FuncId + 1);
89 if (!Functions[
FuncId].isUnallocatedFunctionInfo())
98 unsigned IAFile,
unsigned IALine,
100 if (
FuncId >= Functions.size())
101 Functions.resize(
FuncId + 1);
104 if (!Functions[
FuncId].isUnallocatedFunctionInfo())
108 InlinedAt.
File = IAFile;
109 InlinedAt.
Line = IALine;
110 InlinedAt.
Col = IACol;
114 Info->ParentFuncIdPlusOne = IAFunc + 1;
115 Info->InlinedAt = InlinedAt;
119 while (
Info->isInlinedCallSite()) {
120 InlinedAt =
Info->InlinedAt;
130 unsigned Line,
unsigned Column,
131 bool PrologueEnd,
bool IsStmt) {
140 std::pair<StringRef, unsigned> Ret =
141 std::make_pair(Insertion.first->first(), Insertion.first->second);
142 if (Insertion.second) {
144 StrTab.
append(Ret.first.begin(), Ret.first.end() + 1);
149unsigned CodeViewContext::getStringTableOffset(
StringRef S) {
163 OS.emitInt32(
uint32_t(DebugSubsectionKind::StringTable));
164 OS.emitAbsoluteSymbolDiff(StringEnd, StringBegin, 4);
165 OS.emitLabel(StringBegin);
170 if (!StrTabFragment) {
172 StrTabFragment =
OS.getCurrentFragment();
176 OS.emitValueToAlignment(
Align(4), 0);
178 OS.emitLabel(StringEnd);
191 OS.emitInt32(
uint32_t(DebugSubsectionKind::FileChecksums));
192 OS.emitAbsoluteSymbolDiff(FileEnd, FileBegin, 4);
193 OS.emitLabel(FileBegin);
195 unsigned CurrentOffset = 0;
200 for (
auto File : Files) {
201 OS.emitAssignment(File.ChecksumTableOffset,
204 if (!File.ChecksumKind) {
209 CurrentOffset += File.Checksum.size();
210 CurrentOffset =
alignTo(CurrentOffset, 4);
213 OS.emitInt32(File.StringTableOffset);
215 if (!File.ChecksumKind) {
221 OS.emitInt8(
static_cast<uint8_t>(File.Checksum.size()));
222 OS.emitInt8(File.ChecksumKind);
223 OS.emitBytes(toStringRef(File.Checksum));
224 OS.emitValueToAlignment(
Align(4));
227 OS.emitLabel(FileEnd);
229 ChecksumOffsetsAssigned =
true;
238 unsigned Idx = FileNo - 1;
243 if (ChecksumOffsetsAssigned) {
244 OS.emitSymbolValue(Files[
Idx].ChecksumTableOffset, 4);
251 OS.emitValueImpl(SRE, 4);
255 size_t Offset = MCCVLines.size();
256 auto I = MCCVLineStartStop.insert(
259 I.first->second.second =
Offset + 1;
260 MCCVLines.push_back(LineEntry);
265 std::vector<MCCVLoc> FilteredLines;
269 if (LocBegin >= LocEnd) {
270 return FilteredLines;
274 for (
size_t Idx = LocBegin;
Idx != LocEnd; ++
Idx) {
275 unsigned LocationFuncId = MCCVLines[
Idx].getFunctionId();
276 if (LocationFuncId ==
FuncId) {
278 FilteredLines.push_back(MCCVLines[
Idx]);
288 if (FilteredLines.empty() ||
289 FilteredLines.back().getFileNum() != IA.File ||
290 FilteredLines.back().getLine() != IA.Line ||
291 FilteredLines.back().getColumn() != IA.Col) {
293 IA.File, IA.Line, IA.Col,
false,
299 return FilteredLines;
303 auto I = MCCVLineStartStop.find(
FuncId);
305 if (
I == MCCVLineStartStop.end())
310std::pair<size_t, size_t>
320 unsigned ChildId = KV.first;
322 LocBegin = std::min(LocBegin, Extent.first);
323 LocEnd = std::max(LocEnd, Extent.second);
327 return {LocBegin, LocEnd};
333 if (L >= MCCVLines.size())
335 return ArrayRef(&MCCVLines[L], R - L);
346 OS.emitInt32(
uint32_t(DebugSubsectionKind::Lines));
347 OS.emitAbsoluteSymbolDiff(LineEnd, LineBegin, 4);
348 OS.emitLabel(LineBegin);
349 OS.emitCOFFSecRel32(FuncBegin, 0);
350 OS.emitCOFFSectionIndex(FuncBegin);
354 bool HaveColumns =
any_of(Locs, [](
const MCCVLoc &LineEntry) {
358 OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 4);
360 for (
auto I = Locs.begin(), E = Locs.end();
I != E;) {
362 unsigned CurFileNum =
I->getFileNum();
364 std::find_if(
I, E, [CurFileNum](
const MCCVLoc &Loc) {
367 unsigned EntryCount = FileSegEnd -
I;
368 OS.AddComment(
"Segment for file '" +
369 Twine(StrTab[Files[CurFileNum - 1].StringTableOffset]) +
371 OS.emitCVFileChecksumOffsetDirective(CurFileNum);
372 OS.emitInt32(EntryCount);
374 SegmentSize += 8 * EntryCount;
376 SegmentSize += 4 * EntryCount;
377 OS.emitInt32(SegmentSize);
379 for (
auto J =
I; J != FileSegEnd; ++J) {
380 OS.emitAbsoluteSymbolDiff(J->getLabel(), FuncBegin, 4);
381 unsigned LineData = J->getLine();
383 LineData |= LineInfo::StatementFlag;
384 OS.emitInt32(LineData);
387 for (
auto J =
I; J != FileSegEnd; ++J) {
388 OS.emitInt16(J->getColumn());
394 OS.emitLabel(LineEnd);
398 if (isUInt<7>(
Data)) {
403 if (isUInt<14>(
Data)) {
409 if (isUInt<29>(
Data)) {
427 return ((-
Data) << 1) | 1;
432 unsigned PrimaryFunctionId,
433 unsigned SourceFileId,
434 unsigned SourceLineNum,
440 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
445 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
450 auto &
Saved = DefRangeStorage.emplace_back(Ranges.begin(), Ranges.end());
465 assert(
Success &&
"failed to evaluate label difference as absolute");
467 assert(Result >= 0 &&
"negative label difference requested");
468 assert(Result < UINT_MAX &&
"label difference greater than 2GB");
478 if (LocBegin >= LocEnd)
486 const MCSection *FirstSec = &Locs.
front().getLabel()->getSection();
487 for (
const MCCVLoc &Loc : Locs) {
488 if (&Loc.getLabel()->getSection() != FirstSec) {
489 errs() <<
".cv_loc " << Loc.getFunctionId() <<
' ' << Loc.getFileNum()
490 <<
' ' << Loc.getLine() <<
' ' << Loc.getColumn()
491 <<
" is in the wrong section\n";
503 StartLoc.
setLine(Frag.StartLineNum);
504 bool HaveOpenRange =
false;
508 LastSourceLoc.
File = Frag.StartFileId;
509 LastSourceLoc.
Line = Frag.StartLineNum;
514 for (
const MCCVLoc &Loc : Locs) {
518 constexpr uint32_t InlineSiteSize = 12;
519 constexpr uint32_t AnnotationSize = 8;
520 size_t MaxBufferSize =
MaxRecordLength - InlineSiteSize - AnnotationSize;
521 if (Buffer.
size() >= MaxBufferSize)
524 if (Loc.getFunctionId() == Frag.SiteFuncId) {
525 CurSourceLoc.
File = Loc.getFileNum();
526 CurSourceLoc.
Line = Loc.getLine();
533 CurSourceLoc =
I->second;
541 LastLabel = Loc.getLabel();
543 HaveOpenRange =
false;
551 if (HaveOpenRange && CurSourceLoc.
File == LastSourceLoc.
File &&
552 CurSourceLoc.
Line == LastSourceLoc.
Line)
555 HaveOpenRange =
true;
557 if (CurSourceLoc.
File != LastSourceLoc.
File) {
559 Files[CurSourceLoc.
File - 1]
560 .ChecksumTableOffset->getVariableValue())
566 int LineDelta = CurSourceLoc.
Line - LastSourceLoc.
Line;
569 if (EncodedLineDelta < 0x8 && CodeDelta <= 0xf) {
573 unsigned Operand = (EncodedLineDelta << 4) | CodeDelta;
579 if (LineDelta != 0) {
587 LastLabel = Loc.getLabel();
588 LastSourceLoc = CurSourceLoc;
593 unsigned EndSymLength =
595 unsigned LocAfterLength = ~0U;
597 if (!LocAfter.
empty()) {
599 const MCCVLoc &Loc = LocAfter[0];
618 const MCSymbol *LastLabel =
nullptr;
619 for (std::pair<const MCSymbol *, const MCSymbol *>
Range : Frag.
getRanges()) {
623 GapAndRangeSizes.
push_back({GapSize, RangeSize});
624 LastLabel =
Range.second;
628 for (
size_t I = 0, E = Frag.
getRanges().size();
I != E;) {
632 unsigned RangeSize = GapAndRangeSizes[
I].second;
634 for (; J != E; ++J) {
635 unsigned GapAndRangeSize = GapAndRangeSizes[J].first + GapAndRangeSizes[J].second;
638 RangeSize += GapAndRangeSize;
640 unsigned NumGaps = J -
I - 1;
659 size_t RecordSize = FixedSizePortion.
size() +
664 OS << FixedSizePortion;
678 }
while (RangeSize > 0);
682 "large ranges should not have gaps");
683 unsigned GapStartOffset = GapAndRangeSizes[
I].second;
684 for (++
I;
I != J; ++
I) {
685 unsigned GapSize, RangeSize;
687 std::tie(GapSize, RangeSize) = GapAndRangeSizes[
I];
690 GapStartOffset += GapSize + RangeSize;
695 assert(Fixups.size() < 256 &&
"Store fixups outside of MCFragment's VarFixup "
696 "storage if the number ever exceeds 256");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Fixup Statepoint Caller Saved
static unsigned computeLabelDiff(const MCAssembler &Asm, const MCSymbol *Begin, const MCSymbol *End)
static uint32_t encodeSignedNumber(uint32_t Data)
static bool compressAnnotation(uint32_t Data, SmallVectorImpl< char > &Buffer)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
bool empty() const
empty - Check if the array is empty.
ArrayRef< MCCVLoc > getLinesForExtent(size_t L, size_t R)
std::pair< size_t, size_t > getLineExtent(unsigned FuncId)
void encodeInlineLineTable(const MCAssembler &Asm, MCCVInlineLineTableFragment &F)
Encodes the binary annotations once we have a layout.
void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId, const MCSymbol *FuncBegin, const MCSymbol *FuncEnd)
Emits a line table substream.
void emitFileChecksums(MCObjectStreamer &OS)
Emits the file checksum substream.
void recordCVLoc(MCContext &Ctx, const MCSymbol *Label, unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt)
Saves the information from the currently parsed .cv_loc directive and sets CVLocSeen.
void emitDefRange(MCObjectStreamer &OS, ArrayRef< std::pair< const MCSymbol *, const MCSymbol * > > Ranges, StringRef FixedSizePortion)
bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename, ArrayRef< uint8_t > ChecksumBytes, uint8_t ChecksumKind)
MCCVFunctionInfo * getCVFunctionInfo(unsigned FuncId)
Retreive the function info if this is a valid function id, or nullptr.
bool recordFunctionId(unsigned FuncId)
Records the function id of a normal function.
void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo)
Emits the offset into the checksum table of the given file number.
std::vector< MCCVLoc > getFunctionLineEntries(unsigned FuncId)
void addLineEntry(const MCCVLoc &LineEntry)
Add a line entry.
bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol)
Records the function id of an inlined call site.
std::pair< size_t, size_t > getLineExtentIncludingInlinees(unsigned FuncId)
void emitInlineLineTableForFunction(MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
void emitStringTable(MCObjectStreamer &OS)
Emits the string table substream.
bool isValidFileNumber(unsigned FileNumber) const
This is a valid number for use with .cv_loc if we've already seen a .cv_file for it.
void encodeDefRange(const MCAssembler &Asm, MCCVDefRangeFragment &F)
std::pair< StringRef, unsigned > addToStringTable(StringRef S)
Add something to the string table.
Binary assembler expressions.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Fragment representing the .cv_def_range directive.
ArrayRef< std::pair< const MCSymbol *, const MCSymbol * > > getRanges() const
StringRef getFixedSizePortion() const
Fragment representing the binary annotations produced by the .cv_inline_linetable directive.
const MCSymbol * getFnStartSym() const
const MCSymbol * getFnEndSym() const
Instances of this class represent the information from a .cv_loc directive.
void setFileNum(unsigned fileNum)
Set the FileNum of this MCCVLoc.
unsigned getFileNum() const
Get the FileNum of this MCCVLoc.
const MCSymbol * getLabel() const
void setLabel(const MCSymbol *L)
unsigned getColumn() const
Get the Column of this MCCVLoc.
unsigned getFunctionId() const
void setLine(unsigned line)
Set the Line of this MCCVLoc.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
StringRef allocateString(StringRef s)
Allocates a copy of the given string on the allocator managed by this context and returns the result.
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateKnownAbsolute(int64_t &Res, const MCAssembler &Asm) const
Aggressive variant of evaluateAsRelocatable when relocations are unavailable (e.g.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
FragmentType getKind() const
LLVM_ABI void setVarFixups(ArrayRef< MCFixup > Fixups)
LLVM_ABI void setVarContents(ArrayRef< char > Contents)
Streaming object file generation interface.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Streaming machine code generation interface.
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
A table of densely packed, null-terminated strings indexed by offset.
constexpr Iterator end() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A raw_ostream that writes to an SmallVector or SmallString.
This class represents a function that is read from a sample profile.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
@ FK_SecRel_2
A two-byte section relative fixup.
@ FK_SecRel_4
A four-byte section relative fixup.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Information describing a function or inlined call site introduced by .cv_func_id or ....
DenseMap< unsigned, LineInfo > InlinedAtMap
Map from inlined call site id to the inlined at location to use for that call site.
Adapter to write values to a stream in a particular byte order.
void write(ArrayRef< value_type > Val)