-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[BOLT][DWARF][NFC] Remove old GDB Index functions #95019
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Sayhaan Siddiqui (sayhaan) ChangesRemove old usages of GDB Index functions after replacing them with new ones. Patch is 38.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/95019.diff 22 Files Affected:
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index 3cc9d823c815b..4559ff5ff5159 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -150,9 +150,6 @@ class DWARFRewriter {
/// blocks) to be updated.
void updateDebugAddressRanges();
- /// Rewrite .gdb_index section if present.
- void updateGdbIndexSection(CUOffsetMap &CUMap, uint32_t NumCUs);
-
/// DWARFDie contains a pointer to a DIE and hence gets invalidated once the
/// embedded DIE is destroyed. This wrapper class stores a DIE internally and
/// could be cast to a DWARFDie that is valid even after the initial DIE is
@@ -194,14 +191,6 @@ class DWARFRewriter {
DwoRangesBase[DWOId] = RangesBase;
}
- /// Adds an GDBIndexTUEntry if .gdb_index seciton exists.
- void addGDBTypeUnitEntry(const GDBIndexTUEntry &&Entry);
-
- /// Returns all entries needed for Types CU list
- const GDBIndexTUEntryType &getGDBIndexTUEntryVector() const {
- return GDBIndexTUEntryVector;
- }
-
using OverriddenSectionsMap = std::unordered_map<DWARFSectionKind, StringRef>;
/// Output .dwo files.
void writeDWOFiles(DWARFUnit &, const OverriddenSectionsMap &,
diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp
index 5793963f9b80d..c231fffa0d5ff 100644
--- a/bolt/lib/Core/BinaryEmitter.cpp
+++ b/bolt/lib/Core/BinaryEmitter.cpp
@@ -487,6 +487,7 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, FunctionFragment &FF,
// This assumes the second instruction in the macro-op pair will get
// assigned to its own MCRelaxableFragment. Since all JCC instructions
// are relaxable, we should be safe.
+ Streamer.emitNeverAlignCodeAtEnd(/*Alignment to avoid=*/64, *BC.STI);
}
if (!EmitCodeOnly) {
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 7b62999dfb2b6..04dc7e94e6031 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -2062,177 +2062,6 @@ void DWARFRewriter::writeDWOFiles(
TempOut->keep();
}
-void DWARFRewriter::addGDBTypeUnitEntry(const GDBIndexTUEntry &&Entry) {
- std::lock_guard<std::mutex> Lock(DWARFRewriterMutex);
- if (!BC.getGdbIndexSection())
- return;
- GDBIndexTUEntryVector.emplace_back(Entry);
-}
-
-void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap, uint32_t NumCUs) {
- if (!BC.getGdbIndexSection())
- return;
-
- // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
- // for .gdb_index section format.
-
- StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents();
-
- const char *Data = GdbIndexContents.data();
-
- // Parse the header.
- const uint32_t Version = read32le(Data);
- if (Version != 7 && Version != 8) {
- errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n";
- exit(1);
- }
-
- // Some .gdb_index generators use file offsets while others use section
- // offsets. Hence we can only rely on offsets relative to each other,
- // and ignore their absolute values.
- const uint32_t CUListOffset = read32le(Data + 4);
- const uint32_t CUTypesOffset = read32le(Data + 8);
- const uint32_t AddressTableOffset = read32le(Data + 12);
- const uint32_t SymbolTableOffset = read32le(Data + 16);
- const uint32_t ConstantPoolOffset = read32le(Data + 20);
- Data += 24;
-
- // Map CUs offsets to indices and verify existing index table.
- std::map<uint32_t, uint32_t> OffsetToIndexMap;
- const uint32_t CUListSize = CUTypesOffset - CUListOffset;
- const uint32_t TUListSize = AddressTableOffset - CUTypesOffset;
- const unsigned NUmCUsEncoded = CUListSize / 16;
- unsigned MaxDWARFVersion = BC.DwCtx->getMaxVersion();
- unsigned NumDWARF5TUs =
- getGDBIndexTUEntryVector().size() - BC.DwCtx->getNumTypeUnits();
- bool SkipTypeUnits = false;
- // For DWARF5 Types are in .debug_info.
- // LLD doesn't generate Types CU List, and in CU list offset
- // only includes CUs.
- // GDB 11+ includes only CUs in CU list and generates Types
- // list.
- // GDB 9 includes CUs and TUs in CU list and generates TYpes
- // list. The NumCUs is CUs + TUs, so need to modify the check.
- // For split-dwarf
- // GDB-11, DWARF5: TU units from dwo are not included.
- // GDB-11, DWARF4: TU units from dwo are included.
- if (MaxDWARFVersion >= 5)
- SkipTypeUnits = !TUListSize ? true
- : ((NUmCUsEncoded + NumDWARF5TUs) ==
- BC.DwCtx->getNumCompileUnits());
-
- if (!((CUListSize == NumCUs * 16) ||
- (CUListSize == (NumCUs + NumDWARF5TUs) * 16))) {
- errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n";
- exit(1);
- }
- DenseSet<uint64_t> OriginalOffsets;
- for (unsigned Index = 0, Units = BC.DwCtx->getNumCompileUnits();
- Index < Units; ++Index) {
- const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index);
- if (SkipTypeUnits && CU->isTypeUnit())
- continue;
- const uint64_t Offset = read64le(Data);
- Data += 16;
- if (CU->getOffset() != Offset) {
- errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n";
- exit(1);
- }
-
- OriginalOffsets.insert(Offset);
- OffsetToIndexMap[Offset] = Index;
- }
-
- // Ignore old address table.
- const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset;
- // Move Data to the beginning of symbol table.
- Data += SymbolTableOffset - CUTypesOffset;
-
- // Calculate the size of the new address table.
- uint32_t NewAddressTableSize = 0;
- for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) {
- const SmallVector<DebugAddressRange, 2> &Ranges = CURangesPair.second;
- NewAddressTableSize += Ranges.size() * 20;
- }
-
- // Difference between old and new table (and section) sizes.
- // Could be negative.
- int32_t Delta = NewAddressTableSize - OldAddressTableSize;
-
- size_t NewGdbIndexSize = GdbIndexContents.size() + Delta;
-
- // Free'd by ExecutableFileMemoryManager.
- auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize];
- uint8_t *Buffer = NewGdbIndexContents;
-
- write32le(Buffer, Version);
- write32le(Buffer + 4, CUListOffset);
- write32le(Buffer + 8, CUTypesOffset);
- write32le(Buffer + 12, AddressTableOffset);
- write32le(Buffer + 16, SymbolTableOffset + Delta);
- write32le(Buffer + 20, ConstantPoolOffset + Delta);
- Buffer += 24;
-
- using MapEntry = std::pair<uint32_t, CUInfo>;
- std::vector<MapEntry> CUVector(CUMap.begin(), CUMap.end());
- // Need to sort since we write out all of TUs in .debug_info before CUs.
- std::sort(CUVector.begin(), CUVector.end(),
- [](const MapEntry &E1, const MapEntry &E2) -> bool {
- return E1.second.Offset < E2.second.Offset;
- });
- // Writing out CU List <Offset, Size>
- for (auto &CUInfo : CUVector) {
- // Skipping TU for DWARF5 when they are not included in CU list.
- if (!OriginalOffsets.count(CUInfo.first))
- continue;
- write64le(Buffer, CUInfo.second.Offset);
- // Length encoded in CU doesn't contain first 4 bytes that encode length.
- write64le(Buffer + 8, CUInfo.second.Length + 4);
- Buffer += 16;
- }
-
- // Rewrite TU CU List, since abbrevs can be different.
- // Entry example:
- // 0: offset = 0x00000000, type_offset = 0x0000001e, type_signature =
- // 0x418503b8111e9a7b Spec says " triplet, the first value is the CU offset,
- // the second value is the type offset in the CU, and the third value is the
- // type signature" Looking at what is being generated by gdb-add-index. The
- // first entry is TU offset, second entry is offset from it, and third entry
- // is the type signature.
- if (TUListSize)
- for (const GDBIndexTUEntry &Entry : getGDBIndexTUEntryVector()) {
- write64le(Buffer, Entry.UnitOffset);
- write64le(Buffer + 8, Entry.TypeDIERelativeOffset);
- write64le(Buffer + 16, Entry.TypeHash);
- Buffer += sizeof(GDBIndexTUEntry);
- }
-
- // Generate new address table.
- for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair :
- ARangesSectionWriter->getCUAddressRanges()) {
- const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first];
- const DebugAddressRangesVector &Ranges = CURangesPair.second;
- for (const DebugAddressRange &Range : Ranges) {
- write64le(Buffer, Range.LowPC);
- write64le(Buffer + 8, Range.HighPC);
- write32le(Buffer + 16, CUIndex);
- Buffer += 20;
- }
- }
-
- const size_t TrailingSize =
- GdbIndexContents.data() + GdbIndexContents.size() - Data;
- assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize &&
- "size calculation error");
-
- // Copy over the rest of the original data.
- memcpy(Buffer, Data, TrailingSize);
-
- // Register the new section.
- BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents,
- NewGdbIndexSize);
-}
-
std::unique_ptr<DebugBufferVector>
DWARFRewriter::makeFinalLocListsSection(DWARFVersion Version) {
auto LocBuffer = std::make_unique<DebugBufferVector>();
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d44faa55c456f..63bb86717bb14 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5483,6 +5483,10 @@ def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">,
MarshallingInfoFlag<CodeGenOpts<"InstrumentForProfiling">>;
def pipe : Flag<["-", "--"], "pipe">,
HelpText<"Use pipes between commands, when possible">;
+// Facebook T92898286
+def post_link_optimize : Flag<["--"], "post-link-optimize">,
+ HelpText<"Apply post-link optimizations using BOLT">;
+// End Facebook T92898286
def prebind__all__twolevel__modules : Flag<["-"], "prebind_all_twolevel_modules">;
def prebind : Flag<["-"], "prebind">;
def preload : Flag<["-"], "preload">;
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index b141e5f2adfab..f7611af5763ab 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -672,12 +672,41 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ // Facebook T92898286
+ if (Args.hasArg(options::OPT_post_link_optimize))
+ CmdArgs.push_back("-q");
+ // End Facebook T92898286
+
Args.AddAllArgs(CmdArgs, options::OPT_T);
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
C.addCommand(std::make_unique<Command>(JA, *this,
ResponseFileSupport::AtFileCurCP(),
Exec, CmdArgs, Inputs, Output));
+ // Facebook T92898286
+ if (!Args.hasArg(options::OPT_post_link_optimize) || !Output.isFilename())
+ return;
+
+ const char *MvExec = Args.MakeArgString(ToolChain.GetProgramPath("mv"));
+ ArgStringList MoveCmdArgs;
+ MoveCmdArgs.push_back(Output.getFilename());
+ const char *PreBoltBin =
+ Args.MakeArgString(Twine(Output.getFilename()) + ".pre-bolt");
+ MoveCmdArgs.push_back(PreBoltBin);
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ MvExec, MoveCmdArgs, std::nullopt));
+
+ ArgStringList BoltCmdArgs;
+ const char *BoltExec =
+ Args.MakeArgString(ToolChain.GetProgramPath("llvm-bolt"));
+ BoltCmdArgs.push_back(PreBoltBin);
+ BoltCmdArgs.push_back("-reorder-blocks=reverse");
+ BoltCmdArgs.push_back("-update-debug-sections");
+ BoltCmdArgs.push_back("-o");
+ BoltCmdArgs.push_back(Output.getFilename());
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ BoltExec, BoltCmdArgs, std::nullopt));
+ // End Facebook T92898286
}
void tools::gnutools::Assembler::ConstructJob(Compilation &C,
diff --git a/cross-project-tests/lit.cfg.py b/cross-project-tests/lit.cfg.py
index 774c4eaf4d976..619634578dfe6 100644
--- a/cross-project-tests/lit.cfg.py
+++ b/cross-project-tests/lit.cfg.py
@@ -84,7 +84,13 @@ def get_required_attr(config, attr_name):
# use_clang() and use_lld() respectively, so set them to "", if needed.
if not hasattr(config, "clang_src_dir"):
config.clang_src_dir = ""
-llvm_config.use_clang(required=("clang" in config.llvm_enabled_projects))
+# Facebook T92898286
+should_test_bolt = get_required_attr(config, "llvm_test_bolt")
+if should_test_bolt:
+ llvm_config.use_clang(required=("clang" in config.llvm_enabled_projects), additional_flags=["--post-link-optimize"])
+else:
+ llvm_config.use_clang(required=("clang" in config.llvm_enabled_projects))
+# End Facebook T92898286
if not hasattr(config, "lld_src_dir"):
config.lld_src_dir = ""
@@ -293,3 +299,9 @@ def get_clang_default_dwarf_version_string(triple):
# Allow 'REQUIRES: XXX-registered-target' in tests.
for arch in config.targets_to_build:
config.available_features.add(arch.lower() + "-registered-target")
+
+# Facebook T92898286
+# Ensure the user's PYTHONPATH is included.
+if "PYTHONPATH" in os.environ:
+ config.environment["PYTHONPATH"] = os.environ["PYTHONPATH"]
+# End Facebook T92898286
diff --git a/cross-project-tests/lit.site.cfg.py.in b/cross-project-tests/lit.site.cfg.py.in
index 39458dfc79afd..2d53cd377f033 100644
--- a/cross-project-tests/lit.site.cfg.py.in
+++ b/cross-project-tests/lit.site.cfg.py.in
@@ -21,6 +21,10 @@ config.mlir_src_root = "@MLIR_SOURCE_DIR@"
config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
+# Facebook T92898286
+config.llvm_test_bolt = lit.util.pythonize_bool("@LLVM_TEST_BOLT@")
+# End Facebook T92898286
+
import lit.llvm
lit.llvm.initialize(lit_config, config)
diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py
index d934349fe3ca3..d4a62c51458cc 100644
--- a/lldb/test/API/lit.cfg.py
+++ b/lldb/test/API/lit.cfg.py
@@ -248,6 +248,11 @@ def delete_module_cache(path):
if is_configured("lldb_framework_dir"):
dotest_cmd += ["--framework", config.lldb_framework_dir]
+# Facebook T92898286
+if is_configured("llvm_test_bolt"):
+ dotest_cmd += ["-E", '"--post-link-optimize"']
+# End Facebook T92898286
+
if (
"lldb-repro-capture" in config.available_features
or "lldb-repro-replay" in config.available_features
diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in
index 8b2d09ae41cd2..602f45759e48f 100644
--- a/lldb/test/API/lit.site.cfg.py.in
+++ b/lldb/test/API/lit.site.cfg.py.in
@@ -1,5 +1,9 @@
@LIT_SITE_CFG_IN_HEADER@
+#Facebook T92898286
+import lit.util
+#End Facebook T92898286
+
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@")
@@ -39,6 +43,10 @@ config.libcxx_include_target_dir = "@LIBCXX_GENERATED_INCLUDE_TARGET_DIR@"
config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-api")
config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-api")
+# Facebook T92898286
+config.llvm_test_bolt = lit.util.pythonize_bool("@LLVM_TEST_BOLT@")
+# End Facebook T92898286
+
# Plugins
lldb_build_intel_pt = '@LLDB_BUILD_INTEL_PT@'
if lldb_build_intel_pt == '1':
diff --git a/lldb/test/Shell/helper/toolchain.py b/lldb/test/Shell/helper/toolchain.py
index 255955fc70d8c..7b7be06643166 100644
--- a/lldb/test/Shell/helper/toolchain.py
+++ b/lldb/test/Shell/helper/toolchain.py
@@ -165,6 +165,11 @@ def use_support_substitutions(config):
if config.cmake_sysroot:
host_flags += ["--sysroot={}".format(config.cmake_sysroot)]
+ # Facebook T92898286
+ if config.llvm_test_bolt:
+ host_flags += ["--post-link-optimize"]
+ # End Facebook T92898286
+
host_flags = " ".join(host_flags)
config.substitutions.append(("%clang_host", "%clang " + host_flags))
config.substitutions.append(("%clangxx_host", "%clangxx " + host_flags))
diff --git a/lldb/test/Shell/lit.site.cfg.py.in b/lldb/test/Shell/lit.site.cfg.py.in
index b69e7bce1bc0b..fe8323734b7db 100644
--- a/lldb/test/Shell/lit.site.cfg.py.in
+++ b/lldb/test/Shell/lit.site.cfg.py.in
@@ -1,5 +1,10 @@
@LIT_SITE_CFG_IN_HEADER@
+#Facebook T92898286
+import lit.util
+#End Facebook T92898286
+
+
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@")
@@ -31,6 +36,10 @@ config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-shell")
config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-shell")
+# Facebook T92898286
+config.llvm_test_bolt = lit.util.pythonize_bool("@LLVM_TEST_BOLT@")
+# End Facebook T92898286
+
import lit.llvm
lit.llvm.initialize(lit_config, config)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 3208147101c0d..ecd36d2564e4f 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -709,6 +709,10 @@ set(LLVM_LIB_FUZZING_ENGINE "" CACHE PATH
option(LLVM_USE_SPLIT_DWARF
"Use -gsplit-dwarf when compiling llvm and --gdb-index when linking." OFF)
+# Facebook T92898286
+option(LLVM_TEST_BOLT "Enable BOLT testing in non-BOLT tests that use clang" OFF)
+# End Facebook T92898286
+
# Define an option controlling whether we should build for 32-bit on 64-bit
# platforms, where supported.
if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT (WIN32 OR ${CMAKE_SYSTEM_NAME} MATCHES "AIX"))
diff --git a/llvm/include/llvm/MC/MCFragment.h b/llvm/include/llvm/MC/MCFragment.h
index 67e10c3589495..1adb8a67009d1 100644
--- a/llvm/include/llvm/MC/MCFragment.h
+++ b/llvm/include/llvm/MC/MCFragment.h
@@ -33,6 +33,7 @@ class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
public:
enum FragmentType : uint8_t {
FT_Align,
+ FT_NeverAlign,
FT_Data,
FT_CompactEncodedInst,
FT_Fill,
@@ -341,6 +342,27 @@ class MCAlignFragment : public MCFragment {
}
};
+class MCNeverAlignFragment : public MCFragment {
+ /// The alignment the end of the next fragment should avoid.
+ unsigned Alignment;
+
+ /// When emitting Nops some subtargets have specific nop encodings.
+ const MCSubtargetInfo &STI;
+
+public:
+ MCNeverAlignFragment(unsigned Alignment, const MCSubtargetInfo &STI,
+ MCSection *Sec = nullptr)
+ : MCFragment(FT_NeverAlign, false, Sec), Alignment(Alignment), STI(STI) {}
+
+ unsigned getAlignment() const { return Alignment; }
+
+ const MCSubtargetInfo &getSubtargetInfo() const { return STI; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_NeverAlign;
+ }
+};
+
class MCFillFragment : public MCFragment {
uint8_t ValueSize;
/// Value to use for filling bytes.
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index e212d54613980..c7d760721e369 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -157,6 +157,8 @@ class MCObjectStreamer : public MCStreamer {
unsigned MaxBytesToEmit = 0) override;
void emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0) override;
+ void emitNeverAlignCodeAtEnd(unsigned ByteAlignment,
+ const MCSubtargetInfo &STI) override;
void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
SMLoc Loc) override;
void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index b7468cf70a664..dd813192d9ca0 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -887,6 +887,12 @@ class MCStreamer {
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0);
+ /// If the end of the fragment following this NeverAlign fragment ever gets
+ /// aligned to \p ByteAlignment, this fragment emits a single nop before the
+ /// following fragment to break this end-alignment.
+ virtual void emitNeverAlignCodeAtEnd(unsigned ByteAlignment,
+ const MCSubtargetInfo &STI);
+
/// Em...
[truncated]
|
@llvm/pr-subscribers-backend-x86 Author: Sayhaan Siddiqui (sayhaan) ChangesRemove old usages of GDB Index functions after replacing them with new ones. Patch is 38.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/95019.diff 22 Files Affected:
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index 3cc9d823c815b..4559ff5ff5159 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -150,9 +150,6 @@ class DWARFRewriter {
/// blocks) to be updated.
void updateDebugAddressRanges();
- /// Rewrite .gdb_index section if present.
- void updateGdbIndexSection(CUOffsetMap &CUMap, uint32_t NumCUs);
-
/// DWARFDie contains a pointer to a DIE and hence gets invalidated once the
/// embedded DIE is destroyed. This wrapper class stores a DIE internally and
/// could be cast to a DWARFDie that is valid even after the initial DIE is
@@ -194,14 +191,6 @@ class DWARFRewriter {
DwoRangesBase[DWOId] = RangesBase;
}
- /// Adds an GDBIndexTUEntry if .gdb_index seciton exists.
- void addGDBTypeUnitEntry(const GDBIndexTUEntry &&Entry);
-
- /// Returns all entries needed for Types CU list
- const GDBIndexTUEntryType &getGDBIndexTUEntryVector() const {
- return GDBIndexTUEntryVector;
- }
-
using OverriddenSectionsMap = std::unordered_map<DWARFSectionKind, StringRef>;
/// Output .dwo files.
void writeDWOFiles(DWARFUnit &, const OverriddenSectionsMap &,
diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp
index 5793963f9b80d..c231fffa0d5ff 100644
--- a/bolt/lib/Core/BinaryEmitter.cpp
+++ b/bolt/lib/Core/BinaryEmitter.cpp
@@ -487,6 +487,7 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, FunctionFragment &FF,
// This assumes the second instruction in the macro-op pair will get
// assigned to its own MCRelaxableFragment. Since all JCC instructions
// are relaxable, we should be safe.
+ Streamer.emitNeverAlignCodeAtEnd(/*Alignment to avoid=*/64, *BC.STI);
}
if (!EmitCodeOnly) {
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 7b62999dfb2b6..04dc7e94e6031 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -2062,177 +2062,6 @@ void DWARFRewriter::writeDWOFiles(
TempOut->keep();
}
-void DWARFRewriter::addGDBTypeUnitEntry(const GDBIndexTUEntry &&Entry) {
- std::lock_guard<std::mutex> Lock(DWARFRewriterMutex);
- if (!BC.getGdbIndexSection())
- return;
- GDBIndexTUEntryVector.emplace_back(Entry);
-}
-
-void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap, uint32_t NumCUs) {
- if (!BC.getGdbIndexSection())
- return;
-
- // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
- // for .gdb_index section format.
-
- StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents();
-
- const char *Data = GdbIndexContents.data();
-
- // Parse the header.
- const uint32_t Version = read32le(Data);
- if (Version != 7 && Version != 8) {
- errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n";
- exit(1);
- }
-
- // Some .gdb_index generators use file offsets while others use section
- // offsets. Hence we can only rely on offsets relative to each other,
- // and ignore their absolute values.
- const uint32_t CUListOffset = read32le(Data + 4);
- const uint32_t CUTypesOffset = read32le(Data + 8);
- const uint32_t AddressTableOffset = read32le(Data + 12);
- const uint32_t SymbolTableOffset = read32le(Data + 16);
- const uint32_t ConstantPoolOffset = read32le(Data + 20);
- Data += 24;
-
- // Map CUs offsets to indices and verify existing index table.
- std::map<uint32_t, uint32_t> OffsetToIndexMap;
- const uint32_t CUListSize = CUTypesOffset - CUListOffset;
- const uint32_t TUListSize = AddressTableOffset - CUTypesOffset;
- const unsigned NUmCUsEncoded = CUListSize / 16;
- unsigned MaxDWARFVersion = BC.DwCtx->getMaxVersion();
- unsigned NumDWARF5TUs =
- getGDBIndexTUEntryVector().size() - BC.DwCtx->getNumTypeUnits();
- bool SkipTypeUnits = false;
- // For DWARF5 Types are in .debug_info.
- // LLD doesn't generate Types CU List, and in CU list offset
- // only includes CUs.
- // GDB 11+ includes only CUs in CU list and generates Types
- // list.
- // GDB 9 includes CUs and TUs in CU list and generates TYpes
- // list. The NumCUs is CUs + TUs, so need to modify the check.
- // For split-dwarf
- // GDB-11, DWARF5: TU units from dwo are not included.
- // GDB-11, DWARF4: TU units from dwo are included.
- if (MaxDWARFVersion >= 5)
- SkipTypeUnits = !TUListSize ? true
- : ((NUmCUsEncoded + NumDWARF5TUs) ==
- BC.DwCtx->getNumCompileUnits());
-
- if (!((CUListSize == NumCUs * 16) ||
- (CUListSize == (NumCUs + NumDWARF5TUs) * 16))) {
- errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n";
- exit(1);
- }
- DenseSet<uint64_t> OriginalOffsets;
- for (unsigned Index = 0, Units = BC.DwCtx->getNumCompileUnits();
- Index < Units; ++Index) {
- const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index);
- if (SkipTypeUnits && CU->isTypeUnit())
- continue;
- const uint64_t Offset = read64le(Data);
- Data += 16;
- if (CU->getOffset() != Offset) {
- errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n";
- exit(1);
- }
-
- OriginalOffsets.insert(Offset);
- OffsetToIndexMap[Offset] = Index;
- }
-
- // Ignore old address table.
- const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset;
- // Move Data to the beginning of symbol table.
- Data += SymbolTableOffset - CUTypesOffset;
-
- // Calculate the size of the new address table.
- uint32_t NewAddressTableSize = 0;
- for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) {
- const SmallVector<DebugAddressRange, 2> &Ranges = CURangesPair.second;
- NewAddressTableSize += Ranges.size() * 20;
- }
-
- // Difference between old and new table (and section) sizes.
- // Could be negative.
- int32_t Delta = NewAddressTableSize - OldAddressTableSize;
-
- size_t NewGdbIndexSize = GdbIndexContents.size() + Delta;
-
- // Free'd by ExecutableFileMemoryManager.
- auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize];
- uint8_t *Buffer = NewGdbIndexContents;
-
- write32le(Buffer, Version);
- write32le(Buffer + 4, CUListOffset);
- write32le(Buffer + 8, CUTypesOffset);
- write32le(Buffer + 12, AddressTableOffset);
- write32le(Buffer + 16, SymbolTableOffset + Delta);
- write32le(Buffer + 20, ConstantPoolOffset + Delta);
- Buffer += 24;
-
- using MapEntry = std::pair<uint32_t, CUInfo>;
- std::vector<MapEntry> CUVector(CUMap.begin(), CUMap.end());
- // Need to sort since we write out all of TUs in .debug_info before CUs.
- std::sort(CUVector.begin(), CUVector.end(),
- [](const MapEntry &E1, const MapEntry &E2) -> bool {
- return E1.second.Offset < E2.second.Offset;
- });
- // Writing out CU List <Offset, Size>
- for (auto &CUInfo : CUVector) {
- // Skipping TU for DWARF5 when they are not included in CU list.
- if (!OriginalOffsets.count(CUInfo.first))
- continue;
- write64le(Buffer, CUInfo.second.Offset);
- // Length encoded in CU doesn't contain first 4 bytes that encode length.
- write64le(Buffer + 8, CUInfo.second.Length + 4);
- Buffer += 16;
- }
-
- // Rewrite TU CU List, since abbrevs can be different.
- // Entry example:
- // 0: offset = 0x00000000, type_offset = 0x0000001e, type_signature =
- // 0x418503b8111e9a7b Spec says " triplet, the first value is the CU offset,
- // the second value is the type offset in the CU, and the third value is the
- // type signature" Looking at what is being generated by gdb-add-index. The
- // first entry is TU offset, second entry is offset from it, and third entry
- // is the type signature.
- if (TUListSize)
- for (const GDBIndexTUEntry &Entry : getGDBIndexTUEntryVector()) {
- write64le(Buffer, Entry.UnitOffset);
- write64le(Buffer + 8, Entry.TypeDIERelativeOffset);
- write64le(Buffer + 16, Entry.TypeHash);
- Buffer += sizeof(GDBIndexTUEntry);
- }
-
- // Generate new address table.
- for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair :
- ARangesSectionWriter->getCUAddressRanges()) {
- const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first];
- const DebugAddressRangesVector &Ranges = CURangesPair.second;
- for (const DebugAddressRange &Range : Ranges) {
- write64le(Buffer, Range.LowPC);
- write64le(Buffer + 8, Range.HighPC);
- write32le(Buffer + 16, CUIndex);
- Buffer += 20;
- }
- }
-
- const size_t TrailingSize =
- GdbIndexContents.data() + GdbIndexContents.size() - Data;
- assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize &&
- "size calculation error");
-
- // Copy over the rest of the original data.
- memcpy(Buffer, Data, TrailingSize);
-
- // Register the new section.
- BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents,
- NewGdbIndexSize);
-}
-
std::unique_ptr<DebugBufferVector>
DWARFRewriter::makeFinalLocListsSection(DWARFVersion Version) {
auto LocBuffer = std::make_unique<DebugBufferVector>();
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d44faa55c456f..63bb86717bb14 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5483,6 +5483,10 @@ def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">,
MarshallingInfoFlag<CodeGenOpts<"InstrumentForProfiling">>;
def pipe : Flag<["-", "--"], "pipe">,
HelpText<"Use pipes between commands, when possible">;
+// Facebook T92898286
+def post_link_optimize : Flag<["--"], "post-link-optimize">,
+ HelpText<"Apply post-link optimizations using BOLT">;
+// End Facebook T92898286
def prebind__all__twolevel__modules : Flag<["-"], "prebind_all_twolevel_modules">;
def prebind : Flag<["-"], "prebind">;
def preload : Flag<["-"], "preload">;
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index b141e5f2adfab..f7611af5763ab 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -672,12 +672,41 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ // Facebook T92898286
+ if (Args.hasArg(options::OPT_post_link_optimize))
+ CmdArgs.push_back("-q");
+ // End Facebook T92898286
+
Args.AddAllArgs(CmdArgs, options::OPT_T);
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
C.addCommand(std::make_unique<Command>(JA, *this,
ResponseFileSupport::AtFileCurCP(),
Exec, CmdArgs, Inputs, Output));
+ // Facebook T92898286
+ if (!Args.hasArg(options::OPT_post_link_optimize) || !Output.isFilename())
+ return;
+
+ const char *MvExec = Args.MakeArgString(ToolChain.GetProgramPath("mv"));
+ ArgStringList MoveCmdArgs;
+ MoveCmdArgs.push_back(Output.getFilename());
+ const char *PreBoltBin =
+ Args.MakeArgString(Twine(Output.getFilename()) + ".pre-bolt");
+ MoveCmdArgs.push_back(PreBoltBin);
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ MvExec, MoveCmdArgs, std::nullopt));
+
+ ArgStringList BoltCmdArgs;
+ const char *BoltExec =
+ Args.MakeArgString(ToolChain.GetProgramPath("llvm-bolt"));
+ BoltCmdArgs.push_back(PreBoltBin);
+ BoltCmdArgs.push_back("-reorder-blocks=reverse");
+ BoltCmdArgs.push_back("-update-debug-sections");
+ BoltCmdArgs.push_back("-o");
+ BoltCmdArgs.push_back(Output.getFilename());
+ C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+ BoltExec, BoltCmdArgs, std::nullopt));
+ // End Facebook T92898286
}
void tools::gnutools::Assembler::ConstructJob(Compilation &C,
diff --git a/cross-project-tests/lit.cfg.py b/cross-project-tests/lit.cfg.py
index 774c4eaf4d976..619634578dfe6 100644
--- a/cross-project-tests/lit.cfg.py
+++ b/cross-project-tests/lit.cfg.py
@@ -84,7 +84,13 @@ def get_required_attr(config, attr_name):
# use_clang() and use_lld() respectively, so set them to "", if needed.
if not hasattr(config, "clang_src_dir"):
config.clang_src_dir = ""
-llvm_config.use_clang(required=("clang" in config.llvm_enabled_projects))
+# Facebook T92898286
+should_test_bolt = get_required_attr(config, "llvm_test_bolt")
+if should_test_bolt:
+ llvm_config.use_clang(required=("clang" in config.llvm_enabled_projects), additional_flags=["--post-link-optimize"])
+else:
+ llvm_config.use_clang(required=("clang" in config.llvm_enabled_projects))
+# End Facebook T92898286
if not hasattr(config, "lld_src_dir"):
config.lld_src_dir = ""
@@ -293,3 +299,9 @@ def get_clang_default_dwarf_version_string(triple):
# Allow 'REQUIRES: XXX-registered-target' in tests.
for arch in config.targets_to_build:
config.available_features.add(arch.lower() + "-registered-target")
+
+# Facebook T92898286
+# Ensure the user's PYTHONPATH is included.
+if "PYTHONPATH" in os.environ:
+ config.environment["PYTHONPATH"] = os.environ["PYTHONPATH"]
+# End Facebook T92898286
diff --git a/cross-project-tests/lit.site.cfg.py.in b/cross-project-tests/lit.site.cfg.py.in
index 39458dfc79afd..2d53cd377f033 100644
--- a/cross-project-tests/lit.site.cfg.py.in
+++ b/cross-project-tests/lit.site.cfg.py.in
@@ -21,6 +21,10 @@ config.mlir_src_root = "@MLIR_SOURCE_DIR@"
config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
+# Facebook T92898286
+config.llvm_test_bolt = lit.util.pythonize_bool("@LLVM_TEST_BOLT@")
+# End Facebook T92898286
+
import lit.llvm
lit.llvm.initialize(lit_config, config)
diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py
index d934349fe3ca3..d4a62c51458cc 100644
--- a/lldb/test/API/lit.cfg.py
+++ b/lldb/test/API/lit.cfg.py
@@ -248,6 +248,11 @@ def delete_module_cache(path):
if is_configured("lldb_framework_dir"):
dotest_cmd += ["--framework", config.lldb_framework_dir]
+# Facebook T92898286
+if is_configured("llvm_test_bolt"):
+ dotest_cmd += ["-E", '"--post-link-optimize"']
+# End Facebook T92898286
+
if (
"lldb-repro-capture" in config.available_features
or "lldb-repro-replay" in config.available_features
diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in
index 8b2d09ae41cd2..602f45759e48f 100644
--- a/lldb/test/API/lit.site.cfg.py.in
+++ b/lldb/test/API/lit.site.cfg.py.in
@@ -1,5 +1,9 @@
@LIT_SITE_CFG_IN_HEADER@
+#Facebook T92898286
+import lit.util
+#End Facebook T92898286
+
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@")
@@ -39,6 +43,10 @@ config.libcxx_include_target_dir = "@LIBCXX_GENERATED_INCLUDE_TARGET_DIR@"
config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-api")
config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-api")
+# Facebook T92898286
+config.llvm_test_bolt = lit.util.pythonize_bool("@LLVM_TEST_BOLT@")
+# End Facebook T92898286
+
# Plugins
lldb_build_intel_pt = '@LLDB_BUILD_INTEL_PT@'
if lldb_build_intel_pt == '1':
diff --git a/lldb/test/Shell/helper/toolchain.py b/lldb/test/Shell/helper/toolchain.py
index 255955fc70d8c..7b7be06643166 100644
--- a/lldb/test/Shell/helper/toolchain.py
+++ b/lldb/test/Shell/helper/toolchain.py
@@ -165,6 +165,11 @@ def use_support_substitutions(config):
if config.cmake_sysroot:
host_flags += ["--sysroot={}".format(config.cmake_sysroot)]
+ # Facebook T92898286
+ if config.llvm_test_bolt:
+ host_flags += ["--post-link-optimize"]
+ # End Facebook T92898286
+
host_flags = " ".join(host_flags)
config.substitutions.append(("%clang_host", "%clang " + host_flags))
config.substitutions.append(("%clangxx_host", "%clangxx " + host_flags))
diff --git a/lldb/test/Shell/lit.site.cfg.py.in b/lldb/test/Shell/lit.site.cfg.py.in
index b69e7bce1bc0b..fe8323734b7db 100644
--- a/lldb/test/Shell/lit.site.cfg.py.in
+++ b/lldb/test/Shell/lit.site.cfg.py.in
@@ -1,5 +1,10 @@
@LIT_SITE_CFG_IN_HEADER@
+#Facebook T92898286
+import lit.util
+#End Facebook T92898286
+
+
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@")
@@ -31,6 +36,10 @@ config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-shell")
config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-shell")
+# Facebook T92898286
+config.llvm_test_bolt = lit.util.pythonize_bool("@LLVM_TEST_BOLT@")
+# End Facebook T92898286
+
import lit.llvm
lit.llvm.initialize(lit_config, config)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 3208147101c0d..ecd36d2564e4f 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -709,6 +709,10 @@ set(LLVM_LIB_FUZZING_ENGINE "" CACHE PATH
option(LLVM_USE_SPLIT_DWARF
"Use -gsplit-dwarf when compiling llvm and --gdb-index when linking." OFF)
+# Facebook T92898286
+option(LLVM_TEST_BOLT "Enable BOLT testing in non-BOLT tests that use clang" OFF)
+# End Facebook T92898286
+
# Define an option controlling whether we should build for 32-bit on 64-bit
# platforms, where supported.
if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT (WIN32 OR ${CMAKE_SYSTEM_NAME} MATCHES "AIX"))
diff --git a/llvm/include/llvm/MC/MCFragment.h b/llvm/include/llvm/MC/MCFragment.h
index 67e10c3589495..1adb8a67009d1 100644
--- a/llvm/include/llvm/MC/MCFragment.h
+++ b/llvm/include/llvm/MC/MCFragment.h
@@ -33,6 +33,7 @@ class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
public:
enum FragmentType : uint8_t {
FT_Align,
+ FT_NeverAlign,
FT_Data,
FT_CompactEncodedInst,
FT_Fill,
@@ -341,6 +342,27 @@ class MCAlignFragment : public MCFragment {
}
};
+class MCNeverAlignFragment : public MCFragment {
+ /// The alignment the end of the next fragment should avoid.
+ unsigned Alignment;
+
+ /// When emitting Nops some subtargets have specific nop encodings.
+ const MCSubtargetInfo &STI;
+
+public:
+ MCNeverAlignFragment(unsigned Alignment, const MCSubtargetInfo &STI,
+ MCSection *Sec = nullptr)
+ : MCFragment(FT_NeverAlign, false, Sec), Alignment(Alignment), STI(STI) {}
+
+ unsigned getAlignment() const { return Alignment; }
+
+ const MCSubtargetInfo &getSubtargetInfo() const { return STI; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_NeverAlign;
+ }
+};
+
class MCFillFragment : public MCFragment {
uint8_t ValueSize;
/// Value to use for filling bytes.
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index e212d54613980..c7d760721e369 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -157,6 +157,8 @@ class MCObjectStreamer : public MCStreamer {
unsigned MaxBytesToEmit = 0) override;
void emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0) override;
+ void emitNeverAlignCodeAtEnd(unsigned ByteAlignment,
+ const MCSubtargetInfo &STI) override;
void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
SMLoc Loc) override;
void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index b7468cf70a664..dd813192d9ca0 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -887,6 +887,12 @@ class MCStreamer {
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0);
+ /// If the end of the fragment following this NeverAlign fragment ever gets
+ /// aligned to \p ByteAlignment, this fragment emits a single nop before the
+ /// following fragment to break this end-alignment.
+ virtual void emitNeverAlignCodeAtEnd(unsigned ByteAlignment,
+ const MCSubtargetInfo &STI);
+
/// Em...
[truncated]
|
✅ With the latest revision this PR passed the Python code formatter. |
b9273c8
to
5eec1c8
Compare
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D58156979
5eec1c8
to
5283c9a
Compare
Remove old usages of GDB Index functions after replacing them with new ones.