-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[BOLT][DWARF][NFC] Refactor GDB Index into a new file #94405
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-mc @llvm/pr-subscribers-lldb Author: Sayhaan Siddiqui (sayhaan) ChangesCreate a new class and file for functions that update GDB index. Patch is 40.93 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/94405.diff 24 Files Affected:
diff --git a/bolt/include/bolt/Core/GDBIndex.h b/bolt/include/bolt/Core/GDBIndex.h
new file mode 100644
index 00000000000000..0ea588e9cba465
--- /dev/null
+++ b/bolt/include/bolt/Core/GDBIndex.h
@@ -0,0 +1,60 @@
+//===-- bolt/Core/GDBIndex.h - GDB Index support -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// This file contains declaration of classes required for generation of
+/// .gdb_index section.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef BOLT_CORE_GDB_INDEX_H
+#define BOLT_CORE_GDB_INDEX_H
+
+#include "bolt/Core/BinaryContext.h"
+#include <vector>
+
+namespace llvm {
+namespace bolt {
+
+class GDBIndex {
+public:
+ /// Contains information about TU so we can write out correct entries in GDB
+ /// index.
+ struct GDBIndexTUEntry {
+ uint64_t UnitOffset;
+ uint64_t TypeHash;
+ uint64_t TypeDIERelativeOffset;
+ };
+
+private:
+ BinaryContext &BC;
+
+ /// Entries for GDB Index Types CU List
+ using GDBIndexTUEntryType = std::vector<GDBIndexTUEntry>;
+ GDBIndexTUEntryType GDBIndexTUEntryVector;
+
+public:
+ GDBIndex(BinaryContext &BC) : BC(BC) {}
+
+ /// Adds an GDBIndexTUEntry if .gdb_index section exists.
+ void addGDBTypeUnitEntry(const GDBIndexTUEntry &Entry);
+
+ /// Rewrite .gdb_index section if present.
+ void updateGdbIndexSection(
+ CUOffsetMap &CUMap, uint32_t NumCUs,
+ std::unique_ptr<DebugARangesSectionWriter> &ARangesSectionWriter);
+
+ /// Returns all entries needed for Types CU list
+ const GDBIndexTUEntryType &getGDBIndexTUEntryVector() const {
+ return GDBIndexTUEntryVector;
+ }
+};
+
+} // namespace bolt
+} // namespace llvm
+
+#endif
diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp
index 0b44acb0816f2f..e09b9ff92de064 100644
--- a/bolt/lib/Core/BinaryEmitter.cpp
+++ b/bolt/lib/Core/BinaryEmitter.cpp
@@ -485,6 +485,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/Core/CMakeLists.txt b/bolt/lib/Core/CMakeLists.txt
index 441df9fe084648..873cf67a56291f 100644
--- a/bolt/lib/Core/CMakeLists.txt
+++ b/bolt/lib/Core/CMakeLists.txt
@@ -25,6 +25,7 @@ add_llvm_library(LLVMBOLTCore
DynoStats.cpp
Exceptions.cpp
FunctionLayout.cpp
+ GDBIndex.cpp
HashUtilities.cpp
JumpTable.cpp
MCPlusBuilder.cpp
diff --git a/bolt/lib/Core/GDBIndex.cpp b/bolt/lib/Core/GDBIndex.cpp
new file mode 100644
index 00000000000000..fda19a2c8cb3ef
--- /dev/null
+++ b/bolt/lib/Core/GDBIndex.cpp
@@ -0,0 +1,182 @@
+//===- bolt/Rewrite/GDBIndex.cpp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "bolt/Core/GDBIndex.h"
+
+using namespace llvm::bolt;
+using namespace llvm::support::endian;
+
+void GDBIndex::addGDBTypeUnitEntry(const GDBIndexTUEntry &Entry) {
+ GDBIndexTUEntryVector.push_back(Entry);
+}
+
+void GDBIndex::updateGdbIndexSection(
+ CUOffsetMap &CUMap, uint32_t NumCUs,
+ std::unique_ptr<DebugARangesSectionWriter> &ARangesSectionWriter) {
+ 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);
+}
diff --git a/bolt/lib/Passes/ValidateMemRefs.cpp b/bolt/lib/Passes/ValidateMemRefs.cpp
index f29a97c43f497c..1d2c230fa7106a 100644
--- a/bolt/lib/Passes/ValidateMemRefs.cpp
+++ b/bolt/lib/Passes/ValidateMemRefs.cpp
@@ -29,8 +29,7 @@ bool ValidateMemRefs::checkAndFixJTReference(BinaryFunction &BF, MCInst &Inst,
if (!BD)
return false;
- const uint64_t TargetAddress = BD->getAddress() + Offset;
- JumpTable *JT = BC.getJumpTableContainingAddress(TargetAddress);
+ JumpTable *JT = BC.getJumpTableContainingAddress(BD->getAddress());
if (!JT)
return false;
@@ -41,10 +40,10 @@ bool ValidateMemRefs::checkAndFixJTReference(BinaryFunction &BF, MCInst &Inst,
// Accessing a jump table in another function. This is not a
// legitimate jump table access, we need to replace the reference to
// the jump table label with a regular rodata reference. Get a
- // non-JT reference by fetching the symbol 1 byte before the JT
- // label.
- MCSymbol *NewSym = BC.getOrCreateGlobalSymbol(TargetAddress - 1, "DATAat");
- BC.MIB->setOperandToSymbolRef(Inst, OperandNum, NewSym, 1, &*BC.Ctx, 0);
+ // non-JT reference by fetching the symbol 1 byte before the JT label.
+ MCSymbol *NewSym = BC.getOrCreateGlobalSymbol(BD->getAddress() - 1, "DATAat");
+ BC.MIB->setOperandToSymbolRef(Inst, OperandNum, NewSym, Offset + 1, &*BC.Ctx,
+ 0);
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: replaced reference @" << BF.getPrintName()
<< " from " << BD->getName() << " to " << NewSym->getName()
<< " + 1\n");
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 57f37c5023110f..7469db06839e3b 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5465,6 +5465,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 b141e5f2adfab1..f7611af5763ab7 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 774c4eaf4d976b..619634578dfe60 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 39458dfc79afd2..2d53cd377f0330 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 d934349fe3ca3d..d4a62c51458cc1 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 8b2d09ae41cd2a..602f45759e48f3 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 255955fc70d8c4..7b7be06643166d 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 b69e7bce1bc0be..fe8323734b7dbf 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 64898ab09772f4..c4ac19eaca2148 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/llv...
[truncated]
|
@llvm/pr-subscribers-clang Author: Sayhaan Siddiqui (sayhaan) ChangesCreate a new class and file for functions that update GDB index. Patch is 40.93 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/94405.diff 24 Files Affected:
diff --git a/bolt/include/bolt/Core/GDBIndex.h b/bolt/include/bolt/Core/GDBIndex.h
new file mode 100644
index 00000000000000..0ea588e9cba465
--- /dev/null
+++ b/bolt/include/bolt/Core/GDBIndex.h
@@ -0,0 +1,60 @@
+//===-- bolt/Core/GDBIndex.h - GDB Index support -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// This file contains declaration of classes required for generation of
+/// .gdb_index section.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef BOLT_CORE_GDB_INDEX_H
+#define BOLT_CORE_GDB_INDEX_H
+
+#include "bolt/Core/BinaryContext.h"
+#include <vector>
+
+namespace llvm {
+namespace bolt {
+
+class GDBIndex {
+public:
+ /// Contains information about TU so we can write out correct entries in GDB
+ /// index.
+ struct GDBIndexTUEntry {
+ uint64_t UnitOffset;
+ uint64_t TypeHash;
+ uint64_t TypeDIERelativeOffset;
+ };
+
+private:
+ BinaryContext &BC;
+
+ /// Entries for GDB Index Types CU List
+ using GDBIndexTUEntryType = std::vector<GDBIndexTUEntry>;
+ GDBIndexTUEntryType GDBIndexTUEntryVector;
+
+public:
+ GDBIndex(BinaryContext &BC) : BC(BC) {}
+
+ /// Adds an GDBIndexTUEntry if .gdb_index section exists.
+ void addGDBTypeUnitEntry(const GDBIndexTUEntry &Entry);
+
+ /// Rewrite .gdb_index section if present.
+ void updateGdbIndexSection(
+ CUOffsetMap &CUMap, uint32_t NumCUs,
+ std::unique_ptr<DebugARangesSectionWriter> &ARangesSectionWriter);
+
+ /// Returns all entries needed for Types CU list
+ const GDBIndexTUEntryType &getGDBIndexTUEntryVector() const {
+ return GDBIndexTUEntryVector;
+ }
+};
+
+} // namespace bolt
+} // namespace llvm
+
+#endif
diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp
index 0b44acb0816f2f..e09b9ff92de064 100644
--- a/bolt/lib/Core/BinaryEmitter.cpp
+++ b/bolt/lib/Core/BinaryEmitter.cpp
@@ -485,6 +485,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/Core/CMakeLists.txt b/bolt/lib/Core/CMakeLists.txt
index 441df9fe084648..873cf67a56291f 100644
--- a/bolt/lib/Core/CMakeLists.txt
+++ b/bolt/lib/Core/CMakeLists.txt
@@ -25,6 +25,7 @@ add_llvm_library(LLVMBOLTCore
DynoStats.cpp
Exceptions.cpp
FunctionLayout.cpp
+ GDBIndex.cpp
HashUtilities.cpp
JumpTable.cpp
MCPlusBuilder.cpp
diff --git a/bolt/lib/Core/GDBIndex.cpp b/bolt/lib/Core/GDBIndex.cpp
new file mode 100644
index 00000000000000..fda19a2c8cb3ef
--- /dev/null
+++ b/bolt/lib/Core/GDBIndex.cpp
@@ -0,0 +1,182 @@
+//===- bolt/Rewrite/GDBIndex.cpp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "bolt/Core/GDBIndex.h"
+
+using namespace llvm::bolt;
+using namespace llvm::support::endian;
+
+void GDBIndex::addGDBTypeUnitEntry(const GDBIndexTUEntry &Entry) {
+ GDBIndexTUEntryVector.push_back(Entry);
+}
+
+void GDBIndex::updateGdbIndexSection(
+ CUOffsetMap &CUMap, uint32_t NumCUs,
+ std::unique_ptr<DebugARangesSectionWriter> &ARangesSectionWriter) {
+ 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);
+}
diff --git a/bolt/lib/Passes/ValidateMemRefs.cpp b/bolt/lib/Passes/ValidateMemRefs.cpp
index f29a97c43f497c..1d2c230fa7106a 100644
--- a/bolt/lib/Passes/ValidateMemRefs.cpp
+++ b/bolt/lib/Passes/ValidateMemRefs.cpp
@@ -29,8 +29,7 @@ bool ValidateMemRefs::checkAndFixJTReference(BinaryFunction &BF, MCInst &Inst,
if (!BD)
return false;
- const uint64_t TargetAddress = BD->getAddress() + Offset;
- JumpTable *JT = BC.getJumpTableContainingAddress(TargetAddress);
+ JumpTable *JT = BC.getJumpTableContainingAddress(BD->getAddress());
if (!JT)
return false;
@@ -41,10 +40,10 @@ bool ValidateMemRefs::checkAndFixJTReference(BinaryFunction &BF, MCInst &Inst,
// Accessing a jump table in another function. This is not a
// legitimate jump table access, we need to replace the reference to
// the jump table label with a regular rodata reference. Get a
- // non-JT reference by fetching the symbol 1 byte before the JT
- // label.
- MCSymbol *NewSym = BC.getOrCreateGlobalSymbol(TargetAddress - 1, "DATAat");
- BC.MIB->setOperandToSymbolRef(Inst, OperandNum, NewSym, 1, &*BC.Ctx, 0);
+ // non-JT reference by fetching the symbol 1 byte before the JT label.
+ MCSymbol *NewSym = BC.getOrCreateGlobalSymbol(BD->getAddress() - 1, "DATAat");
+ BC.MIB->setOperandToSymbolRef(Inst, OperandNum, NewSym, Offset + 1, &*BC.Ctx,
+ 0);
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: replaced reference @" << BF.getPrintName()
<< " from " << BD->getName() << " to " << NewSym->getName()
<< " + 1\n");
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 57f37c5023110f..7469db06839e3b 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5465,6 +5465,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 b141e5f2adfab1..f7611af5763ab7 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 774c4eaf4d976b..619634578dfe60 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 39458dfc79afd2..2d53cd377f0330 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 d934349fe3ca3d..d4a62c51458cc1 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 8b2d09ae41cd2a..602f45759e48f3 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 255955fc70d8c4..7b7be06643166d 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 b69e7bce1bc0be..fe8323734b7dbf 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 64898ab09772f4..c4ac19eaca2148 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/llv...
[truncated]
|
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D58156977
Add [BOLT][DWARF] to title |
And NFC somewhere. |
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D58193743
✅ With the latest revision this PR passed the C/C++ code formatter. |
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
LGTM |
Create a new class and file for functions that update GDB index.