31 return LHS.Delta < Delta;
35 int64_t LineDelta,
uint64_t AddrDelta,
37 if (LineDelta < MinLineDelta)
39 if (LineDelta > MaxLineDelta)
41 int64_t LineRange = MaxLineDelta - MinLineDelta + 1;
42 int64_t AdjustedOp = ((LineDelta - MinLineDelta) + AddrDelta * LineRange);
57 if (!Data.isValidOffset(
Offset))
59 "0x%8.8" PRIx64
": missing LineTable MinDelta",
Offset);
60 int64_t MinDelta = Data.getSLEB128(&
Offset);
61 if (!Data.isValidOffset(
Offset))
63 "0x%8.8" PRIx64
": missing LineTable MaxDelta",
Offset);
64 int64_t MaxDelta = Data.getSLEB128(&
Offset);
65 int64_t LineRange = MaxDelta - MinDelta + 1;
66 if (!Data.isValidOffset(
Offset))
68 "0x%8.8" PRIx64
": missing LineTable FirstLine",
Offset);
73 if (!Data.isValidOffset(
Offset))
75 "0x%8.8" PRIx64
": EOF found before EndSequence",
Offset);
82 if (!Data.isValidOffset(
Offset))
84 "0x%8.8" PRIx64
": EOF found before SetFile value",
89 if (!Data.isValidOffset(
Offset))
91 "0x%8.8" PRIx64
": EOF found before AdvancePC value",
93 Row.Addr += Data.getULEB128(&
Offset);
95 if (Callback(Row) ==
false)
99 if (!Data.isValidOffset(
Offset))
101 "0x%8.8" PRIx64
": EOF found before AdvanceLine value",
103 Row.Line += Data.getSLEB128(&
Offset);
108 int64_t LineDelta = MinDelta + (AdjustedOp % LineRange);
109 uint64_t AddrDelta = (AdjustedOp / LineRange);
110 Row.Line += LineDelta;
111 Row.Addr += AddrDelta;
113 if (Callback(Row) ==
false)
128 "attempted to encode invalid LineTable object");
132 std::vector<DeltaInfo> DeltaInfos;
133 if (Lines.size() == 1) {
137 int64_t PrevLine = 1;
139 for (
const auto &line_entry : Lines) {
143 int64_t LineDelta = (int64_t)line_entry.Line - PrevLine;
144 auto End = DeltaInfos.end();
145 auto Pos = std::lower_bound(DeltaInfos.begin(),
End, LineDelta);
146 if (Pos !=
End && Pos->Delta == LineDelta)
149 DeltaInfos.insert(Pos,
DeltaInfo(LineDelta, 1));
150 if (LineDelta < MinLineDelta)
151 MinLineDelta = LineDelta;
152 if (LineDelta > MaxLineDelta)
153 MaxLineDelta = LineDelta;
155 PrevLine = (int64_t)line_entry.Line;
157 assert(MinLineDelta <= MaxLineDelta);
161 const int64_t MaxLineRange = 14;
162 if (MaxLineDelta - MinLineDelta > MaxLineRange) {
166 const size_t NumDeltaInfos = DeltaInfos.size();
168 const int64_t FirstDelta = DeltaInfos[
I].Delta;
171 for (J =
I; J < NumDeltaInfos; ++J) {
172 auto LineRange = DeltaInfos[J].Delta - FirstDelta;
173 if (LineRange > MaxLineRange)
175 CurrCount += DeltaInfos[J].Count;
177 if (CurrCount > BestCount) {
179 BestEndIndex = J - 1;
180 BestCount = CurrCount;
183 MinLineDelta = DeltaInfos[BestIndex].Delta;
184 MaxLineDelta = DeltaInfos[BestEndIndex].Delta;
186 if (MinLineDelta == MaxLineDelta && MinLineDelta > 0 &&
187 MinLineDelta < MaxLineRange)
189 assert(MinLineDelta <= MaxLineDelta);
193 LineEntry Prev(BaseAddr, 1, Lines.front().Line);
201 for (
const auto &Curr : Lines) {
202 if (Curr.Addr < BaseAddr)
204 "LineEntry has address 0x%" PRIx64
" which is "
205 "less than the function start address 0x%"
206 PRIx64, Curr.Addr, BaseAddr);
207 if (Curr.Addr < Prev.
Addr)
209 "LineEntry in LineTable not in ascending order");
211 int64_t LineDelta = 0;
212 if (Curr.Line > Prev.
Line)
213 LineDelta = Curr.Line - Prev.
Line;
214 else if (Prev.
Line > Curr.Line)
215 LineDelta = -((int32_t)(Prev.
Line - Curr.Line));
218 if (Curr.File != Prev.
File) {
224 if (
encodeSpecial(MinLineDelta, MaxLineDelta, LineDelta, AddrDelta,
233 if (LineDelta != 0) {
255 LT.Lines.push_back(Row);
259 return std::move(Err);
276 return std::move(Err);
277 if (Result.isValid())
280 "address 0x%" PRIx64
" is not in the line table",
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
bool operator<(const DeltaInfo &LHS, int64_t Delta)
@ SetFile
Set LineTableRow.file_idx, don't push a row.
@ FirstSpecial
All special opcodes push a row.
@ AdvanceLine
Set LineTableRow.file_line, don't push a row.
@ EndSequence
End of the line table.
@ AdvancePC
Increment LineTableRow.address, and push a row.
static bool encodeSpecial(int64_t MinLineDelta, int64_t MaxLineDelta, int64_t LineDelta, uint64_t AddrDelta, uint8_t &SpecialOp)
std::function< bool(const LineEntry &Row)> LineEntryCallback
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class represents an Operation in the Expression.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
A simplified binary data writer class that doesn't require targets, target definitions,...
void writeULEB(uint64_t Value)
Write the value into the stream encoded using unsigned LEB128 at the current file position.
void writeSLEB(int64_t Value)
Write the value into the stream encoded using signed LEB128 at the current file position.
void writeU8(uint8_t Value)
Write a single uint8_t value into the stream at the current file position.
LineTable class contains deserialized versions of line tables for each function's address ranges.
llvm::Error encode(FileWriter &O, uint64_t BaseAddr) const
Encode this LineTable object into FileWriter stream.
static llvm::Expected< LineTable > decode(DataExtractor &Data, uint64_t BaseAddr)
Decode an LineTable object from a binary data stream.
static Expected< LineEntry > lookup(DataExtractor &Data, uint64_t BaseAddr, uint64_t Addr)
Lookup a single address within a line table's data.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ C
The default llvm calling convention, compatible with C.
raw_ostream & operator<<(raw_ostream &OS, const CallSiteInfo &CSI)
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
DeltaInfo(int64_t D, uint32_t C)
Line entries are used to encode the line tables in FunctionInfo objects.
uint32_t File
1 based index of file in FileTable
uint32_t Line
Source line number.
uint64_t Addr
Start address of this line entry.