Skip to content

Commit 202ec31

Browse files
committed
Merge commit 'a6c09d40ed7fe076358429c0978838904c9cceae' into llvmspirv_pulldown
2 parents fa665c4 + a6c09d4 commit 202ec31

File tree

112 files changed

+7398
-11905
lines changed

Some content is hidden

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

112 files changed

+7398
-11905
lines changed

.ci/metrics/metrics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
# This means we essentially have a list of workflows sorted by creation date,
4444
# and that's all we can deduce from it. So for each iteration, we'll blindly
4545
# process the last N workflows.
46-
GITHUB_WORKFLOWS_MAX_PROCESS_COUNT = 1000
46+
GITHUB_WORKFLOWS_MAX_PROCESS_COUNT = 2000
4747
# Second reason for the cut: reaching a workflow older than X.
4848
# This means we will miss long-tails (exceptional jobs running for more than
4949
# X hours), but that's also the case with the count cutoff above.

bolt/lib/Target/AArch64/AArch64MCSymbolizer.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,39 @@ AArch64MCSymbolizer::adjustRelocation(const Relocation &Rel,
125125
// instruction pairs and will perform necessary adjustments.
126126
ErrorOr<uint64_t> SymbolValue = BC.getSymbolValue(*Rel.Symbol);
127127
assert(SymbolValue && "Symbol value should be set");
128-
(void)SymbolValue;
129-
130-
AdjustedRel.Symbol = BC.registerNameAtAddress("__BOLT_got_zero", 0, 0, 0);
131-
AdjustedRel.Addend = Rel.Value;
128+
const uint64_t SymbolPageAddr = *SymbolValue & ~0xfffULL;
129+
130+
// Check if defined symbol and GOT are on the same page. If they are not,
131+
// disambiguate the operand.
132+
if (BC.MIB->isADRP(Inst) && Rel.Addend == 0 &&
133+
SymbolPageAddr == Rel.Value &&
134+
!isPageAddressValidForGOT(SymbolPageAddr)) {
135+
AdjustedRel.Type = ELF::R_AARCH64_ADR_PREL_PG_HI21;
136+
} else {
137+
AdjustedRel.Symbol = BC.registerNameAtAddress("__BOLT_got_zero", 0, 0, 0);
138+
AdjustedRel.Addend = Rel.Value;
139+
}
132140
}
133141

134142
return AdjustedRel;
135143
}
136144

145+
bool AArch64MCSymbolizer::isPageAddressValidForGOT(uint64_t PageAddress) const {
146+
assert(!(PageAddress & 0xfffULL) && "Page address not aligned at 4KB");
147+
148+
ErrorOr<BinarySection &> GOT =
149+
Function.getBinaryContext().getUniqueSectionByName(".got");
150+
if (!GOT || !GOT->getSize())
151+
return false;
152+
153+
const uint64_t GOTFirstPageAddress = GOT->getAddress() & ~0xfffULL;
154+
const uint64_t GOTLastPageAddress =
155+
(GOT->getAddress() + GOT->getSize() - 1) & ~0xfffULL;
156+
157+
return PageAddress >= GOTFirstPageAddress &&
158+
PageAddress <= GOTLastPageAddress;
159+
}
160+
137161
void AArch64MCSymbolizer::tryAddingPcLoadReferenceComment(raw_ostream &CStream,
138162
int64_t Value,
139163
uint64_t Address) {}

bolt/lib/Target/AArch64/AArch64MCSymbolizer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ class AArch64MCSymbolizer : public MCSymbolizer {
2828
std::optional<Relocation> adjustRelocation(const Relocation &Rel,
2929
const MCInst &Inst) const;
3030

31+
/// Return true if \p PageAddress is a valid page address for .got section.
32+
bool isPageAddressValidForGOT(uint64_t PageAddress) const;
33+
3134
public:
3235
AArch64MCSymbolizer(BinaryFunction &Function, bool CreateNewSymbols = true)
3336
: MCSymbolizer(*Function.getBinaryContext().Ctx.get(), nullptr),
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
## Check that BOLT symbolizer properly handles loads from GOT, including
2+
## instruction sequences changed/relaxed by the linker.
3+
4+
# RUN: split-file %s %t
5+
6+
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %t/main.s \
7+
# RUN: -o %t/main.o
8+
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %t/near.s \
9+
# RUN: -o %t/near.o
10+
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %t/far.s \
11+
# RUN: -o %t/far.o
12+
# RUN: %clang %cflags %t/main.o %t/near.o %t/far.o -o %t/main.exe -Wl,-q -static
13+
# RUN: llvm-bolt %t/main.exe -o %t/main.bolt --keep-nops --print-disasm \
14+
# RUN: --print-only=_start | FileCheck %s
15+
16+
#--- main.s
17+
18+
.text
19+
.globl _start
20+
.p2align 2
21+
.type _start, @function
22+
# CHECK-LABEL: _start
23+
_start:
24+
25+
## Function address load relaxable into nop+adr.
26+
# CHECK: nop
27+
# CHECK-NEXT: adr x0, near
28+
adrp x0, :got:near
29+
ldr x0, [x0, :got_lo12:near]
30+
31+
## Function address load relaxable into adrp+add.
32+
# CHECK-NEXT: adrp x1, far
33+
# CHECK-NEXT: add x1, x1, :lo12:far
34+
adrp x1, :got:far
35+
ldr x1, [x1, :got_lo12:far]
36+
37+
## Non-relaxable due to the instruction in-between.
38+
# CHECK-NEXT: adrp x2, __BOLT_got_zero
39+
# CHECK-NEXT: nop
40+
# CHECK-NEXT: ldr x2, [x2, :lo12:__BOLT_got_zero{{.*}}]
41+
adrp x2, :got:near
42+
nop
43+
ldr x2, [x2, :got_lo12:near]
44+
45+
## Load data object with local visibility. Relaxable into adrp+add.
46+
# CHECK-NEXT: adrp x3, "local_far_data/1"
47+
# CHECK-NEXT: add x3, x3, :lo12:"local_far_data/1"
48+
adrp x3, :got:local_far_data
49+
ldr x3, [x3, :got_lo12:local_far_data]
50+
51+
## Global data reference relaxable into adrp+add.
52+
# CHECK-NEXT: adrp x4, far_data
53+
# CHECK-NEXT: add x4, x4, :lo12:far_data
54+
adrp x4, :got:far_data
55+
ldr x4, [x4, :got_lo12:far_data]
56+
57+
ret
58+
.size _start, .-_start
59+
60+
.weak near
61+
.weak far
62+
.weak far_data
63+
64+
## Data object separated by more than 1MB from _start.
65+
.data
66+
.type local_far_data, @object
67+
local_far_data:
68+
.xword 0
69+
.size local_far_data, .-local_far_data
70+
71+
#--- near.s
72+
73+
.text
74+
.globl near
75+
.type near, @function
76+
near:
77+
ret
78+
.size near, .-near
79+
80+
#--- far.s
81+
82+
.text
83+
84+
## Insert 1MB of empty space to make objects after it unreachable by adr
85+
## instructions in _start.
86+
.space 0x100000
87+
88+
.globl far
89+
.type far, @function
90+
far:
91+
ret
92+
.size far, .-far
93+
94+
.data
95+
.globl far_data
96+
.type far_data, @object
97+
far_data:
98+
.xword 0
99+
.size far_data, .-far_data
100+

clang/docs/LanguageExtensions.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,6 +1912,40 @@ A simplistic usage example as might be seen in standard C++ headers follows:
19121912
// Emulate type trait for compatibility with other compilers.
19131913
#endif
19141914

1915+
1916+
.. _builtin_structured_binding_size-doc:
1917+
1918+
__builtin_structured_binding_size (C++)
1919+
---------------------------------------
1920+
1921+
The ``__builtin_structured_binding_size(T)`` type trait returns
1922+
the *structured binding size* ([dcl.struct.bind]) of type ``T``
1923+
1924+
This is equivalent to the size of the pack ``p`` in ``auto&& [...p] = declval<T&>();``.
1925+
If the argument cannot be decomposed, ``__builtin_structured_binding_size(T)``
1926+
is not a valid expression (``__builtin_structured_binding_size`` is SFINAE-friendly).
1927+
1928+
builtin arrays, builtin SIMD vectors,
1929+
builtin complex types, *tuple-like* types, and decomposable class types
1930+
are decomposable types.
1931+
1932+
A type is considered a valid *tuple-like* if ``std::tuple_size_v<T>`` is a valid expression,
1933+
even if there is no valid ``std::tuple_element`` specialization or suitable
1934+
``get`` function for that type.
1935+
1936+
.. code-block:: c++
1937+
1938+
template<std::size_t Idx, typename T>
1939+
requires (Idx < __builtin_structured_binding_size(T))
1940+
decltype(auto) constexpr get_binding(T&& obj) {
1941+
auto && [...p] = std::forward<T>(obj);
1942+
return p...[Idx];
1943+
}
1944+
struct S { int a = 0, b = 42; };
1945+
static_assert(__builtin_structured_binding_size(S) == 2);
1946+
static_assert(get_binding<1>(S{}) == 42);
1947+
1948+
19151949
Blocks
19161950
======
19171951

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ What's New in Clang |release|?
7474
C++ Language Changes
7575
--------------------
7676

77+
- Added a :ref:`__builtin_structured_binding_size <builtin_structured_binding_size-doc>` (T)
78+
builtin that returns the number of structured bindings that would be produced by destructuring ``T``.
79+
7780
- Similarly to GCC, Clang now supports constant expressions in
7881
the strings of a GNU ``asm`` statement.
7982

clang/include/clang/AST/ExprCXX.h

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include <cstdint>
5252
#include <memory>
5353
#include <optional>
54+
#include <variant>
5455

5556
namespace clang {
5657

@@ -2765,27 +2766,27 @@ class CXXPseudoDestructorExpr : public Expr {
27652766
/// \endcode
27662767
class TypeTraitExpr final
27672768
: public Expr,
2768-
private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> {
2769+
private llvm::TrailingObjects<TypeTraitExpr, APValue, TypeSourceInfo *> {
27692770
/// The location of the type trait keyword.
27702771
SourceLocation Loc;
27712772

27722773
/// The location of the closing parenthesis.
27732774
SourceLocation RParenLoc;
27742775

2775-
// Note: The TypeSourceInfos for the arguments are allocated after the
2776-
// TypeTraitExpr.
2777-
27782776
TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
2779-
ArrayRef<TypeSourceInfo *> Args,
2780-
SourceLocation RParenLoc,
2781-
bool Value);
2777+
ArrayRef<TypeSourceInfo *> Args, SourceLocation RParenLoc,
2778+
std::variant<bool, APValue> Value);
27822779

27832780
TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) {}
27842781

27852782
size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
27862783
return getNumArgs();
27872784
}
27882785

2786+
size_t numTrailingObjects(OverloadToken<APValue>) const {
2787+
return TypeTraitExprBits.IsBooleanTypeTrait ? 0 : 1;
2788+
}
2789+
27892790
public:
27902791
friend class ASTStmtReader;
27912792
friend class ASTStmtWriter;
@@ -2798,19 +2799,34 @@ class TypeTraitExpr final
27982799
SourceLocation RParenLoc,
27992800
bool Value);
28002801

2802+
static TypeTraitExpr *Create(const ASTContext &C, QualType T,
2803+
SourceLocation Loc, TypeTrait Kind,
2804+
ArrayRef<TypeSourceInfo *> Args,
2805+
SourceLocation RParenLoc, APValue Value);
2806+
28012807
static TypeTraitExpr *CreateDeserialized(const ASTContext &C,
2808+
bool IsStoredAsBool,
28022809
unsigned NumArgs);
28032810

28042811
/// Determine which type trait this expression uses.
28052812
TypeTrait getTrait() const {
28062813
return static_cast<TypeTrait>(TypeTraitExprBits.Kind);
28072814
}
28082815

2809-
bool getValue() const {
2810-
assert(!isValueDependent());
2816+
bool isStoredAsBoolean() const {
2817+
return TypeTraitExprBits.IsBooleanTypeTrait;
2818+
}
2819+
2820+
bool getBoolValue() const {
2821+
assert(!isValueDependent() && TypeTraitExprBits.IsBooleanTypeTrait);
28112822
return TypeTraitExprBits.Value;
28122823
}
28132824

2825+
const APValue &getAPValue() const {
2826+
assert(!isValueDependent() && !TypeTraitExprBits.IsBooleanTypeTrait);
2827+
return *getTrailingObjects<APValue>();
2828+
}
2829+
28142830
/// Determine the number of arguments to this type trait.
28152831
unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; }
28162832

clang/include/clang/AST/Stmt.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -954,11 +954,13 @@ class alignas(void *) Stmt {
954954
LLVM_PREFERRED_TYPE(TypeTrait)
955955
unsigned Kind : 8;
956956

957-
/// If this expression is not value-dependent, this indicates whether
958-
/// the trait evaluated true or false.
959957
LLVM_PREFERRED_TYPE(bool)
960-
unsigned Value : 1;
958+
unsigned IsBooleanTypeTrait : 1;
961959

960+
/// If this expression is a non value-dependent boolean trait,
961+
/// this indicates whether the trait evaluated true or false.
962+
LLVM_PREFERRED_TYPE(bool)
963+
unsigned Value : 1;
962964
/// The number of arguments to this type trait. According to [implimits]
963965
/// 8 bits would be enough, but we require (and test for) at least 16 bits
964966
/// to mirror FunctionType.

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,8 @@ def err_decomp_decl_std_tuple_size_not_constant : Error<
659659
"is not a valid integral constant expression">;
660660
def note_in_binding_decl_init : Note<
661661
"in implicit initialization of binding declaration %0">;
662+
def err_arg_is_not_destructurable : Error<
663+
"type %0 cannot be decomposed">;
662664

663665
def err_std_type_trait_not_class_template : Error<
664666
"unsupported standard library implementation: "

clang/include/clang/Basic/TokenKinds.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,8 +560,8 @@ TYPE_TRAIT_2(__reference_converts_from_temporary, ReferenceConvertsFromTemporary
560560
// IsDeducible is only used internally by clang for CTAD implementation and
561561
// is not exposed to users.
562562
TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
563-
564563
TYPE_TRAIT_1(__is_bitwise_cloneable, IsBitwiseCloneable, KEYALL)
564+
TYPE_TRAIT_1(__builtin_structured_binding_size, StructuredBindingSize, KEYCXX)
565565

566566
// Embarcadero Expression Traits
567567
EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6137,7 +6137,8 @@ class Sema final : public SemaBase {
61376137
RecordDecl *ClassDecl,
61386138
const IdentifierInfo *Name);
61396139

6140-
unsigned GetDecompositionElementCount(QualType DecompType);
6140+
std::optional<unsigned int> GetDecompositionElementCount(QualType DecompType,
6141+
SourceLocation Loc);
61416142
void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD);
61426143

61436144
/// Stack containing information needed when in C++2a an 'auto' is encountered

clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H
1111

1212
#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
13+
#include "clang/Tooling/DependencyScanning/InProcessModuleCache.h"
1314
#include "llvm/ADT/BitmaskEnum.h"
1415

1516
namespace clang {
@@ -99,6 +100,8 @@ class DependencyScanningService {
99100
return SharedCache;
100101
}
101102

103+
ModuleCacheMutexes &getModuleCacheMutexes() { return ModCacheMutexes; }
104+
102105
private:
103106
const ScanningMode Mode;
104107
const ScanningOutputFormat Format;
@@ -110,6 +113,8 @@ class DependencyScanningService {
110113
const bool TraceVFS;
111114
/// The global file system cache.
112115
DependencyScanningFilesystemSharedCache SharedCache;
116+
/// The global module cache mutexes.
117+
ModuleCacheMutexes ModCacheMutexes;
113118
};
114119

115120
} // end namespace dependencies
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===----------------------------------------------------------------------===//
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_TOOLING_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H
10+
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H
11+
12+
#include "clang/Serialization/ModuleCache.h"
13+
#include "llvm/ADT/StringMap.h"
14+
15+
#include <shared_mutex>
16+
17+
namespace clang {
18+
namespace tooling {
19+
namespace dependencies {
20+
struct ModuleCacheMutexes {
21+
std::mutex Mutex;
22+
llvm::StringMap<std::unique_ptr<std::shared_mutex>> Map;
23+
};
24+
25+
IntrusiveRefCntPtr<ModuleCache>
26+
makeInProcessModuleCache(ModuleCacheMutexes &Mutexes);
27+
} // namespace dependencies
28+
} // namespace tooling
29+
} // namespace clang
30+
31+
#endif

0 commit comments

Comments
 (0)