Skip to content

Commit 32aee39

Browse files
committed
Merge from 'main' to 'sycl-web' (88 commits)
CONFLICT (content): Merge conflict in clang/lib/CodeGen/CodeGenAction.cpp
2 parents f680bb8 + bac6cd5 commit 32aee39

File tree

288 files changed

+13219
-7690
lines changed

Some content is hidden

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

288 files changed

+13219
-7690
lines changed

clang-tools-extra/clangd/Config.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "llvm/ADT/Optional.h"
3030
#include "llvm/ADT/StringMap.h"
3131
#include "llvm/ADT/StringSet.h"
32+
#include "llvm/Support/Regex.h"
33+
#include <functional>
3234
#include <string>
3335
#include <vector>
3436

@@ -100,6 +102,12 @@ struct Config {
100102
} ClangTidy;
101103

102104
UnusedIncludesPolicy UnusedIncludes = None;
105+
106+
/// IncludeCleaner will not diagnose usages of these headers matched by
107+
/// these regexes.
108+
struct {
109+
std::vector<std::function<bool(llvm::StringRef)>> IgnoreHeader;
110+
} Includes;
103111
} Diagnostics;
104112

105113
/// Style of the codebase.

clang-tools-extra/clangd/ConfigCompile.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@
4545
#include "llvm/Support/SMLoc.h"
4646
#include "llvm/Support/SourceMgr.h"
4747
#include <algorithm>
48+
#include <memory>
4849
#include <string>
50+
#include <vector>
4951

5052
namespace clang {
5153
namespace clangd {
@@ -432,6 +434,7 @@ struct FragmentCompiler {
432434
Out.Apply.push_back([Val](const Params &, Config &C) {
433435
C.Diagnostics.UnusedIncludes = *Val;
434436
});
437+
compile(std::move(F.Includes));
435438

436439
compile(std::move(F.ClangTidy));
437440
}
@@ -507,6 +510,41 @@ struct FragmentCompiler {
507510
}
508511
}
509512

513+
void compile(Fragment::DiagnosticsBlock::IncludesBlock &&F) {
514+
#ifdef CLANGD_PATH_CASE_INSENSITIVE
515+
static llvm::Regex::RegexFlags Flags = llvm::Regex::IgnoreCase;
516+
#else
517+
static llvm::Regex::RegexFlags Flags = llvm::Regex::NoFlags;
518+
#endif
519+
auto Filters = std::make_shared<std::vector<llvm::Regex>>();
520+
for (auto &HeaderPattern : F.IgnoreHeader) {
521+
// Anchor on the right.
522+
std::string AnchoredPattern = "(" + *HeaderPattern + ")$";
523+
llvm::Regex CompiledRegex(AnchoredPattern, Flags);
524+
std::string RegexError;
525+
if (!CompiledRegex.isValid(RegexError)) {
526+
diag(Warning,
527+
llvm::formatv("Invalid regular expression '{0}': {1}",
528+
*HeaderPattern, RegexError)
529+
.str(),
530+
HeaderPattern.Range);
531+
continue;
532+
}
533+
Filters->push_back(std::move(CompiledRegex));
534+
}
535+
if (Filters->empty())
536+
return;
537+
auto Filter = [Filters](llvm::StringRef Path) {
538+
for (auto &Regex : *Filters)
539+
if (Regex.match(Path))
540+
return true;
541+
return false;
542+
};
543+
Out.Apply.push_back([Filter](const Params &, Config &C) {
544+
C.Diagnostics.Includes.IgnoreHeader.emplace_back(Filter);
545+
});
546+
}
547+
510548
void compile(Fragment::CompletionBlock &&F) {
511549
if (F.AllScopes) {
512550
Out.Apply.push_back(

clang-tools-extra/clangd/ConfigFragment.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,15 @@ struct Fragment {
232232
/// - None
233233
llvm::Optional<Located<std::string>> UnusedIncludes;
234234

235+
/// Controls IncludeCleaner diagnostics.
236+
struct IncludesBlock {
237+
/// Regexes that will be used to avoid diagnosing certain includes as
238+
/// unused or missing. These can match any suffix of the header file in
239+
/// question.
240+
std::vector<Located<std::string>> IgnoreHeader;
241+
};
242+
IncludesBlock Includes;
243+
235244
/// Controls how clang-tidy will run over the code base.
236245
///
237246
/// The settings are merged with any settings found in .clang-tidy

clang-tools-extra/clangd/IncludeCleaner.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@
2323
#include "clang/Lex/HeaderSearch.h"
2424
#include "clang/Lex/Preprocessor.h"
2525
#include "clang/Tooling/Syntax/Tokens.h"
26+
#include "llvm/ADT/ArrayRef.h"
2627
#include "llvm/ADT/STLFunctionalExtras.h"
28+
#include "llvm/ADT/SmallString.h"
2729
#include "llvm/ADT/StringSet.h"
2830
#include "llvm/Support/FormatVariadic.h"
2931
#include "llvm/Support/Path.h"
32+
#include "llvm/Support/Regex.h"
33+
#include <functional>
3034

3135
namespace clang {
3236
namespace clangd {
@@ -233,7 +237,8 @@ void findReferencedMacros(const SourceManager &SM, Preprocessor &PP,
233237
}
234238
}
235239

236-
static bool mayConsiderUnused(const Inclusion &Inc, ParsedAST &AST) {
240+
static bool mayConsiderUnused(const Inclusion &Inc, ParsedAST &AST,
241+
const Config &Cfg) {
237242
if (Inc.BehindPragmaKeep)
238243
return false;
239244

@@ -258,6 +263,15 @@ static bool mayConsiderUnused(const Inclusion &Inc, ParsedAST &AST) {
258263
FE->getName());
259264
return false;
260265
}
266+
for (auto &Filter : Cfg.Diagnostics.Includes.IgnoreHeader) {
267+
// Convert the path to Unix slashes and try to match aginast the fiilter.
268+
llvm::SmallString<64> Path(Inc.Resolved);
269+
llvm::sys::path::native(Path, llvm::sys::path::Style::posix);
270+
if (Filter(Inc.Resolved)) {
271+
dlog("{0} header is filtered out by the configuration", FE->getName());
272+
return false;
273+
}
274+
}
261275
return true;
262276
}
263277

@@ -369,6 +383,7 @@ getUnused(ParsedAST &AST,
369383
const llvm::DenseSet<IncludeStructure::HeaderID> &ReferencedFiles,
370384
const llvm::StringSet<> &ReferencedPublicHeaders) {
371385
trace::Span Tracer("IncludeCleaner::getUnused");
386+
const Config &Cfg = Config::current();
372387
std::vector<const Inclusion *> Unused;
373388
for (const Inclusion &MFI : AST.getIncludeStructure().MainFileIncludes) {
374389
if (!MFI.HeaderID)
@@ -377,7 +392,7 @@ getUnused(ParsedAST &AST,
377392
continue;
378393
auto IncludeID = static_cast<IncludeStructure::HeaderID>(*MFI.HeaderID);
379394
bool Used = ReferencedFiles.contains(IncludeID);
380-
if (!Used && !mayConsiderUnused(MFI, AST)) {
395+
if (!Used && !mayConsiderUnused(MFI, AST, Cfg)) {
381396
dlog("{0} was not used, but is not eligible to be diagnosed as unused",
382397
MFI.Written);
383398
continue;

clang-tools-extra/clangd/TUScheduler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ ASTWorker::~ASTWorker() {
798798

799799
void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags,
800800
bool ContentChanged) {
801-
std::string TaskName = llvm::formatv("Update ({0})", Inputs.Version);
801+
llvm::StringLiteral TaskName = "Update";
802802
auto Task = [=]() mutable {
803803
// Get the actual command as `Inputs` does not have a command.
804804
// FIXME: some build systems like Bazel will take time to preparing

clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,24 @@ TEST_F(ConfigCompileTests, DiagnosticsIncludeCleaner) {
263263
EXPECT_TRUE(compileAndApply());
264264
EXPECT_EQ(Conf.Diagnostics.UnusedIncludes,
265265
Config::UnusedIncludesPolicy::Strict);
266+
267+
Frag = {};
268+
EXPECT_TRUE(Conf.Diagnostics.Includes.IgnoreHeader.empty())
269+
<< Conf.Diagnostics.Includes.IgnoreHeader.size();
270+
Frag.Diagnostics.Includes.IgnoreHeader.push_back(
271+
Located<std::string>("foo.h"));
272+
Frag.Diagnostics.Includes.IgnoreHeader.push_back(
273+
Located<std::string>(".*inc"));
274+
EXPECT_TRUE(compileAndApply());
275+
auto HeaderFilter = [this](llvm::StringRef Path) {
276+
for (auto &Filter : Conf.Diagnostics.Includes.IgnoreHeader) {
277+
if (Filter(Path))
278+
return true;
279+
}
280+
return false;
281+
};
282+
EXPECT_TRUE(HeaderFilter("foo.h"));
283+
EXPECT_FALSE(HeaderFilter("bar.h"));
266284
}
267285

268286
TEST_F(ConfigCompileTests, DiagnosticSuppression) {

clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,8 @@ TEST(DiagnosticsTest, IncludeCleaner) {
17381738
]]
17391739
#include "used.h"
17401740
1741+
#include "ignore.h"
1742+
17411743
#include <system_header.h>
17421744
17431745
void foo() {
@@ -1754,12 +1756,19 @@ TEST(DiagnosticsTest, IncludeCleaner) {
17541756
#pragma once
17551757
void used() {}
17561758
)cpp";
1759+
TU.AdditionalFiles["ignore.h"] = R"cpp(
1760+
#pragma once
1761+
void ignore() {}
1762+
)cpp";
17571763
TU.AdditionalFiles["system/system_header.h"] = "";
17581764
TU.ExtraArgs = {"-isystem" + testPath("system")};
17591765
// Off by default.
17601766
EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty());
17611767
Config Cfg;
17621768
Cfg.Diagnostics.UnusedIncludes = Config::UnusedIncludesPolicy::Strict;
1769+
// Set filtering.
1770+
Cfg.Diagnostics.Includes.IgnoreHeader.emplace_back(
1771+
[](llvm::StringRef Header) { return Header.endswith("ignore.h"); });
17631772
WithContextValue WithCfg(Config::Key, std::move(Cfg));
17641773
EXPECT_THAT(
17651774
*TU.build().getDiagnostics(),

clang/docs/ClangCommandLineReference.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ Generate Interface Stub Files, emit merged text not binary.
801801

802802
Extract API information
803803

804-
.. option:: -fopenmp-new-driver
804+
.. option:: -fopenmp-new-driver, fno-openmp-new-driver
805805

806806
Use the new driver for OpenMP offloading.
807807

clang/docs/MisExpect.rst

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
===================
2+
Misexpect
3+
===================
4+
.. contents::
5+
6+
.. toctree::
7+
:maxdepth: 1
8+
9+
When developers use ``llvm.expect`` intrinsics, i.e., through use of
10+
``__builtin_expect(...)``, they are trying to communicate how their code is
11+
expected to behave at runtime to the optimizer. These annotations, however, can
12+
be incorrect for a variety of reasons: changes to the code base invalidate them
13+
silently, the developer mis-annotated them (e.g., using ``LIKELY`` instead of
14+
``UNLIKELY``), or perhaps they assumed something incorrectly when they wrote
15+
the annotation. Regardless of why, it is useful to detect these situations so
16+
that the optimizer can make more useful decisions about the code.
17+
18+
MisExpect diagnostics are intended to help developers identify and address
19+
these situations, by comparing the branch weights added by the ``llvm.expect``
20+
intrinsic to those collected through profiling. Whenever these values are
21+
mismatched, a diagnostic is surfaced to the user. Details on how the checks
22+
operate in the LLVM backed can be found in LLVM's documentation.
23+
24+
By default MisExpect checking is quite strict, because the use of the
25+
``llvm.expect`` intrinsic is designed for specialized cases, where the outcome
26+
of a condition is severely skewed. As a result, the optimizer can be extremely
27+
aggressive, which can result in performance degradation if the outcome is less
28+
predictable than the annotation suggests. Even when the annotation is correct
29+
90% of the time, it may be beneficial to either remove the annotation or to use
30+
a different intrinsic that can communicate the probability more directly.
31+
32+
Because this may be too strict, MisExpect diagnostics are not enabled by
33+
default, and support an additional flag to tolerate some deviation from the
34+
exact thresholds. The ``-fdiagnostic-misexpect-tolerance=N`` accepts
35+
deviations when comparing branch weights within ``N%`` of the expected values.
36+
So passing ``-fdiagnostic-misexpect-tolerance=5`` will not report diagnostic messages
37+
if the branch weight from the profile is within 5% of the weight added by
38+
the ``llvm.expect`` intrinsic.
39+
40+
MisExpect diagnostics are also available in the form of optimization remarks,
41+
which can be serialized and processed through the ``opt-viewer.py``
42+
scripts in LLVM.
43+
44+
.. option:: -Rpass=misexpect
45+
46+
Enables optimization remarks for misexpect when profiling data conflicts with
47+
use of ``llvm.expect`` intrinsics.
48+
49+
50+
.. option:: -Wmisexpect
51+
52+
Enables misexpect warnings when profiling data conflicts with use of
53+
``llvm.expect`` intrinsics.
54+
55+
.. option:: -fdiagnostic-misexpect-tolerance=N
56+
57+
Relaxes misexpect checking to tolerate profiling values within N% of the
58+
expected branch weight. e.g., a value of ``N=5`` allows misexpect to check against
59+
``0.95 * Threshold``
60+
61+
LLVM supports 4 types of profile formats: Frontend, IR, CS-IR, and
62+
Sampling. MisExpect Diagnostics are compatible with all Profiling formats.
63+
64+
+----------------+--------------------------------------------------------------------------------------+
65+
| Profile Type | Description |
66+
+================+======================================================================================+
67+
| Frontend | Profiling instrumentation added during compilation by the frontend, i.e. ``clang`` |
68+
+----------------+--------------------------------------------------------------------------------------+
69+
| IR | Profiling instrumentation added during by the LLVM backend |
70+
+----------------+--------------------------------------------------------------------------------------+
71+
| CS-IR | Context Sensitive IR based profiles |
72+
+----------------+--------------------------------------------------------------------------------------+
73+
| Sampling | Profiles collected through sampling with external tools, such as ``perf`` on Linux |
74+
+----------------+--------------------------------------------------------------------------------------+
75+

clang/docs/OffloadingDesign.rst

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@ application using Clang.
1717
OpenMP Offloading
1818
=================
1919

20-
.. note::
21-
This documentation describes Clang's behavior using the new offloading
22-
driver. This currently must be enabled manually using
23-
``-fopenmp-new-driver``.
24-
2520
Clang supports OpenMP target offloading to several different architectures such
2621
as NVPTX, AMDGPU, X86_64, Arm, and PowerPC. Offloading code is generated by
2722
Clang and then executed using the ``libomptarget`` runtime and the associated
@@ -226,15 +221,15 @@ A fat binary is a binary file that contains information intended for another
226221
device. We create a fat object by embedding the output of the device compilation
227222
stage into the host as a named section. The output from the device compilation
228223
is passed to the host backend using the ``-fembed-offload-object`` flag. This
229-
inserts the object as a global in the host's IR. The section name contains the
230-
target triple and architecture that the data corresponds to for later use.
231-
Typically we will also add an extra string to the section name to prevent it
232-
from being merged with other sections if the user performs relocatable linking
233-
on the object.
224+
embeds the device image into the ``.llvm.offloading`` section using a special
225+
binary format that behaves like a string map. This binary format is used to
226+
bundle metadata about the image so the linker can associate the proper device
227+
linking action with the image. Each device image will start with the magic bytes
228+
``0x10FF10AD``.
234229

235230
.. code-block:: llvm
236231
237-
@llvm.embedded.object = private constant [1 x i8] c"\00", section ".llvm.offloading.nvptx64.sm_70."
232+
@llvm.embedded.object = private constant [1 x i8] c"\00", section ".llvm.offloading"
238233
239234
The device code will then be placed in the corresponding section one the backend
240235
is run on the host, creating a fat object. Using fat objects allows us to treat
@@ -250,7 +245,7 @@ will use this information when :ref:`Device Linking`.
250245
+==================================+====================================================================+
251246
| omp_offloading_entries | Offloading entry information (see :ref:`table-tgt_offload_entry`) |
252247
+----------------------------------+--------------------------------------------------------------------+
253-
| .llvm.offloading.<triple>.<arch> | Embedded device object file for the target device and architecture |
248+
| .llvm.offloading | Embedded device object file for the target device and architecture |
254249
+----------------------------------+--------------------------------------------------------------------+
255250

256251
.. _Device Linking:
@@ -262,9 +257,10 @@ Objects containing :ref:`table-offloading_sections` require special handling to
262257
create an executable device image. This is done using a Clang tool, see
263258
:doc:`ClangLinkerWrapper` for more information. This tool works as a wrapper
264259
over the host linking job. It scans the input object files for the offloading
265-
sections and runs the appropriate device linking action. The linked device image
266-
is then :ref:`wrapped <Device Binary Wrapping>` to create the symbols used to load the
267-
device image and link it with the host.
260+
section ``.llvm.offloading``. The device files stored in this section are then
261+
extracted and passed tot he appropriate linking job. The linked device image is
262+
then :ref:`wrapped <Device Binary Wrapping>` to create the symbols used to load
263+
the device image and link it with the host.
268264

269265
The linker wrapper tool supports linking bitcode files through link time
270266
optimization (LTO). This is used whenever the object files embedded in the host
@@ -438,19 +434,22 @@ This code is compiled using the following Clang flags.
438434
439435
$ clang++ -fopenmp -fopenmp-targets=nvptx64 -O3 zaxpy.cpp -c
440436
441-
The output section in the object file can be seen using the ``readelf`` utility
437+
The output section in the object file can be seen using the ``readelf`` utility.
438+
The ``.llvm.offloading`` section has the ``SHF_EXCLUDE`` flag so it will be
439+
removed from the final executable or shared library by the linker.
442440

443441
.. code-block:: text
444442
445443
$ llvm-readelf -WS zaxpy.o
446-
[Nr] Name Type
447-
...
448-
[34] omp_offloading_entries PROGBITS
449-
[35] .llvm.offloading.nvptx64-nvidia-cuda.sm_70 PROGBITS
444+
Section Headers:
445+
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
446+
[11] omp_offloading_entries PROGBITS 0000000000000000 0001f0 000040 00 A 0 0 1
447+
[12] .llvm.offloading PROGBITS 0000000000000000 000260 030950 00 E 0 0 8
448+
450449
451450
Compiling this file again will invoke the ``clang-linker-wrapper`` utility to
452451
extract and link the device code stored at the section named
453-
``.llvm.offloading.nvptx64-nvidia-cuda.sm_70`` and then use entries stored in
452+
``.llvm.offloading`` and then use entries stored in
454453
the section named ``omp_offloading_entries`` to create the symbols necessary for
455454
``libomptarget`` to register the device image and call the entry function.
456455

0 commit comments

Comments
 (0)