Skip to content

Commit b6dac6c

Browse files
Merge branch 'llvm:main' into gh-101657
2 parents 9b2902a + bea0225 commit b6dac6c

File tree

2,141 files changed

+95859
-48793
lines changed

Some content is hidden

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

2,141 files changed

+95859
-48793
lines changed

.clang-format

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
BasedOnStyle: LLVM
2+
LineEnding: LF

.github/new-prs-labeler.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,3 +1121,6 @@ tablegen:
11211121
- llvm/include/TableGen/**
11221122
- llvm/lib/TableGen/**
11231123
- llvm/utils/TableGen/**
1124+
1125+
infrastructure:
1126+
- .ci/**

.github/workflows/libcxx-build-and-test.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ jobs:
215215
- uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
216216
with:
217217
# https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md
218-
xcode-version: '16.3'
218+
xcode-version: '26.0'
219219
- uses: seanmiddleditch/gha-setup-ninja@3b1f8f94a2f8254bd26914c4ab9474d4f0015f67 # v6
220220
- name: Build and test
221221
run: |
@@ -281,6 +281,10 @@ jobs:
281281
- name: Set up the MSVC dev environment
282282
if: ${{ matrix.mingw != true }}
283283
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
284+
- name: Add the installed Clang at the start of the path
285+
if: ${{ matrix.mingw != true }}
286+
run: |
287+
echo "c:\Program Files\LLVM\bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append
284288
- name: Build and test
285289
run: |
286290
bash libcxx/utils/ci/run-buildbot ${{ matrix.config }}

.github/workflows/llvm-tests.yml renamed to .github/workflows/llvm-abi-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: LLVM Tests
1+
name: LLVM ABI Tests
22

33
permissions:
44
contents: read

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ class BinaryContext {
190190
/// Unique build ID if available for the binary.
191191
std::optional<std::string> FileBuildID;
192192

193+
/// GNU property note indicating AArch64 BTI.
194+
bool UsesBTI{false};
195+
193196
/// Set of all sections.
194197
struct CompareSections {
195198
bool operator()(const BinarySection *A, const BinarySection *B) const {
@@ -384,6 +387,9 @@ class BinaryContext {
384387
}
385388
void setFileBuildID(StringRef ID) { FileBuildID = std::string(ID); }
386389

390+
bool usesBTI() const { return UsesBTI; }
391+
void setUsesBTI(bool Value) { UsesBTI = Value; }
392+
387393
bool hasSymbolsWithFileName() const { return HasSymbolsWithFileName; }
388394
void setHasSymbolsWithFileName(bool Value) { HasSymbolsWithFileName = Value; }
389395

bolt/include/bolt/Core/MCInstUtils.h

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

1212
#include "bolt/Core/BinaryBasicBlock.h"
13+
#include "bolt/Core/MCPlus.h"
1314
#include <map>
1415
#include <variant>
1516

@@ -175,6 +176,171 @@ static inline raw_ostream &operator<<(raw_ostream &OS,
175176
return Ref.print(OS);
176177
}
177178

179+
/// Instruction-matching helpers operating on a single instruction at a time.
180+
///
181+
/// The idea is to make low-level instruction matching as readable as possible.
182+
/// The classes contained in this namespace are intended to be used as a
183+
/// domain-specific language to match MCInst with the particular opcode and
184+
/// operands.
185+
///
186+
/// The goals of this DSL include
187+
/// * matching a single instruction against the template consisting of the
188+
/// particular target-specific opcode and a pattern of operands
189+
/// * matching operands against the known values (such as 42, AArch64::X1 or
190+
/// "the value of --brk-operand=N command line argument")
191+
/// * capturing operands of an instruction ("whatever is the destination
192+
/// register of AArch64::ADDXri instruction, store it to Xd variable to be
193+
/// queried later")
194+
/// * expressing repeated operands of a single matched instruction (such as
195+
/// "ADDXri Xd, Xd, 42, 0" for an arbitrary register Xd) as well as across
196+
/// multiple calls to matchInst(), which is naturally achieved by sequentially
197+
/// capturing the operands and matching operands against the known values
198+
/// * matching multi-instruction code patterns by sequentially calling
199+
/// matchInst() while passing around already matched operands
200+
///
201+
/// The non-goals (compared to MCPlusBuilder::MCInstMatcher) include
202+
/// * matching an arbitrary tree of instructions in a single matchInst() call
203+
/// * encapsulation of target-specific knowledge ("match an increment of Xm
204+
/// by 42")
205+
///
206+
/// Unlike MCPlusBuilder::MCInstMatcher, this DSL focuses on the use cases when
207+
/// the precise control over the instruction order is important. For example,
208+
/// let's consider a target-specific function that has to match two particular
209+
/// instructions against this pattern (for two different registers Xm and Xn)
210+
///
211+
/// ADDXrs Xm, Xn, Xm, #0
212+
/// BR Xm
213+
///
214+
/// and return the register holding the branch target. Assuming the instructions
215+
/// are available as MaybeAdd and MaybeBr, the following code can be used:
216+
///
217+
/// // Bring the short names into the local scope:
218+
/// using namespace LowLevelInstMatcherDSL;
219+
/// // Declare the registers to capture:
220+
/// Reg Xn, Xm;
221+
/// // Capture the 0th and 1st operands, match the 2nd operand against the
222+
/// // just captured Xm register, match the 3rd operand against literal 0:
223+
/// if (!matchInst(MaybeAdd, AArch64::ADDXrs, Xm, Xn, Xm, Imm(0))
224+
/// return AArch64::NoRegister;
225+
/// // Match the 0th operand against Xm:
226+
/// if (!matchInst(MaybeBr, AArch64::BR, Xm))
227+
/// return AArch64::NoRegister;
228+
/// // Manually check that Xm and Xn did not match the same register:
229+
/// if (Xm.get() == Xn.get())
230+
/// return AArch64::NoRegister;
231+
/// // Return the matched register:
232+
/// return Xm.get();
233+
///
234+
namespace LowLevelInstMatcherDSL {
235+
236+
// The base class to match an operand of type T.
237+
//
238+
// The subclasses of OpMatcher are intended to be allocated on the stack and
239+
// to only be used by passing them to matchInst() and by calling their get()
240+
// function, thus the peculiar `mutable` specifiers: to make the calling code
241+
// compact and readable, the templated matchInst() function has to accept both
242+
// long-lived Imm/Reg wrappers declared as local variables (intended to capture
243+
// the first operand's value and match the subsequent operands, whether inside
244+
// a single instruction or across multiple instructions), as well as temporary
245+
// wrappers around literal values to match, f.e. Imm(42) or Reg(AArch64::XZR).
246+
template <typename T> class OpMatcher {
247+
mutable std::optional<T> Value;
248+
mutable std::optional<T> SavedValue;
249+
250+
// Remember/restore the last Value - to be called by matchInst.
251+
void remember() const { SavedValue = Value; }
252+
void restore() const { Value = SavedValue; }
253+
254+
template <class... OpMatchers>
255+
friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
256+
257+
protected:
258+
OpMatcher(std::optional<T> ValueToMatch) : Value(ValueToMatch) {}
259+
260+
bool matchValue(T OpValue) const {
261+
// Check that OpValue does not contradict the existing Value.
262+
bool MatchResult = !Value || *Value == OpValue;
263+
// If MatchResult is false, all matchers will be reset before returning from
264+
// matchInst, including this one, thus no need to assign conditionally.
265+
Value = OpValue;
266+
267+
return MatchResult;
268+
}
269+
270+
public:
271+
/// Returns the captured value.
272+
T get() const {
273+
assert(Value.has_value());
274+
return *Value;
275+
}
276+
};
277+
278+
class Reg : public OpMatcher<MCPhysReg> {
279+
bool matches(const MCOperand &Op) const {
280+
if (!Op.isReg())
281+
return false;
282+
283+
return matchValue(Op.getReg());
284+
}
285+
286+
template <class... OpMatchers>
287+
friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
288+
289+
public:
290+
Reg(std::optional<MCPhysReg> RegToMatch = std::nullopt)
291+
: OpMatcher<MCPhysReg>(RegToMatch) {}
292+
};
293+
294+
class Imm : public OpMatcher<int64_t> {
295+
bool matches(const MCOperand &Op) const {
296+
if (!Op.isImm())
297+
return false;
298+
299+
return matchValue(Op.getImm());
300+
}
301+
302+
template <class... OpMatchers>
303+
friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
304+
305+
public:
306+
Imm(std::optional<int64_t> ImmToMatch = std::nullopt)
307+
: OpMatcher<int64_t>(ImmToMatch) {}
308+
};
309+
310+
/// Tries to match Inst and updates Ops on success.
311+
///
312+
/// If Inst has the specified Opcode and its operand list prefix matches Ops,
313+
/// this function returns true and updates Ops, otherwise false is returned and
314+
/// values of Ops are kept as before matchInst was called.
315+
///
316+
/// Please note that while Ops are technically passed by a const reference to
317+
/// make invocations like `matchInst(MI, Opcode, Imm(42))` possible, all their
318+
/// fields are marked mutable.
319+
template <class... OpMatchers>
320+
bool matchInst(const MCInst &Inst, unsigned Opcode, const OpMatchers &...Ops) {
321+
if (Inst.getOpcode() != Opcode)
322+
return false;
323+
assert(sizeof...(Ops) <= MCPlus::getNumPrimeOperands(Inst) &&
324+
"Too many operands are matched for the Opcode");
325+
326+
// Ask each matcher to remember its current value in case of rollback.
327+
(Ops.remember(), ...);
328+
329+
// Check if all matchers match the corresponding operands.
330+
auto It = Inst.begin();
331+
auto AllMatched = (Ops.matches(*(It++)) && ... && true);
332+
333+
// If match failed, restore the original captured values.
334+
if (!AllMatched) {
335+
(Ops.restore(), ...);
336+
return false;
337+
}
338+
339+
return true;
340+
}
341+
342+
} // namespace LowLevelInstMatcherDSL
343+
178344
} // namespace bolt
179345
} // namespace llvm
180346

bolt/include/bolt/Passes/SplitFunctions.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,6 @@
1818
namespace llvm {
1919
namespace bolt {
2020

21-
/// Strategy used to partition blocks into fragments.
22-
enum SplitFunctionsStrategy : char {
23-
/// Split each function into a hot and cold fragment using profiling
24-
/// information.
25-
Profile2 = 0,
26-
/// Split each function into a hot, warm, and cold fragment using
27-
/// profiling information.
28-
CDSplit,
29-
/// Split each function into a hot and cold fragment at a randomly chosen
30-
/// split point (ignoring any available profiling information).
31-
Random2,
32-
/// Split each function into N fragments at a randomly chosen split points
33-
/// (ignoring any available profiling information).
34-
RandomN,
35-
/// Split all basic blocks of each function into fragments such that each
36-
/// fragment contains exactly a single basic block.
37-
All
38-
};
39-
4021
class SplitStrategy {
4122
public:
4223
using BlockIt = BinaryFunction::BasicBlockOrderType::iterator;

bolt/include/bolt/Rewrite/MetadataRewriters.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ std::unique_ptr<MetadataRewriter> createPseudoProbeRewriter(BinaryContext &);
2727

2828
std::unique_ptr<MetadataRewriter> createSDTRewriter(BinaryContext &);
2929

30+
std::unique_ptr<MetadataRewriter> createGNUPropertyRewriter(BinaryContext &);
31+
3032
} // namespace bolt
3133
} // namespace llvm
3234

bolt/include/bolt/Rewrite/RewriteInstance.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,11 @@ class RewriteInstance {
249249
/// Analyze relocation \p Rel.
250250
/// Return true if the relocation was successfully processed, false otherwise.
251251
/// The \p SymbolName, \p SymbolAddress, \p Addend and \p ExtractedValue
252-
/// parameters will be set on success. The \p Skip argument indicates
253-
/// that the relocation was analyzed, but it must not be processed.
252+
/// parameters will be set on success.
254253
bool analyzeRelocation(const object::RelocationRef &Rel, uint32_t &RType,
255254
std::string &SymbolName, bool &IsSectionRelocation,
256255
uint64_t &SymbolAddress, int64_t &Addend,
257-
uint64_t &ExtractedValue, bool &Skip) const;
256+
uint64_t &ExtractedValue) const;
258257

259258
/// Rewrite non-allocatable sections with modifications.
260259
void rewriteNoteSections();

bolt/include/bolt/Utils/CommandLineOpts.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ enum HeatmapModeKind {
2929
HM_Optional // perf2bolt --heatmap
3030
};
3131

32+
/// Strategy used to partition blocks into fragments.
33+
enum SplitFunctionsStrategy : char {
34+
/// Split each function into a hot and cold fragment using profiling
35+
/// information.
36+
Profile2 = 0,
37+
/// Split each function into a hot, warm, and cold fragment using
38+
/// profiling information.
39+
CDSplit,
40+
/// Split each function into a hot and cold fragment at a randomly chosen
41+
/// split point (ignoring any available profiling information).
42+
Random2,
43+
/// Split each function into N fragments at a randomly chosen split points
44+
/// (ignoring any available profiling information).
45+
RandomN,
46+
/// Split all basic blocks of each function into fragments such that each
47+
/// fragment contains exactly a single basic block.
48+
All
49+
};
50+
3251
using HeatmapBlockSizes = std::vector<unsigned>;
3352
struct HeatmapBlockSpecParser : public llvm::cl::parser<HeatmapBlockSizes> {
3453
explicit HeatmapBlockSpecParser(llvm::cl::Option &O)
@@ -78,6 +97,7 @@ extern llvm::cl::opt<std::string> OutputFilename;
7897
extern llvm::cl::opt<std::string> PerfData;
7998
extern llvm::cl::opt<bool> PrintCacheMetrics;
8099
extern llvm::cl::opt<bool> PrintSections;
100+
extern llvm::cl::opt<SplitFunctionsStrategy> SplitStrategy;
81101

82102
// The format to use with -o in aggregation mode (perf2bolt)
83103
enum ProfileFormatKind { PF_Fdata, PF_YAML };

0 commit comments

Comments
 (0)