Go to the documentation of this file.
39 std::lock_guard<std::mutex> Guard(
Mutex);
40 const auto NextIndex = Files.size();
42 auto R = FileEntryToIndex.
insert(std::make_pair(FE, NextIndex));
44 Files.emplace_back(FE);
45 return R.first->second;
59 std::lock_guard<std::mutex> Guard(
Mutex);
62 "no functions to encode");
65 "GsymCreator wasn't finalized prior to encoding");
67 if (Funcs.size() > UINT32_MAX)
69 "too many FunctionInfos");
72 BaseAddress ? *BaseAddress : Funcs.front().startAddress();
73 const uint64_t MaxAddr = Funcs.back().startAddress();
74 const uint64_t AddrDelta = MaxAddr - MinAddr;
84 memset(Hdr.
UUID, 0,
sizeof(Hdr.
UUID));
89 if (AddrDelta <= UINT8_MAX)
91 else if (AddrDelta <= UINT16_MAX)
93 else if (AddrDelta <= UINT32_MAX)
107 for (
const auto &FuncInfo : Funcs) {
111 O.writeU8(
static_cast<uint8_t
>(AddrOffset));
114 O.writeU16(
static_cast<uint16_t>(AddrOffset));
117 O.writeU32(
static_cast<uint32_t>(AddrOffset));
120 O.writeU64(AddrOffset);
127 const off_t AddrInfoOffsetsOffset =
O.tell();
128 for (
size_t i = 0,
n = Funcs.size();
i <
n; ++
i)
134 assert(Files[0].Dir == 0);
136 size_t NumFiles = Files.size();
137 if (NumFiles > UINT32_MAX)
139 O.writeU32(
static_cast<uint32_t>(NumFiles));
140 for (
auto File : Files) {
141 O.writeU32(File.Dir);
142 O.writeU32(File.Base);
146 const off_t StrtabOffset =
O.tell();
147 StrTab.
write(
O.get_stream());
148 const off_t StrtabSize =
O.tell() - StrtabOffset;
149 std::vector<uint32_t> AddrInfoOffsets;
152 for (
const auto &FuncInfo : Funcs) {
154 AddrInfoOffsets.push_back(OffsetOrErr.get());
156 return OffsetOrErr.takeError();
164 for (
auto AddrInfoOffset : AddrInfoOffsets) {
165 O.fixup32(AddrInfoOffset, AddrInfoOffsetsOffset + Offset);
173 template <
class ForwardIt,
class BinaryPredicate>
175 BinaryPredicate Pred) {
176 if (FirstIt != LastIt) {
177 auto PrevIt = FirstIt++;
178 FirstIt =
std::find_if(FirstIt, LastIt, [&](
const auto &Curr) {
179 return Pred(*PrevIt++, Curr);
181 if (FirstIt != LastIt)
182 for (ForwardIt CurrIt = FirstIt; ++CurrIt != LastIt;)
183 if (!Pred(*PrevIt, *CurrIt)) {
192 std::lock_guard<std::mutex> Guard(
Mutex);
223 auto NumBefore = Funcs.size();
226 [&](
const auto &Prev,
const auto &Curr) {
230 const bool ranges_equal = Prev.Range == Curr.Range;
231 if (ranges_equal || Prev.Range.intersects(Curr.Range)) {
250 if (!Prev.hasRichInfo() && Curr.hasRichInfo()) {
257 OS <<
"warning: same address range contains "
259 <<
"info. Removing:\n"
260 << Prev <<
"\nIn favor of this one:\n"
268 OS <<
"warning: function ranges overlap:\n"
273 }
else if (Prev.Range.size() == 0 &&
274 Curr.Range.contains(Prev.Range.start())) {
276 OS <<
"warning: removing symbol:\n"
277 << Prev <<
"\nKeeping:\n"
292 if (!Funcs.empty() && Funcs.back().Range.size() == 0 && ValidTextRanges) {
294 ValidTextRanges->getRangeThatContains(Funcs.back().Range.start())) {
295 Funcs.back().Range = *Range;
298 OS <<
"Pruned " << NumBefore - Funcs.size() <<
" functions, ended with "
299 << Funcs.size() <<
" total\n";
309 std::lock_guard<std::mutex> Guard(
Mutex);
321 return StrTab.
add(CHStr);
325 std::lock_guard<std::mutex> Guard(
Mutex);
332 std::lock_guard<std::mutex> Guard(
Mutex);
333 for (
auto &FI : Funcs) {
341 std::lock_guard<std::mutex> Guard(
Mutex);
342 for (
const auto &FI : Funcs) {
349 std::lock_guard<std::mutex> Guard(
Mutex);
355 return ValidTextRanges->contains(
Addr);
360 std::lock_guard<std::mutex> Guard(
Mutex);
This is an optimization pass for GlobalISel generic memory operations.
bool contains(StringRef S) const
Check if a string is contained in the string table.
#define offsetof(TYPE, MEMBER)
static ErrorSuccess success()
Create a success value.
void finalizeInOrder()
Finalize the string table without reording it.
llvm::Error encode(FileWriter &O) const
Encode a GSYM into the file writer stream at the current position.
bool IsValidTextAddress(uint64_t Addr) const
Check if an address is a valid code address.
std::pair< typename Base::iterator, bool > insert(StringRef key)
Tagged union holding either a T or a Error.
constexpr uint32_t GSYM_MAGIC
constexpr uint32_t GSYM_VERSION
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
bool hasFunctionInfoForAddress(uint64_t Addr) const
Check if an address has already been added as a function info.
bool contains(uint64_t Addr) const
This class implements an extremely fast bulk output stream that can only output to a stream.
Function information in GSYM files encodes information for one contiguous address range.
A container which contains a StringRef plus a precomputed hash.
void insert(AddressRange Range)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Subclass of Error for the sole purpose of identifying the success path in the type system.
A simplified binary data writer class that doesn't require targets, target definitions,...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
print Print MemDeps of function
std::pair< llvm::MachO::Target, std::string > UUID
void forEachFunctionInfo(std::function< bool(FunctionInfo &)> const &Callback)
Thread safe iteration over all function infos.
void write(raw_ostream &OS) const
size_t getNumFunctionInfos() const
Get the current number of FunctionInfo objects contained in this object.
StringRef - Represent a constant reference to a string, i.e.
void addFunctionInfo(FunctionInfo &&FI)
Add a function info to this GSYM creator.
if(llvm_vc STREQUAL "") set(fake_version_inc "$
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
uint32_t insertString(StringRef S, bool Copy=true)
Insert a string into the GSYM string table.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
A raw_ostream that writes to a file descriptor.
Files in GSYM are contained in FileEntry structs where we split the directory and basename into two d...
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Lightweight error class with error context and mandatory checking.
size_t add(CachedHashStringRef S)
Add a string to the builder.
void sort(IteratorTy Start, IteratorTy End)
Utility for building string tables with deduplicated suffixes.
uint32_t insertFile(StringRef Path, sys::path::Style Style=sys::path::Style::native)
Insert a file into this GSYM creator.
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
llvm::Error save(StringRef Path, llvm::support::endianness ByteOrder) const
Save a GSYM file to a stand alone file.
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
llvm::Error finalize(llvm::raw_ostream &OS)
Finalize the data in the GSYM creator prior to saving the data out.
GsymCreator(bool Quiet=false)
static ForwardIt removeIfBinary(ForwardIt FirstIt, ForwardIt LastIt, BinaryPredicate Pred)