Skip to content

Commit 10d4e1c

Browse files
authored
Merge branch 'main' into orc-fix-waitingongraph-coalescer-remove
2 parents 383c513 + e737f67 commit 10d4e1c

File tree

421 files changed

+15562
-3702
lines changed

Some content is hidden

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

421 files changed

+15562
-3702
lines changed

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,12 @@ class MCPlusBuilder {
632632
return false;
633633
}
634634

635+
/// Generate the matching pointer authentication instruction from a fused
636+
/// pauth-and-return instruction.
637+
virtual void createMatchingAuth(const MCInst &AuthAndRet, MCInst &Auth) {
638+
llvm_unreachable("not implemented");
639+
}
640+
635641
/// Returns the register used as a return address. Returns std::nullopt if
636642
/// not applicable, such as reading the return address from a system register
637643
/// or from the stack.

bolt/lib/Passes/Inliner.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,13 @@ InliningInfo getInliningInfo(const BinaryFunction &BF) {
195195
if (BC.MIB->isPush(Inst) || BC.MIB->isPop(Inst))
196196
continue;
197197

198+
// Pointer signing and authenticatin instructions are used around
199+
// Push and Pop. These are also straightforward to handle.
200+
if (BC.isAArch64() &&
201+
(BC.MIB->isPSignOnLR(Inst) || BC.MIB->isPAuthOnLR(Inst) ||
202+
BC.MIB->isPAuthAndRet(Inst)))
203+
continue;
204+
198205
DirectSP |= BC.MIB->hasDefOfPhysReg(Inst, SPReg) ||
199206
BC.MIB->hasUseOfPhysReg(Inst, SPReg);
200207
}
@@ -338,6 +345,18 @@ Inliner::inlineCall(BinaryBasicBlock &CallerBB,
338345
BC.Ctx.get());
339346
}
340347

348+
// Handling fused authentication and return instructions (Armv8.3-A):
349+
// if the Callee does not end in a tailcall, the return will be removed
350+
// from the inlined block. If that return is RETA(A|B), we have to keep
351+
// the authentication part.
352+
// RETAA -> AUTIASP
353+
// RETAB -> AUTIBSP
354+
if (!CSIsTailCall && BC.isAArch64() && BC.MIB->isPAuthAndRet(Inst)) {
355+
MCInst Auth;
356+
BC.MIB->createMatchingAuth(Inst, Auth);
357+
InsertII =
358+
std::next(InlinedBB->insertInstruction(InsertII, std::move(Auth)));
359+
}
341360
if (CSIsTailCall || (!MIB.isCall(Inst) && !MIB.isReturn(Inst))) {
342361
InsertII =
343362
std::next(InlinedBB->insertInstruction(InsertII, std::move(Inst)));

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,33 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
313313
Inst.getOpcode() == AArch64::RETABSPPCr;
314314
}
315315

316+
void createMatchingAuth(const MCInst &AuthAndRet, MCInst &Auth) override {
317+
Auth.clear();
318+
Auth.setOperands(AuthAndRet.getOperands());
319+
switch (AuthAndRet.getOpcode()) {
320+
case AArch64::RETAA:
321+
Auth.setOpcode(AArch64::AUTIASP);
322+
break;
323+
case AArch64::RETAB:
324+
Auth.setOpcode(AArch64::AUTIBSP);
325+
break;
326+
case AArch64::RETAASPPCi:
327+
Auth.setOpcode(AArch64::AUTIASPPCi);
328+
break;
329+
case AArch64::RETABSPPCi:
330+
Auth.setOpcode(AArch64::AUTIBSPPCi);
331+
break;
332+
case AArch64::RETAASPPCr:
333+
Auth.setOpcode(AArch64::AUTIASPPCr);
334+
break;
335+
case AArch64::RETABSPPCr:
336+
Auth.setOpcode(AArch64::AUTIBSPPCr);
337+
break;
338+
default:
339+
llvm_unreachable("Unhandled fused pauth-and-return instruction");
340+
}
341+
}
342+
316343
std::optional<MCPhysReg> getSignedReg(const MCInst &Inst) const override {
317344
switch (Inst.getOpcode()) {
318345
case AArch64::PACIA:
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# This test checks that inlining functions with fused pointer-auth-and-return
2+
# instructions is properly handled by BOLT.
3+
4+
# REQUIRES: system-linux
5+
6+
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown -mattr=+v8.3a %s -o %t.o
7+
# RUN: %clang %cflags -O0 %t.o -o %t.exe -Wl,-q
8+
# RUN: llvm-bolt --inline-all --print-inline --print-only=_Z3barP1A \
9+
# RUN: %t.exe -o %t.bolt | FileCheck %s
10+
11+
# CHECK: BOLT-INFO: inlined 0 calls at 1 call sites in 2 iteration(s). Change in binary size: 8 bytes.
12+
# CHECK: Binary Function "_Z3barP1A" after inlining {
13+
# CHECK-NOT: bl _Z3fooP1A
14+
# CHECK: ldr x8, [x0]
15+
# CHECK-NEXT: ldr w0, [x8]
16+
# CHECK-NEXT: autiasp
17+
18+
.text
19+
.globl _Z3fooP1A
20+
.type _Z3fooP1A,@function
21+
_Z3fooP1A:
22+
paciasp
23+
ldr x8, [x0]
24+
ldr w0, [x8]
25+
retaa
26+
.size _Z3fooP1A, .-_Z3fooP1A
27+
28+
.globl _Z3barP1A
29+
.type _Z3barP1A,@function
30+
_Z3barP1A:
31+
stp x29, x30, [sp, #-16]!
32+
mov x29, sp
33+
bl _Z3fooP1A
34+
mul w0, w0, w0
35+
ldp x29, x30, [sp], #16
36+
ret
37+
.size _Z3barP1A, .-_Z3barP1A
38+
39+
.globl main
40+
.p2align 2
41+
.type main,@function
42+
main:
43+
mov w0, wzr
44+
ret
45+
.size main, .-main
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# This test checks that inlining functions with fused pointer-auth-and-return
2+
# instructions into a location with a tailcall is properly handled by BOLT.
3+
# Because _Z3barP1A ends in a tailcall, we don't remove the return instruction
4+
# from the inlined block. Therefore, we should see a retaa, and not an autiasp.
5+
6+
# REQUIRES: system-linux
7+
8+
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown -mattr=+v8.3a %s -o %t.o
9+
# RUN: %clang %cflags -O0 %t.o -o %t.exe -Wl,-q
10+
# RUN: llvm-bolt --inline-all --print-inline --print-only=_Z3barP1A \
11+
# RUN: %t.exe -o %t.bolt | FileCheck %s
12+
13+
# CHECK: BOLT-INFO: inlined 0 calls at 1 call sites in 2 iteration(s). Change in binary size: 12 bytes.
14+
# CHECK: Binary Function "_Z3barP1A" after inlining {
15+
# CHECK-NOT: bl _Z3fooP1A
16+
# CHECK: mov x29, sp
17+
# CHECK-NEXT: paciasp
18+
# CHECK-NEXT: ldr x8, [x0]
19+
# CHECK-NEXT: ldr w0, [x8]
20+
# CHECK-NEXT: retaa
21+
22+
.text
23+
.globl _Z3fooP1A
24+
.type _Z3fooP1A,@function
25+
_Z3fooP1A:
26+
paciasp
27+
ldr x8, [x0]
28+
ldr w0, [x8]
29+
retaa
30+
.size _Z3fooP1A, .-_Z3fooP1A
31+
32+
.globl _Z3barP1A
33+
.type _Z3barP1A,@function
34+
_Z3barP1A:
35+
stp x29, x30, [sp, #-16]!
36+
mov x29, sp
37+
b _Z3fooP1A // tailcall
38+
.size _Z3barP1A, .-_Z3barP1A
39+
40+
.globl main
41+
.p2align 2
42+
.type main,@function
43+
main:
44+
mov w0, wzr
45+
ret
46+
.size main, .-main
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# This test checks that inlining functions with the pauth-lr variants of
2+
# fused pointer-auth-and-return instructions is properly handled by BOLT.
3+
4+
# REQUIRES: system-linux
5+
6+
# RUN: %clang %cflags -march=armv9.5-a+pauth-lr -O0 %s -o %t.exe -Wl,-q
7+
# RUN: llvm-bolt --inline-all --print-inline --print-only=_Z3barP1A \
8+
# RUN: %t.exe -o %t.bolt | FileCheck %s
9+
10+
# CHECK: BOLT-INFO: inlined 0 calls at 2 call sites in 2 iteration(s). Change in binary size: 16 bytes.
11+
# CHECK: Binary Function "_Z3barP1A" after inlining {
12+
# CHECK-NOT: bl _Z3fooP1A
13+
# CHECK: paciasppc
14+
# CHECK-NEXT: ldr x8, [x0]
15+
# CHECK-NEXT: ldr w0, [x8]
16+
# CHECK-NEXT: autiasppcr x28
17+
# CHECK-NEXT: paciasppc
18+
# CHECK-NEXT: ldr x7, [x0]
19+
# CHECK-NEXT: ldr w0, [x7]
20+
# CHECK-NEXT: autiasppc _Z3bazP1A
21+
22+
.text
23+
.globl _Z3fooP1A
24+
.type _Z3fooP1A,@function
25+
_Z3fooP1A:
26+
paciasppc
27+
ldr x8, [x0]
28+
ldr w0, [x8]
29+
retaasppcr x28
30+
.size _Z3fooP1A, .-_Z3fooP1A
31+
32+
.text
33+
.globl _Z3bazP1A
34+
.type _Z3bazP1A,@function
35+
_Z3bazP1A:
36+
0:
37+
paciasppc
38+
ldr x7, [x0]
39+
ldr w0, [x7]
40+
retaasppc 0b
41+
.size _Z3bazP1A, .-_Z3bazP1A
42+
43+
.globl _Z3barP1A
44+
.type _Z3barP1A,@function
45+
_Z3barP1A:
46+
stp x29, x30, [sp, #-16]!
47+
mov x29, sp
48+
bl _Z3fooP1A
49+
bl _Z3bazP1A
50+
mul w0, w0, w0
51+
ldp x29, x30, [sp], #16
52+
ret
53+
.size _Z3barP1A, .-_Z3barP1A
54+
55+
.globl main
56+
.p2align 2
57+
.type main,@function
58+
main:
59+
mov w0, wzr
60+
ret
61+
.size main, .-main

clang-tools-extra/clang-doc/assets/class-template.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
<section class="hero section-container">
141141
<div class="hero__title">
142142
<h1 class="hero__title-large">{{TagType}} {{Name}}</h1>
143+
<p>Defined at line {{Location.LineNumber}} of file {{Location.Filename}}</p>
143144
{{#Description}}
144145
<div class="hero__subtitle">
145146
{{>Comments}}

clang-tools-extra/clangd/CompileCommands.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ std::optional<std::string> detectSysroot() {
132132

133133
std::string detectStandardResourceDir() {
134134
static int StaticForMainAddr; // Just an address in this process.
135-
return GetResourcesPath("clangd", (void *)&StaticForMainAddr);
135+
return CompilerInvocation::GetResourcesPath("clangd",
136+
(void *)&StaticForMainAddr);
136137
}
137138

138139
// The path passed to argv[0] is important:

clang-tools-extra/clangd/Compiler.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include "Compiler.h"
1010
#include "support/Logger.h"
1111
#include "clang/Basic/TargetInfo.h"
12-
#include "clang/Driver/CreateInvocationFromArgs.h"
1312
#include "clang/Frontend/CompilerInvocation.h"
1413
#include "clang/Lex/PreprocessorOptions.h"
1514
#include "clang/Serialization/PCHContainerOperations.h"

clang-tools-extra/clangd/SemanticSelection.cpp

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
#include "Protocol.h"
1212
#include "Selection.h"
1313
#include "SourceCode.h"
14+
#include "support/Bracket.h"
15+
#include "support/DirectiveTree.h"
16+
#include "support/Token.h"
1417
#include "clang/AST/DeclBase.h"
1518
#include "clang/Basic/SourceLocation.h"
1619
#include "clang/Basic/SourceManager.h"
20+
#include "clang/Basic/TokenKinds.h"
1721
#include "clang/Tooling/Syntax/BuildTree.h"
1822
#include "clang/Tooling/Syntax/Nodes.h"
1923
#include "clang/Tooling/Syntax/TokenBufferTokenManager.h"
@@ -22,9 +26,6 @@
2226
#include "llvm/ADT/StringRef.h"
2327
#include "llvm/Support/Casting.h"
2428
#include "llvm/Support/Error.h"
25-
#include "support/Bracket.h"
26-
#include "support/DirectiveTree.h"
27-
#include "support/Token.h"
2829
#include <optional>
2930
#include <queue>
3031
#include <vector>
@@ -163,6 +164,72 @@ llvm::Expected<SelectionRange> getSemanticRanges(ParsedAST &AST, Position Pos) {
163164
return std::move(Head);
164165
}
165166

167+
class PragmaRegionFinder {
168+
// Record the token range of a region:
169+
//
170+
// #pragma region name[[
171+
// ...
172+
// ]]#pragma endregion
173+
std::vector<Token::Range> &Ranges;
174+
const TokenStream &Code;
175+
// Stack of starting token (the name of the region) indices for nested #pragma
176+
// region.
177+
std::vector<unsigned> Stack;
178+
179+
public:
180+
PragmaRegionFinder(std::vector<Token::Range> &Ranges, const TokenStream &Code)
181+
: Ranges(Ranges), Code(Code) {}
182+
183+
void walk(const DirectiveTree &T) {
184+
for (const auto &C : T.Chunks)
185+
std::visit(*this, C);
186+
}
187+
188+
void operator()(const DirectiveTree::Code &C) {}
189+
190+
void operator()(const DirectiveTree::Directive &D) {
191+
// Get the tokens that make up this directive.
192+
auto Tokens = Code.tokens(D.Tokens);
193+
if (Tokens.empty())
194+
return;
195+
const Token &HashToken = Tokens.front();
196+
assert(HashToken.Kind == tok::hash);
197+
const Token &Pragma = HashToken.nextNC();
198+
if (Pragma.text() != "pragma")
199+
return;
200+
const Token &Value = Pragma.nextNC();
201+
202+
// Handle "#pragma region name"
203+
if (Value.text() == "region") {
204+
// Find the last token at the same line.
205+
const Token *T = &Value.next();
206+
while (T < Tokens.end() && T->Line == Pragma.Line)
207+
T = &T->next();
208+
--T;
209+
Stack.push_back(T->OriginalIndex);
210+
return;
211+
}
212+
213+
// Handle "#pragma endregion"
214+
if (Value.text() == "endregion") {
215+
if (Stack.empty())
216+
return; // unmatched end region; ignore.
217+
218+
unsigned StartIdx = Stack.back();
219+
Stack.pop_back();
220+
Ranges.push_back(Token::Range{StartIdx, HashToken.OriginalIndex});
221+
}
222+
}
223+
224+
void operator()(const DirectiveTree::Conditional &C) {
225+
// C.Branches needs to see the DirectiveTree definition, otherwise build
226+
// fails in C++20.
227+
[[maybe_unused]] DirectiveTree Dummy;
228+
for (const auto &[_, SubTree] : C.Branches)
229+
walk(SubTree);
230+
}
231+
};
232+
166233
// FIXME(kirillbobyrev): Collect comments, PP conditional regions, includes and
167234
// other code regions (e.g. public/private/protected sections of classes,
168235
// control flow statement bodies).
@@ -286,6 +353,17 @@ getFoldingRanges(const std::string &Code, bool LineFoldingOnly) {
286353
}
287354
AddFoldingRange(Start, End, FoldingRange::COMMENT_KIND);
288355
}
356+
357+
// #pragma region
358+
std::vector<Token::Range> Ranges;
359+
PragmaRegionFinder(Ranges, OrigStream).walk(DirectiveStructure);
360+
auto Ts = OrigStream.tokens();
361+
for (const auto &R : Ranges) {
362+
auto End = StartPosition(Ts[R.End]);
363+
if (LineFoldingOnly)
364+
End.line--;
365+
AddFoldingRange(EndPosition(Ts[R.Begin]), End, FoldingRange::REGION_KIND);
366+
}
289367
return Result;
290368
}
291369

0 commit comments

Comments
 (0)