Skip to content

Commit cf328ff

Browse files
authored
[IR] Memory Model Relaxation Annotations (#78569)
Implements the core/target-agnostic components of Memory Model Relaxation Annotations. RFC: https://discourse.llvm.org/t/rfc-mmras-memory-model-relaxation-annotations/76361/5
1 parent 805d563 commit cf328ff

38 files changed

+1954
-55
lines changed

llvm/docs/MemoryModelRelaxationAnnotations.rst

Lines changed: 481 additions & 0 deletions
Large diffs are not rendered by default.

llvm/docs/Reference.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ LLVM and API reference documentation.
3939
PDB/index
4040
PointerAuth
4141
ScudoHardenedAllocator
42+
MemoryModelRelaxationAnnotations
4243
MemTagSanitizer
4344
Security
4445
SecurityTransparencyReports
@@ -194,6 +195,9 @@ Additional Topics
194195
:doc:`ScudoHardenedAllocator`
195196
A library that implements a security-hardened `malloc()`.
196197

198+
:doc:`MemoryModelRelaxationAnnotations`
199+
Target-defined relaxation to LLVM's concurrency model.
200+
197201
:doc:`MemTagSanitizer`
198202
Security hardening for production code aiming to mitigate memory
199203
related vulnerabilities. Based on the Armv8.5-A Memory Tagging Extension.

llvm/docs/ReleaseNotes.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ Update on required toolchains to build LLVM
5050
Changes to the LLVM IR
5151
----------------------
5252

53+
- Added Memory Model Relaxation Annotations (MMRAs).
54+
5355
Changes to LLVM infrastructure
5456
------------------------------
5557

@@ -133,7 +135,7 @@ Changes to the C API
133135
functions for accessing the values in a blockaddress constant.
134136

135137
* Added ``LLVMConstStringInContext2`` function, which better matches the C++
136-
API by using ``size_t`` for string length. Deprecated ``LLVMConstStringInContext``.
138+
API by using ``size_t`` for string length. Deprecated ``LLVMConstStringInContext``.
137139

138140
* Added the following functions for accessing a function's prefix data:
139141

llvm/include/llvm/Analysis/VectorUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ MDNode *intersectAccessGroups(const Instruction *Inst1,
301301
const Instruction *Inst2);
302302

303303
/// Specifically, let Kinds = [MD_tbaa, MD_alias_scope, MD_noalias, MD_fpmath,
304-
/// MD_nontemporal, MD_access_group].
304+
/// MD_nontemporal, MD_access_group, MD_mmra].
305305
/// For K in Kinds, we get the MDNode for K from each of the
306306
/// elements of VL, compute their "intersection" (i.e., the most generic
307307
/// metadata value that covers all of the individual values), and set I's

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ struct MachineIRBuilderState {
5353
DebugLoc DL;
5454
/// PC sections metadata to be set to any instruction we create.
5555
MDNode *PCSections = nullptr;
56+
/// MMRA Metadata to be set on any instruction we create.
57+
MDNode *MMRA = nullptr;
5658

5759
/// \name Fields describing the insertion point.
5860
/// @{
@@ -354,6 +356,7 @@ class MachineIRBuilder {
354356
setMBB(*MI.getParent());
355357
State.II = MI.getIterator();
356358
setPCSections(MI.getPCSections());
359+
setMMRAMetadata(MI.getMMRAMetadata());
357360
}
358361
/// @}
359362

@@ -387,6 +390,12 @@ class MachineIRBuilder {
387390
/// Get the current instruction's PC sections metadata.
388391
MDNode *getPCSections() { return State.PCSections; }
389392

393+
/// Set the PC sections metadata to \p MD for all the next build instructions.
394+
void setMMRAMetadata(MDNode *MMRA) { State.MMRA = MMRA; }
395+
396+
/// Get the current instruction's MMRA metadata.
397+
MDNode *getMMRAMetadata() { return State.MMRA; }
398+
390399
/// Build and insert <empty> = \p Opcode <empty>.
391400
/// The insertion point is the one set by the last call of either
392401
/// setBasicBlock or setMI.

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,8 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
11251125
MachineInstr::ExtraInfo *createMIExtraInfo(
11261126
ArrayRef<MachineMemOperand *> MMOs, MCSymbol *PreInstrSymbol = nullptr,
11271127
MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr,
1128-
MDNode *PCSections = nullptr, uint32_t CFIType = 0);
1128+
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
1129+
MDNode *MMRAs = nullptr);
11291130

11301131
/// Allocate a string and populate it with the given external symbol name.
11311132
const char *createExternalSymbolName(StringRef Name);

llvm/include/llvm/CodeGen/MachineInstr.h

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,37 +160,41 @@ class MachineInstr
160160
MCSymbol *PreInstrSymbol = nullptr,
161161
MCSymbol *PostInstrSymbol = nullptr,
162162
MDNode *HeapAllocMarker = nullptr,
163-
MDNode *PCSections = nullptr,
164-
uint32_t CFIType = 0) {
163+
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
164+
MDNode *MMRAs = nullptr) {
165165
bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
166166
bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
167167
bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
168+
bool HasMMRAs = MMRAs != nullptr;
168169
bool HasCFIType = CFIType != 0;
169170
bool HasPCSections = PCSections != nullptr;
170171
auto *Result = new (Allocator.Allocate(
171172
totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *, uint32_t>(
172173
MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol,
173-
HasHeapAllocMarker + HasPCSections, HasCFIType),
174+
HasHeapAllocMarker + HasPCSections + HasMMRAs, HasCFIType),
174175
alignof(ExtraInfo)))
175176
ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol,
176-
HasHeapAllocMarker, HasPCSections, HasCFIType);
177+
HasHeapAllocMarker, HasPCSections, HasCFIType, HasMMRAs);
177178

178179
// Copy the actual data into the trailing objects.
179180
std::copy(MMOs.begin(), MMOs.end(),
180181
Result->getTrailingObjects<MachineMemOperand *>());
181182

183+
unsigned MDNodeIdx = 0;
184+
182185
if (HasPreInstrSymbol)
183186
Result->getTrailingObjects<MCSymbol *>()[0] = PreInstrSymbol;
184187
if (HasPostInstrSymbol)
185188
Result->getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol] =
186189
PostInstrSymbol;
187190
if (HasHeapAllocMarker)
188-
Result->getTrailingObjects<MDNode *>()[0] = HeapAllocMarker;
191+
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = HeapAllocMarker;
189192
if (HasPCSections)
190-
Result->getTrailingObjects<MDNode *>()[HasHeapAllocMarker] =
191-
PCSections;
193+
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = PCSections;
192194
if (HasCFIType)
193195
Result->getTrailingObjects<uint32_t>()[0] = CFIType;
196+
if (HasMMRAs)
197+
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = MMRAs;
194198

195199
return Result;
196200
}
@@ -223,6 +227,12 @@ class MachineInstr
223227
return HasCFIType ? getTrailingObjects<uint32_t>()[0] : 0;
224228
}
225229

230+
MDNode *getMMRAMetadata() const {
231+
return HasMMRAs ? getTrailingObjects<MDNode *>()[HasHeapAllocMarker +
232+
HasPCSections]
233+
: nullptr;
234+
}
235+
226236
private:
227237
friend TrailingObjects;
228238

@@ -237,6 +247,7 @@ class MachineInstr
237247
const bool HasHeapAllocMarker;
238248
const bool HasPCSections;
239249
const bool HasCFIType;
250+
const bool HasMMRAs;
240251

241252
// Implement the `TrailingObjects` internal API.
242253
size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const {
@@ -255,11 +266,12 @@ class MachineInstr
255266
// Just a boring constructor to allow us to initialize the sizes. Always use
256267
// the `create` routine above.
257268
ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol,
258-
bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType)
269+
bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType,
270+
bool HasMMRAs)
259271
: NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol),
260272
HasPostInstrSymbol(HasPostInstrSymbol),
261273
HasHeapAllocMarker(HasHeapAllocMarker), HasPCSections(HasPCSections),
262-
HasCFIType(HasCFIType) {}
274+
HasCFIType(HasCFIType), HasMMRAs(HasMMRAs) {}
263275
};
264276

265277
/// Enumeration of the kinds of inline extra info available. It is important
@@ -838,6 +850,15 @@ class MachineInstr
838850
return nullptr;
839851
}
840852

853+
/// Helper to extract mmra.op metadata.
854+
MDNode *getMMRAMetadata() const {
855+
if (!Info)
856+
return nullptr;
857+
if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
858+
return EI->getMMRAMetadata();
859+
return nullptr;
860+
}
861+
841862
/// Helper to extract a CFI type hash if one has been added.
842863
uint32_t getCFIType() const {
843864
if (!Info)
@@ -1902,6 +1923,8 @@ class MachineInstr
19021923
// addresses into.
19031924
void setPCSections(MachineFunction &MF, MDNode *MD);
19041925

1926+
void setMMRAMetadata(MachineFunction &MF, MDNode *MMRAs);
1927+
19051928
/// Set the CFI type for the instruction.
19061929
void setCFIType(MachineFunction &MF, uint32_t Type);
19071930

@@ -2014,7 +2037,7 @@ class MachineInstr
20142037
void setExtraInfo(MachineFunction &MF, ArrayRef<MachineMemOperand *> MMOs,
20152038
MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol,
20162039
MDNode *HeapAllocMarker, MDNode *PCSections,
2017-
uint32_t CFIType);
2040+
uint32_t CFIType, MDNode *MMRAs);
20182041
};
20192042

20202043
/// Special DenseMapInfo traits to compare MachineInstr* by *value* of the

llvm/include/llvm/CodeGen/MachineInstrBuilder.h

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,12 @@ class MachineInstrBuilder {
322322
return *this;
323323
}
324324

325+
const MachineInstrBuilder &setMMRAMetadata(MDNode *MMRA) const {
326+
if (MMRA)
327+
MI->setMMRAMetadata(*MF, MMRA);
328+
return *this;
329+
}
330+
325331
/// Copy all the implicit operands from OtherMI onto this one.
326332
const MachineInstrBuilder &
327333
copyImplicitOps(const MachineInstr &OtherMI) const {
@@ -337,14 +343,15 @@ class MachineInstrBuilder {
337343
};
338344

339345
/// Set of metadata that should be preserved when using BuildMI(). This provides
340-
/// a more convenient way of preserving DebugLoc and PCSections.
346+
/// a more convenient way of preserving DebugLoc, PCSections and MMRA.
341347
class MIMetadata {
342348
public:
343349
MIMetadata() = default;
344-
MIMetadata(DebugLoc DL, MDNode *PCSections = nullptr)
345-
: DL(std::move(DL)), PCSections(PCSections) {}
346-
MIMetadata(const DILocation *DI, MDNode *PCSections = nullptr)
347-
: DL(DI), PCSections(PCSections) {}
350+
MIMetadata(DebugLoc DL, MDNode *PCSections = nullptr, MDNode *MMRA = nullptr)
351+
: DL(std::move(DL)), PCSections(PCSections), MMRA(MMRA) {}
352+
MIMetadata(const DILocation *DI, MDNode *PCSections = nullptr,
353+
MDNode *MMRA = nullptr)
354+
: DL(DI), PCSections(PCSections), MMRA(MMRA) {}
348355
explicit MIMetadata(const Instruction &From)
349356
: DL(From.getDebugLoc()),
350357
PCSections(From.getMetadata(LLVMContext::MD_pcsections)) {}
@@ -353,26 +360,30 @@ class MIMetadata {
353360

354361
const DebugLoc &getDL() const { return DL; }
355362
MDNode *getPCSections() const { return PCSections; }
363+
MDNode *getMMRAMetadata() const { return MMRA; }
356364

357365
private:
358366
DebugLoc DL;
359367
MDNode *PCSections = nullptr;
368+
MDNode *MMRA = nullptr;
360369
};
361370

362371
/// Builder interface. Specify how to create the initial instruction itself.
363372
inline MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD,
364373
const MCInstrDesc &MCID) {
365374
return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, MIMD.getDL()))
366-
.setPCSections(MIMD.getPCSections());
375+
.setPCSections(MIMD.getPCSections())
376+
.setMMRAMetadata(MIMD.getMMRAMetadata());
367377
}
368378

369379
/// This version of the builder sets up the first operand as a
370380
/// destination virtual register.
371381
inline MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD,
372382
const MCInstrDesc &MCID, Register DestReg) {
373383
return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, MIMD.getDL()))
374-
.setPCSections(MIMD.getPCSections())
375-
.addReg(DestReg, RegState::Define);
384+
.setPCSections(MIMD.getPCSections())
385+
.setMMRAMetadata(MIMD.getMMRAMetadata())
386+
.addReg(DestReg, RegState::Define);
376387
}
377388

378389
/// This version of the builder inserts the newly-built instruction before
@@ -386,8 +397,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
386397
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
387398
BB.insert(I, MI);
388399
return MachineInstrBuilder(MF, MI)
389-
.setPCSections(MIMD.getPCSections())
390-
.addReg(DestReg, RegState::Define);
400+
.setPCSections(MIMD.getPCSections())
401+
.setMMRAMetadata(MIMD.getMMRAMetadata())
402+
.addReg(DestReg, RegState::Define);
391403
}
392404

393405
/// This version of the builder inserts the newly-built instruction before
@@ -404,8 +416,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
404416
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
405417
BB.insert(I, MI);
406418
return MachineInstrBuilder(MF, MI)
407-
.setPCSections(MIMD.getPCSections())
408-
.addReg(DestReg, RegState::Define);
419+
.setPCSections(MIMD.getPCSections())
420+
.setMMRAMetadata(MIMD.getMMRAMetadata())
421+
.addReg(DestReg, RegState::Define);
409422
}
410423

411424
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineInstr &I,
@@ -435,7 +448,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
435448
MachineFunction &MF = *BB.getParent();
436449
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
437450
BB.insert(I, MI);
438-
return MachineInstrBuilder(MF, MI).setPCSections(MIMD.getPCSections());
451+
return MachineInstrBuilder(MF, MI)
452+
.setPCSections(MIMD.getPCSections())
453+
.setMMRAMetadata(MIMD.getMMRAMetadata());
439454
}
440455

441456
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
@@ -445,7 +460,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
445460
MachineFunction &MF = *BB.getParent();
446461
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
447462
BB.insert(I, MI);
448-
return MachineInstrBuilder(MF, MI).setPCSections(MIMD.getPCSections());
463+
return MachineInstrBuilder(MF, MI)
464+
.setPCSections(MIMD.getPCSections())
465+
.setMMRAMetadata(MIMD.getMMRAMetadata());
449466
}
450467

451468
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineInstr &I,

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ class SelectionDAG {
284284
CallSiteInfo CSInfo;
285285
MDNode *HeapAllocSite = nullptr;
286286
MDNode *PCSections = nullptr;
287+
MDNode *MMRA = nullptr;
287288
bool NoMerge = false;
288289
};
289290
/// Out-of-line extra information for SDNodes.
@@ -2279,11 +2280,21 @@ class SelectionDAG {
22792280
void addPCSections(const SDNode *Node, MDNode *MD) {
22802281
SDEI[Node].PCSections = MD;
22812282
}
2283+
/// Set MMRAMetadata to be associated with Node.
2284+
void addMMRAMetadata(const SDNode *Node, MDNode *MMRA) {
2285+
SDEI[Node].MMRA = MMRA;
2286+
}
22822287
/// Return PCSections associated with Node, or nullptr if none exists.
22832288
MDNode *getPCSections(const SDNode *Node) const {
22842289
auto It = SDEI.find(Node);
22852290
return It != SDEI.end() ? It->second.PCSections : nullptr;
22862291
}
2292+
/// Return the MMRA MDNode associated with Node, or nullptr if none
2293+
/// exists.
2294+
MDNode *getMMRAMetadata(const SDNode *Node) const {
2295+
auto It = SDEI.find(Node);
2296+
return It != SDEI.end() ? It->second.MMRA : nullptr;
2297+
}
22872298
/// Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
22882299
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge) {
22892300
if (NoMerge)

llvm/include/llvm/IR/FixedMetadataKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,4 @@ LLVM_FIXED_MD_KIND(MD_kcfi_type, "kcfi_type", 36)
5151
LLVM_FIXED_MD_KIND(MD_pcsections, "pcsections", 37)
5252
LLVM_FIXED_MD_KIND(MD_DIAssignID, "DIAssignID", 38)
5353
LLVM_FIXED_MD_KIND(MD_coro_outside_frame, "coro.outside.frame", 39)
54+
LLVM_FIXED_MD_KIND(MD_mmra, "mmra", 40)

0 commit comments

Comments
 (0)