mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
d33177a252
Summary: The accelerator tables use the debug_str section to store their strings. However, they do not support the indirect method of access that is available for the debug_info section (DW_FORM_strx et al.). Currently our code is assuming that all strings can/will be referenced indirectly, and puts all of them into the debug_str_offsets section. This is generally true for regular (unsplit) dwarf, but in the DWO case, most of the strings in the debug_str section will only be used from the accelerator tables. Therefore the contents of the debug_str_offsets section will be largely unused and bloating the main executable. This patch rectifies this by teaching the DwarfStringPool to differentiate between strings accessed directly and indirectly. When a user inserts a string into the pool it has to declare whether that string will be referenced directly or not. If at least one user requsts indirect access, that string will be assigned an index ID and put into debug_str_offsets table. Otherwise, the offset table is skipped. This approach reduces the overall binary size (when compiled with -gdwarf-5 -gsplit-dwarf) in my tests by about 2% (debug_str_offsets is shrunk by 99%). Reviewers: probinson, dblaikie, JDevlieghere Subscribers: aprantl, mgrang, llvm-commits Differential Revision: https://reviews.llvm.org/D49493 llvm-svn: 339122
86 lines
2.9 KiB
C++
86 lines
2.9 KiB
C++
//===- NonRelocatableStringpool.h - A simple stringpool --------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_TOOLS_DSYMUTIL_NONRELOCATABLESTRINGPOOL_H
|
|
#define LLVM_TOOLS_DSYMUTIL_NONRELOCATABLESTRINGPOOL_H
|
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
|
|
#include "llvm/Support/Allocator.h"
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
namespace llvm {
|
|
namespace dsymutil {
|
|
|
|
/// A string table that doesn't need relocations.
|
|
///
|
|
/// We are doing a final link, no need for a string table that has relocation
|
|
/// entries for every reference to it. This class provides this ability by just
|
|
/// associating offsets with strings.
|
|
class NonRelocatableStringpool {
|
|
public:
|
|
/// Entries are stored into the StringMap and simply linked together through
|
|
/// the second element of this pair in order to keep track of insertion
|
|
/// order.
|
|
using MapTy = StringMap<DwarfStringPoolEntry, BumpPtrAllocator>;
|
|
|
|
NonRelocatableStringpool() {
|
|
// Legacy dsymutil puts an empty string at the start of the line table.
|
|
EmptyString = getEntry("");
|
|
}
|
|
|
|
DwarfStringPoolEntryRef getEntry(StringRef S);
|
|
|
|
/// Get the offset of string \p S in the string table. This can insert a new
|
|
/// element or return the offset of a pre-existing one.
|
|
uint32_t getStringOffset(StringRef S) { return getEntry(S).getOffset(); }
|
|
|
|
/// Get permanent storage for \p S (but do not necessarily emit \p S in the
|
|
/// output section). A latter call to getStringOffset() with the same string
|
|
/// will chain it though.
|
|
///
|
|
/// \returns The StringRef that points to permanent storage to use
|
|
/// in place of \p S.
|
|
StringRef internString(StringRef S);
|
|
|
|
uint64_t getSize() { return CurrentEndOffset; }
|
|
|
|
/// Return the list of strings to be emitted. This does not contain the
|
|
/// strings which were added via internString only.
|
|
std::vector<DwarfStringPoolEntryRef> getEntriesForEmission() const;
|
|
|
|
private:
|
|
MapTy Strings;
|
|
uint32_t CurrentEndOffset = 0;
|
|
unsigned NumEntries = 0;
|
|
DwarfStringPoolEntryRef EmptyString;
|
|
};
|
|
|
|
/// Helper for making strong types.
|
|
template <typename T, typename S> class StrongType : public T {
|
|
public:
|
|
template <typename... Args>
|
|
explicit StrongType(Args... A) : T(std::forward<Args>(A)...) {}
|
|
};
|
|
|
|
/// It's very easy to introduce bugs by passing the wrong string pool in the
|
|
/// dwarf linker. By using strong types the interface enforces that the right
|
|
/// kind of pool is used.
|
|
struct UniqueTag {};
|
|
struct OffsetsTag {};
|
|
using UniquingStringPool = StrongType<NonRelocatableStringpool, UniqueTag>;
|
|
using OffsetsStringPool = StrongType<NonRelocatableStringpool, OffsetsTag>;
|
|
|
|
} // end namespace dsymutil
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_TOOLS_DSYMUTIL_NONRELOCATABLESTRINGPOOL_H
|