Skip to content

Commit

Permalink
merge main into amd-stg-open
Browse files Browse the repository at this point in the history
Change-Id: I3eb35c87ce71179d5074c67fd042f7fc7762de2f
  • Loading branch information
ronlieb committed Oct 24, 2023
2 parents 5216158 + b4e5529 commit a9b8060
Show file tree
Hide file tree
Showing 853 changed files with 19,460 additions and 14,662 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ on:
- 'lldb/docs/**'
- 'libunwind/docs/**'
- 'libcxx/docs/**'
- 'libc/docs/**'
pull_request:
paths:
- 'llvm/docs/**'
Expand All @@ -27,6 +28,7 @@ on:
- 'lldb/docs/**'
- 'libunwind/docs/**'
- 'libcxx/docs/**'
- 'libc/docs/**'

jobs:
check-docs-build:
Expand Down Expand Up @@ -59,6 +61,8 @@ jobs:
- 'libunwind/docs/**'
libcxx:
- 'libcxx/docs/**'
libc:
- 'libc/docs/**'
- name: Fetch LLVM sources (PR)
if: ${{ github.event_name == 'pull_request' }}
uses: actions/checkout@v4
Expand Down Expand Up @@ -107,4 +111,9 @@ jobs:
run: |
cmake -B libcxx-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RUNTIMES="libcxxabi;libcxx" -DLLVM_ENABLE_SPHINX=ON ./runtimes
TZ=UTC ninja -C libcxx-build docs-libcxx-html
- name: Build libc docs
if: steps.docs-changed-subprojects.outputs.libc_any_changed == 'true'
run: |
cmake -B libc-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RUNTIMES="libc" -DLLVM_ENABLE_SPHINX=ON ./runtimes
TZ=UTC ninja -C docs-libc-html
50 changes: 35 additions & 15 deletions bolt/include/bolt/Core/AddressMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@
//
//===----------------------------------------------------------------------===//
//
// Helper class to create a mapping from input to output addresses needed for
// updating debugging symbols and BAT. We emit an MCSection containing
// <Input address, Output MCSymbol> pairs to the object file and JITLink will
// transform this in <Input address, Output address> pairs. The linker output
// can then be parsed and used to establish the mapping.
// This file contains the declaration of the AddressMap class used for looking
// up addresses in the output object.
//
//===----------------------------------------------------------------------===//
//

#ifndef BOLT_CORE_ADDRESS_MAP_H
#define BOLT_CORE_ADDRESS_MAP_H

#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSymbol.h"

#include <optional>
#include <unordered_map>
Expand All @@ -30,26 +28,48 @@ namespace bolt {

class BinaryContext;

/// Helper class to create a mapping from input entities to output addresses
/// needed for updating debugging symbols and BAT. We emit a section containing
/// <Input entity, Output MCSymbol> pairs to the object file and JITLink will
/// transform this in <Input entity, Output address> pairs. The linker output
/// can then be parsed and used to establish the mapping.
///
/// The entities that can be mapped to output address are input addresses and
/// labels (MCSymbol). Input addresses support one-to-many mapping.
class AddressMap {
using MapTy = std::unordered_multimap<uint64_t, uint64_t>;
MapTy Map;
static const char *const AddressSectionName;
static const char *const LabelSectionName;

public:
static const char *const SectionName;
/// Map multiple <input address> to <output address>.
using Addr2AddrMapTy = std::unordered_multimap<uint64_t, uint64_t>;
Addr2AddrMapTy Address2AddressMap;

/// Map MCSymbol to its output address. Normally used for temp symbols that
/// are not updated by the linker.
using Label2AddrMapTy = DenseMap<const MCSymbol *, uint64_t>;
Label2AddrMapTy Label2AddrMap;

public:
static void emit(MCStreamer &Streamer, BinaryContext &BC);
static AddressMap parse(StringRef Buffer, const BinaryContext &BC);
static std::optional<AddressMap> parse(BinaryContext &BC);

std::optional<uint64_t> lookup(uint64_t InputAddress) const {
auto It = Map.find(InputAddress);
if (It != Map.end())
auto It = Address2AddressMap.find(InputAddress);
if (It != Address2AddressMap.end())
return It->second;
return std::nullopt;
}

std::optional<uint64_t> lookup(const MCSymbol *Symbol) const {
auto It = Label2AddrMap.find(Symbol);
if (It != Label2AddrMap.end())
return It->second;
return std::nullopt;
}

std::pair<MapTy::const_iterator, MapTy::const_iterator>
std::pair<Addr2AddrMapTy::const_iterator, Addr2AddrMapTy::const_iterator>
lookupAll(uint64_t InputAddress) const {
return Map.equal_range(InputAddress);
return Address2AddressMap.equal_range(InputAddress);
}
};

Expand Down
94 changes: 74 additions & 20 deletions bolt/lib/Core/AddressMap.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
//===- bolt/Core/AddressMap.cpp - Input-output Address Map ----------------===//
//
// 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/AddressMap.h"
#include "bolt/Core/BinaryContext.h"
#include "bolt/Core/BinaryFunction.h"
#include "bolt/Core/BinarySection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/DataExtractor.h"

namespace llvm {
namespace bolt {

const char *const AddressMap::SectionName = ".bolt.address_map";
const char *const AddressMap::AddressSectionName = ".bolt.addr2addr_map";
const char *const AddressMap::LabelSectionName = ".bolt.label2addr_map";

static void emitLabel(MCStreamer &Streamer, uint64_t InputAddress,
const MCSymbol *OutputLabel) {
static void emitAddress(MCStreamer &Streamer, uint64_t InputAddress,
const MCSymbol *OutputLabel) {
Streamer.emitIntValue(InputAddress, 8);
Streamer.emitSymbolValue(OutputLabel, 8);
}

static void emitLabel(MCStreamer &Streamer, const MCSymbol *OutputLabel) {
Streamer.emitIntValue(reinterpret_cast<uint64_t>(OutputLabel), 8);
Streamer.emitSymbolValue(OutputLabel, 8);
}

void AddressMap::emit(MCStreamer &Streamer, BinaryContext &BC) {
Streamer.switchSection(BC.getDataSection(SectionName));
// Mark map sections as link-only to avoid allocation in the output file.
const unsigned Flags = BinarySection::getFlags(/*IsReadOnly*/ true,
/*IsText*/ false,
/*IsAllocatable*/ true);
BC.registerOrUpdateSection(AddressSectionName, ELF::SHT_PROGBITS, Flags)
.setLinkOnly();
BC.registerOrUpdateSection(LabelSectionName, ELF::SHT_PROGBITS, Flags)
.setLinkOnly();

for (const auto &[BFAddress, BF] : BC.getBinaryFunctions()) {
if (!BF.requiresAddressMap())
Expand All @@ -26,37 +48,69 @@ void AddressMap::emit(MCStreamer &Streamer, BinaryContext &BC) {
if (!BB.getLabel()->isDefined())
continue;

emitLabel(Streamer, BFAddress + BB.getInputAddressRange().first,
BB.getLabel());
Streamer.switchSection(BC.getDataSection(LabelSectionName));
emitLabel(Streamer, BB.getLabel());

if (!BB.hasLocSyms())
continue;

Streamer.switchSection(BC.getDataSection(AddressSectionName));
for (auto [Offset, Symbol] : BB.getLocSyms())
emitLabel(Streamer, BFAddress + Offset, Symbol);
emitAddress(Streamer, BFAddress + Offset, Symbol);
}
}
}

AddressMap AddressMap::parse(StringRef Buffer, const BinaryContext &BC) {
const auto EntrySize = 2 * BC.AsmInfo->getCodePointerSize();
assert(Buffer.size() % EntrySize == 0 && "Unexpected address map size");
std::optional<AddressMap> AddressMap::parse(BinaryContext &BC) {
auto AddressMapSection = BC.getUniqueSectionByName(AddressSectionName);
auto LabelMapSection = BC.getUniqueSectionByName(LabelSectionName);

DataExtractor DE(Buffer, BC.AsmInfo->isLittleEndian(),
BC.AsmInfo->getCodePointerSize());
DataExtractor::Cursor Cursor(0);
if (!AddressMapSection && !LabelMapSection)
return std::nullopt;

AddressMap Parsed;
Parsed.Map.reserve(Buffer.size() / EntrySize);

while (Cursor && !DE.eof(Cursor)) {
const auto Input = DE.getAddress(Cursor);
const auto Output = DE.getAddress(Cursor);
if (!Parsed.Map.count(Input))
Parsed.Map.insert({Input, Output});
const size_t EntrySize = 2 * BC.AsmInfo->getCodePointerSize();
auto parseSection =
[&](BinarySection &Section,
function_ref<void(uint64_t, uint64_t)> InsertCallback) {
StringRef Buffer = Section.getOutputContents();
assert(Buffer.size() % EntrySize == 0 && "Unexpected address map size");

DataExtractor DE(Buffer, BC.AsmInfo->isLittleEndian(),
BC.AsmInfo->getCodePointerSize());
DataExtractor::Cursor Cursor(0);

while (Cursor && !DE.eof(Cursor)) {
const uint64_t Input = DE.getAddress(Cursor);
const uint64_t Output = DE.getAddress(Cursor);
InsertCallback(Input, Output);
}

assert(Cursor && "Error reading address map section");
BC.deregisterSection(Section);
};

if (AddressMapSection) {
Parsed.Address2AddressMap.reserve(AddressMapSection->getOutputSize() /
EntrySize);
parseSection(*AddressMapSection, [&](uint64_t Input, uint64_t Output) {
if (!Parsed.Address2AddressMap.count(Input))
Parsed.Address2AddressMap.insert({Input, Output});
});
}

if (LabelMapSection) {
Parsed.Label2AddrMap.reserve(LabelMapSection->getOutputSize() / EntrySize);
parseSection(*LabelMapSection, [&](uint64_t Input, uint64_t Output) {
assert(!Parsed.Label2AddrMap.count(
reinterpret_cast<const MCSymbol *>(Input)) &&
"Duplicate label entry detected.");
Parsed.Label2AddrMap.insert(
{reinterpret_cast<const MCSymbol *>(Input), Output});
});
}

assert(Cursor && "Error reading address map section");
return Parsed;
}

Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Core/BinaryContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ BinaryContext::createBinaryContext(const ObjectFile *File, bool IsPIC,
Expected<SubtargetFeatures> Features = File->getFeatures();

if (auto E = Features.takeError())
return E;
return std::move(E);

// We rely on relaxation for some transformations (e.g., promoting all calls
// to PseudoCALL and then making JITLink relax them). Since the relax
Expand Down
11 changes: 8 additions & 3 deletions bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4165,15 +4165,20 @@ void BinaryFunction::updateOutputValues(const BOLTLinker &Linker) {
// Injected functions likely will fail lookup, as they have no
// input range. Just assign the BB the output address of the
// function.
auto MaybeBBAddress =
BC.getIOAddressMap().lookup(BB->getInputOffset() + getAddress());
auto MaybeBBAddress = BC.getIOAddressMap().lookup(BB->getLabel());
const uint64_t BBAddress = MaybeBBAddress ? *MaybeBBAddress
: BB->isSplit() ? FF.getAddress()
: getOutputAddress();
BB->setOutputStartAddress(BBAddress);

if (PrevBB)
if (PrevBB) {
assert(PrevBB->getOutputAddressRange().first <= BBAddress &&
"Bad output address for basic block.");
assert((PrevBB->getOutputAddressRange().first != BBAddress ||
!hasInstructions() || PrevBB->empty()) &&
"Bad output address for basic block.");
PrevBB->setOutputEndAddress(BBAddress);
}
PrevBB = BB;
}

Expand Down
10 changes: 2 additions & 8 deletions bolt/lib/Rewrite/RewriteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3196,9 +3196,6 @@ void RewriteInstance::preregisterSections() {
ROFlags);
BC->registerOrUpdateSection(getNewSecPrefix() + ".rodata.cold",
ELF::SHT_PROGBITS, ROFlags);
BC->registerOrUpdateSection(AddressMap::SectionName, ELF::SHT_PROGBITS,
ROFlags)
.setLinkOnly();
}

void RewriteInstance::emitAndLink() {
Expand Down Expand Up @@ -3669,11 +3666,8 @@ void RewriteInstance::mapAllocatableSections(
}

void RewriteInstance::updateOutputValues(const BOLTLinker &Linker) {
if (auto MapSection = BC->getUniqueSectionByName(AddressMap::SectionName)) {
auto Map = AddressMap::parse(MapSection->getOutputContents(), *BC);
BC->setIOAddressMap(std::move(Map));
BC->deregisterSection(*MapSection);
}
if (std::optional<AddressMap> Map = AddressMap::parse(*BC))
BC->setIOAddressMap(std::move(*Map));

for (BinaryFunction *Function : BC->getAllBinaryFunctions())
Function->updateOutputValues(Linker);
Expand Down
1 change: 1 addition & 0 deletions bolt/test/X86/jump-table-icp.test
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ RUN: (llvm-bolt %t.exe --data %t.fdata -o %t --relocs \
RUN: --reorder-blocks=cache --split-functions --split-all-cold \
RUN: --use-gnu-stack --dyno-stats --indirect-call-promotion=jump-tables \
RUN: --print-icp -v=0 \
RUN: --enable-bat --print-cache-metrics \
RUN: --icp-jt-remaining-percent-threshold=10 \
RUN: --icp-jt-total-percent-threshold=2 \
RUN: --indirect-call-promotion-topn=1 \
Expand Down
17 changes: 15 additions & 2 deletions clang-tools-extra/clangd/SystemIncludeExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,14 @@ struct DriverArgs {
std::string Sysroot;
std::string ISysroot;
std::string Target;
std::string Stdlib;

bool operator==(const DriverArgs &RHS) const {
return std::tie(Driver, StandardIncludes, StandardCXXIncludes, Lang,
Sysroot, ISysroot, Target) ==
Sysroot, ISysroot, Target, Stdlib) ==
std::tie(RHS.Driver, RHS.StandardIncludes, RHS.StandardCXXIncludes,
RHS.Lang, RHS.Sysroot, RHS.ISysroot, RHS.Target);
RHS.Lang, RHS.Sysroot, RHS.ISysroot, RHS.Target,
RHS.Stdlib);
}

DriverArgs(const tooling::CompileCommand &Cmd, llvm::StringRef File) {
Expand Down Expand Up @@ -136,6 +138,13 @@ struct DriverArgs {
} else if (Arg.consume_front("-target")) {
if (Arg.empty() && I + 1 < E)
Target = Cmd.CommandLine[I + 1];
} else if (Arg.consume_front("--stdlib")) {
if (Arg.consume_front("="))
Stdlib = Arg.str();
else if (Arg.empty() && I + 1 < E)
Stdlib = Cmd.CommandLine[I + 1];
} else if (Arg.consume_front("-stdlib=")) {
Stdlib = Arg.str();
}
}

Expand Down Expand Up @@ -175,6 +184,8 @@ struct DriverArgs {
Args.append({"-isysroot", ISysroot});
if (!Target.empty())
Args.append({"-target", Target});
if (!Stdlib.empty())
Args.append({"--stdlib", Stdlib});
return Args;
}

Expand Down Expand Up @@ -206,6 +217,8 @@ template <> struct DenseMapInfo<DriverArgs> {
Val.Lang,
Val.Sysroot,
Val.ISysroot,
Val.Target,
Val.Stdlib,
});
}
static bool isEqual(const DriverArgs &LHS, const DriverArgs &RHS) {
Expand Down
10 changes: 10 additions & 0 deletions clang-tools-extra/clangd/refactor/tweaks/RawStringLiteral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "ParsedAST.h"
#include "refactor/Tweak.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
Expand Down Expand Up @@ -43,6 +44,12 @@ class RawStringLiteral : public Tweak {

REGISTER_TWEAK(RawStringLiteral)

static bool isFeatureAvailable(const ASTContext &Context) {
// Raw strings are available only for C++11 or later versions, and they are
// not available for C.
return Context.getLangOpts().CPlusPlus11;
}

static bool isNormalString(const StringLiteral &Str, SourceLocation Cursor,
SourceManager &SM) {
// All chunks must be normal ASCII strings, not u8"..." etc.
Expand Down Expand Up @@ -72,6 +79,9 @@ static bool canBeRaw(llvm::StringRef Content) {
}

bool RawStringLiteral::prepare(const Selection &Inputs) {
if (!isFeatureAvailable(Inputs.AST->getASTContext())) {
return false;
}
const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor();
if (!N)
return false;
Expand Down
Loading

0 comments on commit a9b8060

Please sign in to comment.