Skip to content

Commit 26b171f

Browse files
committed
merge main into amd-staging
2 parents 5a17ee6 + 90e3ac6 commit 26b171f

File tree

239 files changed

+6189
-2541
lines changed

Some content is hidden

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

239 files changed

+6189
-2541
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @nikic
2929
/llvm/lib/Transforms/InstCombine/ @nikic
3030

31+
# AMDGPU buffer pointer lowerings
32+
/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp @krzysz00
33+
3134
/clang/test/CXX/drs/ @Endilll
3235
/clang/www/cxx_dr_status.html @Endilll
3336
/clang/www/make_cxx_dr_status @Endilll

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ class BinaryContext {
11131113
return FragmentClasses.isEquivalent(LHS, RHS);
11141114
}
11151115

1116-
/// Add interprocedural reference for \p Function to \p Address
1116+
/// Add interprocedural branch reference from \p Function to \p Address.
11171117
void addInterproceduralReference(BinaryFunction *Function, uint64_t Address) {
11181118
InterproceduralReferences.push_back({Function, Address});
11191119
}
@@ -1128,7 +1128,8 @@ class BinaryContext {
11281128
/// argument is false.
11291129
bool handleAArch64Veneer(uint64_t Address, bool MatchOnly = false);
11301130

1131-
/// Resolve inter-procedural dependencies from
1131+
/// Resolve inter-procedural branch dependencies discovered during
1132+
/// disassembly.
11321133
void processInterproceduralReferences();
11331134

11341135
/// Skip functions with all parent and child fragments transitively.

bolt/lib/Core/BinaryContext.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,8 +1438,6 @@ void BinaryContext::processInterproceduralReferences() {
14381438
continue;
14391439
}
14401440

1441-
// Check if address falls in function padding space - this could be
1442-
// unmarked data in code. In this case adjust the padding space size.
14431441
ErrorOr<BinarySection &> Section = getSectionForAddress(Address);
14441442
assert(Section && "cannot get section for referenced address");
14451443

@@ -1451,7 +1449,7 @@ void BinaryContext::processInterproceduralReferences() {
14511449
if (SectionName == ".plt" || SectionName == ".plt.got")
14521450
continue;
14531451

1454-
// Check if it is aarch64 veneer written at Address
1452+
// Check if it is aarch64 veneer written at Address.
14551453
if (isAArch64() && handleAArch64Veneer(Address))
14561454
continue;
14571455

@@ -1463,6 +1461,8 @@ void BinaryContext::processInterproceduralReferences() {
14631461
exit(1);
14641462
}
14651463

1464+
// Check if the address falls into the function padding space - this could
1465+
// be an unmarked data in code. In this case, adjust the padding space size.
14661466
TargetFunction = getBinaryFunctionContainingAddress(Address,
14671467
/*CheckPastEnd=*/false,
14681468
/*UseMaxSize=*/true);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// UNSUPPORTED: system-windows
22

3-
// RUN: clang-tidy -p %S/Inputs/empty-database %s 2>&1 | FileCheck %s
3+
// RUN: clang-tidy -checks='-*,clang-analyzer-*' -p %S/Inputs/empty-database %s 2>&1 | FileCheck %s
44

55
// CHECK: 'directory' field of compilation database is empty; using the current working directory instead.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// UNSUPPORTED: system-windows
22

3-
// RUN: not --crash clang-tidy -p %S/Inputs/invalid-database %s 2>&1 | FileCheck %s
3+
// RUN: not --crash clang-tidy -checks='-*,clang-analyzer-*' -p %S/Inputs/invalid-database %s 2>&1 | FileCheck %s
44

55
// CHECK: LLVM ERROR: Cannot chdir into "/invalid/"!
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
================================
2+
ClangIR Code Duplication Roadmap
3+
================================
4+
5+
.. contents::
6+
:local:
7+
8+
Introduction
9+
============
10+
11+
This document describes the general approach to code duplication in the ClangIR
12+
code generation implementation. It acknowledges specific problems with the
13+
current implementation, discusses strategies for mitigating the risk inherent in
14+
the current approach, and describes a general long-term plan for addressing the
15+
issue.
16+
17+
Background
18+
==========
19+
20+
The ClangIR code generation is very closely modeled after Clang's LLVM IR code
21+
generation, and we intend for the CIR produced to eventually be semantically
22+
equivalent to the LLVM IR produced when not going through ClangIR. However, we
23+
acknowledge that as the ClangIR implementation is under development, there will
24+
be differences in semantics, both because we have not yet implemented all
25+
features of the classic codegen and because the CIR dialect is still evolving
26+
and does not yet have a way to represent all of the necessary semantics.
27+
28+
We have chosen to model the ClangIR code generation directly after the classic
29+
codegen, to the point of following identical code structure, using similar names
30+
and often duplicating the logic because this seemed to be the most certain path
31+
to producing equivalent results. Having such nearly identical code allows for
32+
direct comparison between the CIR codegen and the LLVM IR codegen to find what
33+
is missing or incorrect in the CIR implementation.
34+
35+
However, we recognize that this is not a sustainable permanent solution. As
36+
bugs are fixed and new features are added to the classic codegen, the process of
37+
keeping the analogous CIR code up to date will be a purely manual process.
38+
39+
Long term, we need a more sustainable approach.
40+
41+
Current Strategy
42+
================
43+
44+
Practical considerations require that we make steady progress towards a working
45+
implementation of ClangIR. This necessity is directly opposed to the goal of
46+
minimizing code duplication.
47+
48+
For this reason, we have decided to accept a large amount of code duplication
49+
in the short term, even with the explicit understanding that this is producing
50+
a significant amount of technical debt as the project progresses.
51+
52+
As the CIR implementation is developed, we often note small pieces of code that
53+
could be shared with the classic codegen if they were moved to a different part
54+
of the source, such as a shared utility class in some directory available to
55+
both codegen implementations or by moving the function into a related AST class.
56+
It is left to the discretion of the developer and reviewers to decide whether
57+
such refactoring should be done during the CIR development, or if it is
58+
sufficient to leave a comment in the code indicating this as an opportunity for
59+
future improvement. Because much of the current code is likely to change when
60+
the long term code sharing strategy is complete, we will lean towards only
61+
implementing refactorings that make sense independent of the code sharing
62+
problem.
63+
64+
We have discussed various ways that major classes such as CGCXXABI/CIRGenCXXABI
65+
could be refactored to allow parts of there implementation to be shared today
66+
through inheritence and templated base classes. However, this may prove to be
67+
wasted effort when the permanent solution is developed. Also, deferring this
68+
kind of intertwined implementation prevents introducing cross-dependencies that
69+
would make it more difficult to remove one IR code generation implementation
70+
without degrading the quality of the other. Therefore, we have decided that it
71+
is better to accept significant amounts of code duplication now, and defer
72+
this type of refactoring until it is clear what the permanent solution will be.
73+
74+
Mitigation Through Testing
75+
==========================
76+
77+
The most important tactic that we are using to mitigate the risk of CIR diverging
78+
from classic codegen is to incorporate two sets of LLVM IR checks in the CIR
79+
codegen LIT tests. One set checks the LLVM IR that is produced by first
80+
generating CIR and then lowering that to LLVM IR. Another set checks the LLVM IR
81+
that is produced directly by the classic codegen.
82+
83+
At the time that tests are created, we compare the LLVM IR output from these two
84+
paths to verify (manually) that any meaningful differences between them are the
85+
result of known missing features in the current CIR implementation. Whenever
86+
possible, differences are corrected in the same PR that the test is being added,
87+
updating the CIR implementation as it is being developed.
88+
89+
However, these tests serve a second purpose. They also serve as sentinels to
90+
alert us to changes in the classic codegen behavior that will need to be
91+
accounted for in the CIR implementation. While we appreciate any help from
92+
developers contributing to classic codegen, our current expectation is that it
93+
will be the responsibility of the ClangIR contributors to update the CIR
94+
implementation when these tests fail.
95+
96+
As the CIR implementation gets closer to the goal of IR that is semantically
97+
equivalent to the LLVM IR produced by the classic codegen, we would like to
98+
enhance the CIR tests to perform some automatic verification of the equivalence
99+
of the generated LLVM IR, perhaps using a combination of tools such as `opt
100+
-pass-normalize` and Alive2.
101+
102+
Eventually, we would like to be able to run all existing classic codegen tests
103+
using the CIR path as well.
104+
105+
Other Considerations
106+
====================
107+
108+
The close modeling of CIR after classic codegen has also meant that the CIR
109+
dialect often represents language details at a much lower level than it ideally
110+
should.
111+
112+
In the interest of having a complete working implementation of ClangIR as soon
113+
as is practical, we have chosen to take the approach of following the classic
114+
codegen implementation closely in the initial implementation and only raising
115+
the representation in the CIR dialect to a higher level when there is a clear
116+
and immediate benefit to doing so.
117+
118+
Over time, we expect to progressively raise the CIR representation to a higher
119+
level and remove low level details, including ABI-specific handling from the
120+
dialect. (See the "Long Term Vision" section below for more details.) Having
121+
a working implementation in place makes it easier to verify that the
122+
high-level representation and subsequent lowering are correct.
123+
124+
Mixing With Other Dialects
125+
==========================
126+
127+
Mixing of dialects is a central design feature of MLIR. The CIR dialect is
128+
currently more self-contained than most dialects, but even now we generate
129+
the ACC (OpenACCC) dialect in combination with CIR, and when support for OpenMP
130+
and CUDA are added, similar mixing will occur.
131+
132+
We also expect CIR to be at least partially lowered to other dialects during
133+
the optimization phase to enable features such as data dependence analysis, even
134+
if we will eventually be lowering it to LLVM IR.
135+
136+
Therefore, any plan for generating LLVM IR from CIR must be integrated with the
137+
general MLIR lowering design, which typically involves lowering to the LLVM
138+
dialect, which is then transformed to LLVM IR.
139+
140+
Other Consumers of CIR and MLIR
141+
===============================
142+
143+
We must also consider that we will not always be lowering CIR to LLVM IR. CIR,
144+
usually mixed with other dialects, will also be directed to offload targets
145+
and other code generators through interfaces that are opaque to Clang, such as
146+
SPIR-V and MLIR core dialects. We must still produce semantically correct CIR
147+
for these consumers.
148+
149+
Long Term Vision
150+
================
151+
152+
As the CIR implementation matures, we will eliminate target-specific handling
153+
from the high-level CIR generated by Clang. The high-level CIR will then be
154+
progressively lowered to a form that is closer to LLVM IR, including a pass
155+
that inserts ABI-specific handling, potentially representing the target-specific
156+
details in another dialect. More complex transformations, such as library-aware
157+
idiom recognition or advanced loop representations—may occur later in the
158+
compilation pipeline through additional passes, which can be controlled by
159+
specific compiler flags.
160+
161+
As we raise CIR to this higher level implementation, there will naturally be
162+
less code duplication, and less need to have the same logic repeated in the
163+
CIR generation.
164+
165+
We will continue to use that same basic design and structure for CIR code
166+
generation, with classes like CIRGenModule and CIRGenFunction that serve the
167+
same purpose as their counterparts in classic codegen, but the handling there
168+
will be more closely tied to core semantics and therefore less likely to require
169+
frequent changes to stay in sync with classic codegen.
170+
171+
As the handling of low-level details is moved to later lowering phases, we will
172+
need to move away from the current tight coupling of the CIR and classic codegen
173+
implementations. As this happens, we will look for ways that this handling can
174+
be moved to new classes that are specifically designed to be shared among
175+
clients that are targeting different IR substrates. That is, rather than trying
176+
to overlay reuse onto the existing implementations, we will replace relevant
177+
parts of the existing implementation, piece by piece, as appropriate, with new
178+
implementations that perform the same function but with a more general design.
179+
180+
Example: C Calling Convention Handling
181+
======================================
182+
183+
C calling convention handling is an example of a general purpose redesign that
184+
is already underway. This was started independently of CIR, but it will be
185+
directly useful for lowering from high-level call representation in CIR to a
186+
representation that includes the target- and calling convention-specific details
187+
of function signatures, parameter type coercion, and so on.
188+
189+
The current CIR implementation duplicates most of the classic codegen handling
190+
for function call handling, but it omits several pieces that handle type
191+
coercion. This leads to an implementation that has all of the complexity of the
192+
class codegen without actually achieving the goals of that complexity. It will
193+
be a significant improvement to the CIR implementation to simplify the function
194+
call handling in such a way that it generates a high-level representation of the
195+
call, while preserving all information that will be needed to lower the call to
196+
an ABI-compliant representation in a later phase of compilation.
197+
198+
This provides a clear example where trying to refactor the classic codegen in
199+
some way to be reused by CIR would have been counterproductive. The classic
200+
codegen implementation was tightly coupled with Clang's LLVM IR generation. The
201+
implementation is being completely redesigned to allow general reuse, not just by
202+
CIR, but also by other front ends.
203+
204+
The CIR calling convention lowering will make use of the general purpose C
205+
calling convention library that is being created, but it should create an MLIR
206+
transform pass on top of that library that is general enough to be used by other
207+
dialects, such as FIR, that also need the same calling convention handling.
208+
209+
Significant Areas For Improvement
210+
=================================
211+
212+
The following list enumerates some of the areas where significant restructuring
213+
of the code is needed to enable better code sharing between CIR and classic
214+
codegen. Each of these areas is relatively self-contained in the codegen
215+
implementation, making the path to a shared implementation relatively clear.
216+
217+
- Constant expression evaluation
218+
- Complex multiplication and division expansion
219+
- Builtin function handling
220+
- Exception Handling and C++ Cleanups
221+
- Inline assembly handling
222+
- C++ ABI Handling
223+
224+
- VTable generation
225+
- Virtual function calls
226+
- Constructor and destructor arguments
227+
- Dynamic casts
228+
- Base class address calculation
229+
- Type descriptors
230+
- Array new and delete
231+
232+
Pervasive Low-Level Issues
233+
==========================
234+
235+
This section lists some of the features where a non-trivial amount of code
236+
is shared between CIR and classic codegen, but the handling of the feature
237+
is distributed across the codegen implementation, making it more difficult
238+
to design an abstraction that can easily be shared.
239+
240+
- Global variable and function linkage
241+
- Alignment management
242+
- Debug information
243+
- TBAA handling
244+
- Sanitizer integration
245+
- Lifetime markers

clang/docs/ReleaseNotes.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ Potentially Breaking Changes
8686
options-related code has been moved out of the Driver into a separate library.
8787
- The ``clangFrontend`` library no longer depends on ``clangDriver``, which may
8888
break downstream projects that relied on this transitive dependency.
89+
- Clang is now more precise with regards to the lifetime of temporary objects
90+
such as when aggregates are passed by value to a function, resulting in
91+
better sharing of stack slots and reduced stack usage. This change can lead
92+
to use-after-scope related issues in code that unintentionally relied on the
93+
previous behavior. If recompiling with ``-fsanitize=address`` shows a
94+
use-after-scope warning, then this is likely the case, and the report printed
95+
should be able to help users pinpoint where the use-after-scope is occurring.
96+
Users can use ``-Xclang -sloppy-temporary-lifetimes`` to retain the old
97+
behavior until they are able to find and resolve issues in their code.
8998

9099
C/C++ Language Potentially Breaking Changes
91100
-------------------------------------------

clang/docs/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Design Documents
123123
ControlFlowIntegrityDesign
124124
HardwareAssistedAddressSanitizerDesign.rst
125125
ConstantInterpreter
126-
126+
ClangIRCodeDuplication
127127

128128
Indices and tables
129129
==================

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,10 @@ ENUM_CODEGENOPT(ZeroCallUsedRegs, ZeroCallUsedRegsKind,
475475
/// non-deleting destructors. (No effect on Microsoft ABI.)
476476
CODEGENOPT(CtorDtorReturnThis, 1, 0, Benign)
477477

478+
/// Set via -Xclang -sloppy-temporary-lifetimes to disable emission of lifetime
479+
/// marker intrinsic calls.
480+
CODEGENOPT(NoLifetimeMarkersForTemporaries, 1, 0, Benign)
481+
478482
/// Enables emitting Import Call sections on supported targets that can be used
479483
/// by the Windows kernel to enable import call optimization.
480484
CODEGENOPT(ImportCallOptimization, 1, 0, Benign)

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
331331
return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order);
332332
}
333333

334+
/// Emit a load from an boolean flag variable.
335+
cir::LoadOp createFlagLoad(mlir::Location loc, mlir::Value addr) {
336+
mlir::Type boolTy = getBoolTy();
337+
if (boolTy != mlir::cast<cir::PointerType>(addr.getType()).getPointee())
338+
addr = createPtrBitcast(addr, boolTy);
339+
return createLoad(loc, addr, /*isVolatile=*/false, /*alignment=*/1);
340+
}
341+
334342
cir::StoreOp createFlagStore(mlir::Location loc, bool val, mlir::Value dst) {
335343
mlir::Value flag = getBool(val, loc);
336344
return CIRBaseBuilderTy::createStore(loc, flag, dst);

0 commit comments

Comments
 (0)