Skip to content

Commit 8dc188b

Browse files
Merge branch 'main' into fix-remove-dead-values-bug
2 parents e22f086 + 87e39c3 commit 8dc188b

File tree

318 files changed

+5540
-1239
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

318 files changed

+5540
-1239
lines changed

bolt/runtime/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ set(BOLT_RT_FLAGS
3535
-fno-exceptions
3636
-fno-rtti
3737
-fno-stack-protector
38-
-fPIC)
38+
-fPIC
39+
# Runtime currently assumes omitted frame pointers for functions marked __attribute((naked)).
40+
# Protect against distros adding -fno-omit-frame-pointer and compiling with GCC.
41+
# Refs: llvm/llvm-project#148595 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882
42+
-fomit-frame-pointer
43+
)
3944
if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
4045
set(BOLT_RT_FLAGS ${BOLT_RT_FLAGS}
4146
-mno-sse

bolt/runtime/instr.cpp

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -568,13 +568,13 @@ struct FunctionDescription {
568568
/// should be straightforward as most data is POD or an array of POD elements.
569569
/// This metadata is used to reconstruct function CFGs.
570570
struct ProfileWriterContext {
571-
IndCallDescription *IndCallDescriptions;
572-
IndCallTargetDescription *IndCallTargets;
573-
uint8_t *FuncDescriptions;
574-
char *Strings; // String table with function names used in this binary
571+
const IndCallDescription *IndCallDescriptions;
572+
const IndCallTargetDescription *IndCallTargets;
573+
const uint8_t *FuncDescriptions;
574+
const char *Strings; // String table with function names used in this binary
575575
int FileDesc; // File descriptor for the file on disk backing this
576576
// information in memory via mmap
577-
void *MMapPtr; // The mmap ptr
577+
const void *MMapPtr; // The mmap ptr
578578
int MMapSize; // The mmap size
579579

580580
/// Hash table storing all possible call destinations to detect untracked
@@ -721,7 +721,7 @@ static char *getBinaryPath() {
721721

722722
ProfileWriterContext readDescriptions() {
723723
ProfileWriterContext Result;
724-
char *BinPath = getBinaryPath();
724+
const char *BinPath = getBinaryPath();
725725
assert(BinPath && BinPath[0] != '\0', "failed to find binary path");
726726

727727
uint64_t FD = __open(BinPath, O_RDONLY,
@@ -732,23 +732,24 @@ ProfileWriterContext readDescriptions() {
732732

733733
// mmap our binary to memory
734734
uint64_t Size = __lseek(FD, 0, SEEK_END);
735-
uint8_t *BinContents = reinterpret_cast<uint8_t *>(
735+
const uint8_t *BinContents = reinterpret_cast<uint8_t *>(
736736
__mmap(0, Size, PROT_READ, MAP_PRIVATE, FD, 0));
737737
assert(BinContents != MAP_FAILED, "readDescriptions: Failed to mmap self!");
738738
Result.MMapPtr = BinContents;
739739
Result.MMapSize = Size;
740-
Elf64_Ehdr *Hdr = reinterpret_cast<Elf64_Ehdr *>(BinContents);
741-
Elf64_Shdr *Shdr = reinterpret_cast<Elf64_Shdr *>(BinContents + Hdr->e_shoff);
742-
Elf64_Shdr *StringTblHeader = reinterpret_cast<Elf64_Shdr *>(
740+
const Elf64_Ehdr *Hdr = reinterpret_cast<const Elf64_Ehdr *>(BinContents);
741+
const Elf64_Shdr *Shdr =
742+
reinterpret_cast<const Elf64_Shdr *>(BinContents + Hdr->e_shoff);
743+
const Elf64_Shdr *StringTblHeader = reinterpret_cast<const Elf64_Shdr *>(
743744
BinContents + Hdr->e_shoff + Hdr->e_shstrndx * Hdr->e_shentsize);
744745

745746
// Find .bolt.instr.tables with the data we need and set pointers to it
746747
for (int I = 0; I < Hdr->e_shnum; ++I) {
747-
char *SecName = reinterpret_cast<char *>(
748+
const char *SecName = reinterpret_cast<const char *>(
748749
BinContents + StringTblHeader->sh_offset + Shdr->sh_name);
749750
if (compareStr(SecName, ".bolt.instr.tables", 64) != 0) {
750-
Shdr = reinterpret_cast<Elf64_Shdr *>(BinContents + Hdr->e_shoff +
751-
(I + 1) * Hdr->e_shentsize);
751+
Shdr = reinterpret_cast<const Elf64_Shdr *>(BinContents + Hdr->e_shoff +
752+
(I + 1) * Hdr->e_shentsize);
752753
continue;
753754
}
754755
// Actual contents of the ELF note start after offset 20 decimal:
@@ -758,19 +759,19 @@ ProfileWriterContext readDescriptions() {
758759
// Offset 12: Producer name (BOLT\0) (5 bytes + align to 4-byte boundary)
759760
// Offset 20: Contents
760761
uint32_t IndCallDescSize =
761-
*reinterpret_cast<uint32_t *>(BinContents + Shdr->sh_offset + 20);
762-
uint32_t IndCallTargetDescSize = *reinterpret_cast<uint32_t *>(
762+
*reinterpret_cast<const uint32_t *>(BinContents + Shdr->sh_offset + 20);
763+
uint32_t IndCallTargetDescSize = *reinterpret_cast<const uint32_t *>(
763764
BinContents + Shdr->sh_offset + 24 + IndCallDescSize);
764-
uint32_t FuncDescSize =
765-
*reinterpret_cast<uint32_t *>(BinContents + Shdr->sh_offset + 28 +
766-
IndCallDescSize + IndCallTargetDescSize);
767-
Result.IndCallDescriptions = reinterpret_cast<IndCallDescription *>(
765+
uint32_t FuncDescSize = *reinterpret_cast<const uint32_t *>(
766+
BinContents + Shdr->sh_offset + 28 + IndCallDescSize +
767+
IndCallTargetDescSize);
768+
Result.IndCallDescriptions = reinterpret_cast<const IndCallDescription *>(
768769
BinContents + Shdr->sh_offset + 24);
769-
Result.IndCallTargets = reinterpret_cast<IndCallTargetDescription *>(
770+
Result.IndCallTargets = reinterpret_cast<const IndCallTargetDescription *>(
770771
BinContents + Shdr->sh_offset + 28 + IndCallDescSize);
771772
Result.FuncDescriptions = BinContents + Shdr->sh_offset + 32 +
772773
IndCallDescSize + IndCallTargetDescSize;
773-
Result.Strings = reinterpret_cast<char *>(
774+
Result.Strings = reinterpret_cast<const char *>(
774775
BinContents + Shdr->sh_offset + 32 + IndCallDescSize +
775776
IndCallTargetDescSize + FuncDescSize);
776777
return Result;
@@ -814,13 +815,14 @@ void printStats(const ProfileWriterContext &Ctx) {
814815
strCopy(StatPtr,
815816
"\nBOLT INSTRUMENTATION RUNTIME STATISTICS\n\nIndCallDescSize: ");
816817
StatPtr = intToStr(StatPtr,
817-
Ctx.FuncDescriptions -
818-
reinterpret_cast<uint8_t *>(Ctx.IndCallDescriptions),
818+
Ctx.FuncDescriptions - reinterpret_cast<const uint8_t *>(
819+
Ctx.IndCallDescriptions),
819820
10);
820821
StatPtr = strCopy(StatPtr, "\nFuncDescSize: ");
821-
StatPtr = intToStr(
822-
StatPtr,
823-
reinterpret_cast<uint8_t *>(Ctx.Strings) - Ctx.FuncDescriptions, 10);
822+
StatPtr = intToStr(StatPtr,
823+
reinterpret_cast<const uint8_t *>(Ctx.Strings) -
824+
Ctx.FuncDescriptions,
825+
10);
824826
StatPtr = strCopy(StatPtr, "\n__bolt_instr_num_ind_calls: ");
825827
StatPtr = intToStr(StatPtr, __bolt_instr_num_ind_calls, 10);
826828
StatPtr = strCopy(StatPtr, "\n__bolt_instr_num_funcs: ");
@@ -1549,7 +1551,7 @@ __bolt_instr_data_dump(int FD) {
15491551
Ctx.CallFlowTable->forEachElement(visitCallFlowEntry, FD, &Ctx);
15501552

15511553
__fsync(FD);
1552-
__munmap(Ctx.MMapPtr, Ctx.MMapSize);
1554+
__munmap((void *)Ctx.MMapPtr, Ctx.MMapSize);
15531555
__close(Ctx.FileDesc);
15541556
HashAlloc.destroy();
15551557
GlobalWriteProfileMutex->release();
@@ -1756,7 +1758,7 @@ extern "C" __attribute((naked)) void __bolt_instr_start()
17561758
"jal x1, __bolt_instr_setup\n"
17571759
RESTORE_ALL
17581760
"setup_symbol:\n"
1759-
"auipc x5, %%pcrel_hi(__bolt_start_trampoline)\n"
1761+
"auipc x5, %%pcrel_hi(__bolt_start_trampoline)\n"
17601762
"addi x5, x5, %%pcrel_lo(setup_symbol)\n"
17611763
"jr x5\n"
17621764
:::);
@@ -1788,8 +1790,8 @@ extern "C" void __bolt_instr_fini() {
17881790
__asm__ __volatile__(
17891791
SAVE_ALL
17901792
"fini_symbol:\n"
1791-
"auipc x5, %%pcrel_hi(__bolt_fini_trampoline)\n"
1792-
"addi x5, x5, %%pcrel_lo(fini_symbol)\n"
1793+
"auipc x5, %%pcrel_hi(__bolt_fini_trampoline)\n"
1794+
"addi x5, x5, %%pcrel_lo(fini_symbol)\n"
17931795
"jalr x1, 0(x5)\n"
17941796
RESTORE_ALL
17951797
:::);

clang-tools-extra/clang-tidy/ClangTidy.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,20 @@ getCheckNames(const ClangTidyOptions &Options,
505505
return Factory.getCheckNames();
506506
}
507507

508+
void filterCheckOptions(ClangTidyOptions &Options,
509+
const std::vector<std::string> &EnabledChecks) {
510+
ClangTidyOptions::OptionMap FilteredOptions;
511+
for (const auto &[OptionName, Value] : Options.CheckOptions) {
512+
const size_t CheckNameEndPos = OptionName.find('.');
513+
if (CheckNameEndPos == StringRef::npos)
514+
continue;
515+
const StringRef CheckName = OptionName.substr(0, CheckNameEndPos);
516+
if (llvm::binary_search(EnabledChecks, CheckName))
517+
FilteredOptions[OptionName] = Value;
518+
}
519+
Options.CheckOptions = std::move(FilteredOptions);
520+
}
521+
508522
ClangTidyOptions::OptionMap
509523
getCheckOptions(const ClangTidyOptions &Options,
510524
bool AllowEnablingAnalyzerAlphaCheckers) {

clang-tools-extra/clang-tidy/ClangTidy.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ ClangTidyOptions::OptionMap
7676
getCheckOptions(const ClangTidyOptions &Options,
7777
bool AllowEnablingAnalyzerAlphaCheckers);
7878

79+
/// Filters CheckOptions in \p Options to only include options specified in
80+
/// the \p EnabledChecks which is a sorted vector.
81+
void filterCheckOptions(ClangTidyOptions &Options,
82+
const std::vector<std::string> &EnabledChecks);
83+
7984
/// Run a set of clang-tidy checks on a set of files.
8085
///
8186
/// \param EnableCheckProfile If provided, it enables check profile collection

clang-tools-extra/clang-tidy/readability/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ add_clang_library(clangTidyReadabilityModule STATIC
5858
UniqueptrDeleteReleaseCheck.cpp
5959
UppercaseLiteralSuffixCheck.cpp
6060
UseAnyOfAllOfCheck.cpp
61+
UseConcisePreprocessorDirectivesCheck.cpp
6162
UseStdMinMaxCheck.cpp
6263

6364
LINK_LIBS

clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "UniqueptrDeleteReleaseCheck.h"
6262
#include "UppercaseLiteralSuffixCheck.h"
6363
#include "UseAnyOfAllOfCheck.h"
64+
#include "UseConcisePreprocessorDirectivesCheck.h"
6465
#include "UseStdMinMaxCheck.h"
6566

6667
namespace clang::tidy {
@@ -173,6 +174,8 @@ class ReadabilityModule : public ClangTidyModule {
173174
"readability-uppercase-literal-suffix");
174175
CheckFactories.registerCheck<UseAnyOfAllOfCheck>(
175176
"readability-use-anyofallof");
177+
CheckFactories.registerCheck<UseConcisePreprocessorDirectivesCheck>(
178+
"readability-use-concise-preprocessor-directives");
176179
CheckFactories.registerCheck<UseStdMinMaxCheck>(
177180
"readability-use-std-min-max");
178181
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//===--- UseConcisePreprocessorDirectivesCheck.cpp - clang-tidy -----------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "UseConcisePreprocessorDirectivesCheck.h"
10+
#include "clang/Basic/TokenKinds.h"
11+
#include "clang/Lex/Lexer.h"
12+
#include "clang/Lex/PPCallbacks.h"
13+
#include "clang/Lex/Preprocessor.h"
14+
15+
#include <array>
16+
17+
namespace clang::tidy::readability {
18+
19+
namespace {
20+
21+
class IfPreprocessorCallbacks final : public PPCallbacks {
22+
public:
23+
IfPreprocessorCallbacks(ClangTidyCheck &Check, const Preprocessor &PP)
24+
: Check(Check), PP(PP) {}
25+
26+
void If(SourceLocation Loc, SourceRange ConditionRange,
27+
ConditionValueKind) override {
28+
impl(Loc, ConditionRange, {"ifdef", "ifndef"});
29+
}
30+
31+
void Elif(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind,
32+
SourceLocation) override {
33+
if (PP.getLangOpts().C23 || PP.getLangOpts().CPlusPlus23)
34+
impl(Loc, ConditionRange, {"elifdef", "elifndef"});
35+
}
36+
37+
private:
38+
void impl(SourceLocation DirectiveLoc, SourceRange ConditionRange,
39+
const std::array<llvm::StringLiteral, 2> &Replacements) {
40+
// Lexer requires its input range to be null-terminated.
41+
SmallString<128> Condition =
42+
Lexer::getSourceText(CharSourceRange::getTokenRange(ConditionRange),
43+
PP.getSourceManager(), PP.getLangOpts());
44+
Condition.push_back('\0');
45+
Lexer Lex(DirectiveLoc, PP.getLangOpts(), Condition.data(),
46+
Condition.data(), Condition.data() + Condition.size() - 1);
47+
Token Tok;
48+
bool Inverted = false; // The inverted form of #*def is #*ndef.
49+
std::size_t ParensNestingDepth = 0;
50+
for (;;) {
51+
if (Lex.LexFromRawLexer(Tok))
52+
return;
53+
54+
if (Tok.is(tok::TokenKind::exclaim) ||
55+
(PP.getLangOpts().CPlusPlus &&
56+
Tok.is(tok::TokenKind::raw_identifier) &&
57+
Tok.getRawIdentifier() == "not"))
58+
Inverted = !Inverted;
59+
else if (Tok.is(tok::TokenKind::l_paren))
60+
++ParensNestingDepth;
61+
else
62+
break;
63+
}
64+
65+
if (Tok.isNot(tok::TokenKind::raw_identifier) ||
66+
Tok.getRawIdentifier() != "defined")
67+
return;
68+
69+
bool NoMoreTokens = Lex.LexFromRawLexer(Tok);
70+
if (Tok.is(tok::TokenKind::l_paren)) {
71+
if (NoMoreTokens)
72+
return;
73+
++ParensNestingDepth;
74+
NoMoreTokens = Lex.LexFromRawLexer(Tok);
75+
}
76+
77+
if (Tok.isNot(tok::TokenKind::raw_identifier))
78+
return;
79+
const StringRef Macro = Tok.getRawIdentifier();
80+
81+
while (!NoMoreTokens) {
82+
NoMoreTokens = Lex.LexFromRawLexer(Tok);
83+
if (Tok.isNot(tok::TokenKind::r_paren))
84+
return;
85+
--ParensNestingDepth;
86+
}
87+
88+
if (ParensNestingDepth != 0)
89+
return;
90+
91+
Check.diag(
92+
DirectiveLoc,
93+
"preprocessor condition can be written more concisely using '#%0'")
94+
<< FixItHint::CreateReplacement(DirectiveLoc, Replacements[Inverted])
95+
<< FixItHint::CreateReplacement(ConditionRange, Macro)
96+
<< Replacements[Inverted];
97+
}
98+
99+
ClangTidyCheck &Check;
100+
const Preprocessor &PP;
101+
};
102+
103+
} // namespace
104+
105+
void UseConcisePreprocessorDirectivesCheck::registerPPCallbacks(
106+
const SourceManager &, Preprocessor *PP, Preprocessor *) {
107+
PP->addPPCallbacks(std::make_unique<IfPreprocessorCallbacks>(*this, *PP));
108+
}
109+
110+
} // namespace clang::tidy::readability
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===--- UseConcisePreprocessorDirectivesCheck.h - clang-tidy ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECONCISEPREPROCESSORDIRECTIVESCHECK_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECONCISEPREPROCESSORDIRECTIVESCHECK_H
11+
12+
#include "../ClangTidyCheck.h"
13+
14+
namespace clang::tidy::readability {
15+
16+
/// Finds uses of ``#if`` that can be simplified to ``#ifdef`` or ``#ifndef``
17+
/// and, since C23 and C++23, uses of ``#elif`` that can be simplified to
18+
/// ``#elifdef`` or ``#elifndef``.
19+
///
20+
/// User-facing documentation:
21+
/// https://clang.llvm.org/extra/clang-tidy/checks/readability/use-concise-preprocessor-directives.html
22+
class UseConcisePreprocessorDirectivesCheck : public ClangTidyCheck {
23+
public:
24+
using ClangTidyCheck::ClangTidyCheck;
25+
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
26+
Preprocessor *ModuleExpanderPP) override;
27+
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
28+
return true;
29+
}
30+
};
31+
32+
} // namespace clang::tidy::readability
33+
34+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECONCISEPREPROCESSORDIRECTIVESCHECK_H

clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -659,9 +659,10 @@ int clangTidyMain(int argc, const char **argv) {
659659
if (DumpConfig) {
660660
EffectiveOptions.CheckOptions =
661661
getCheckOptions(EffectiveOptions, AllowEnablingAnalyzerAlphaCheckers);
662-
llvm::outs() << configurationAsText(ClangTidyOptions::getDefaults().merge(
663-
EffectiveOptions, 0))
664-
<< "\n";
662+
ClangTidyOptions OptionsToDump =
663+
ClangTidyOptions::getDefaults().merge(EffectiveOptions, 0);
664+
filterCheckOptions(OptionsToDump, EnabledChecks);
665+
llvm::outs() << configurationAsText(OptionsToDump) << "\n";
665666
return 0;
666667
}
667668

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ Improvements to clang-tidy
108108
- Improved :program:`clang-tidy-diff.py` script. Add the `-warnings-as-errors`
109109
argument to treat warnings as errors.
110110

111+
- Improved :program:`clang-tidy` to show `CheckOptions` only for checks enabled
112+
in `Checks` when running ``--dump-config``.
113+
111114
- Fixed bug in :program:`clang-tidy` by which `HeaderFilterRegex` did not take
112115
effect when passed via the `.clang-tidy` file.
113116

@@ -166,6 +169,13 @@ New checks
166169
Finds potentially erroneous calls to ``reset`` method on smart pointers when
167170
the pointee type also has a ``reset`` method.
168171

172+
- New :doc:`readability-use-concise-preprocessor-directives
173+
<clang-tidy/checks/readability/use-concise-preprocessor-directives>` check.
174+
175+
Finds uses of ``#if`` that can be simplified to ``#ifdef`` or ``#ifndef`` and,
176+
since C23 and C++23, uses of ``#elif`` that can be simplified to ``#elifdef``
177+
or ``#elifndef``.
178+
169179
New check aliases
170180
^^^^^^^^^^^^^^^^^
171181

0 commit comments

Comments
 (0)