Skip to content

Commit 731c300

Browse files
committed
[RFC] Memory Model Relaxation Annotations
Work-in-progress patch to implement the core/target-agnostic components of Memory Model Relaxation Annotations. This diff is mostly complete but likely has a few holes, especially in codegen (MMRAs aren't always carried over to MI layer I believe). Most of the work needs to be done in adding tests and analyzing the outputs to find what's missing.
1 parent 5fcf907 commit 731c300

35 files changed

+1487
-52
lines changed

llvm/docs/MemoryModelRelaxationAnnotations.rst

Lines changed: 476 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/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
@@ -52,6 +52,8 @@ struct MachineIRBuilderState {
5252
DebugLoc DL;
5353
/// PC sections metadata to be set to any instruction we create.
5454
MDNode *PCSections = nullptr;
55+
/// MMRA Metadata to be set on any instruction we create.
56+
MDNode *MMRA = nullptr;
5557

5658
/// \name Fields describing the insertion point.
5759
/// @{
@@ -353,6 +355,7 @@ class MachineIRBuilder {
353355
setMBB(*MI.getParent());
354356
State.II = MI.getIterator();
355357
setPCSections(MI.getPCSections());
358+
setMMRAMetadata(MI.getMMRAMetadata());
356359
}
357360
/// @}
358361

@@ -383,9 +386,15 @@ class MachineIRBuilder {
383386
/// Set the PC sections metadata to \p MD for all the next build instructions.
384387
void setPCSections(MDNode *MD) { State.PCSections = MD; }
385388

389+
/// Set the PC sections metadata to \p MD for all the next build instructions.
390+
void setMMRAMetadata(MDNode *MMRA) { State.MMRA = MMRA; }
391+
386392
/// Get the current instruction's PC sections metadata.
387393
MDNode *getPCSections() { return State.PCSections; }
388394

395+
/// Get the current instruction's MMRA metadata.
396+
MDNode *getMMRAMetadata() { return State.MMRA; }
397+
389398
/// Build and insert <empty> = \p Opcode <empty>.
390399
/// The insertion point is the one set by the last call of either
391400
/// setBasicBlock or setMI.

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,8 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
11011101
MachineInstr::ExtraInfo *createMIExtraInfo(
11021102
ArrayRef<MachineMemOperand *> MMOs, MCSymbol *PreInstrSymbol = nullptr,
11031103
MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr,
1104-
MDNode *PCSections = nullptr, uint32_t CFIType = 0);
1104+
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
1105+
MDNode *MMRAs = nullptr);
11051106

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

llvm/include/llvm/CodeGen/MachineInstr.h

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/CodeGen/TargetOpcodes.h"
2626
#include "llvm/IR/DebugLoc.h"
2727
#include "llvm/IR/InlineAsm.h"
28+
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
2829
#include "llvm/MC/MCInstrDesc.h"
2930
#include "llvm/MC/MCSymbol.h"
3031
#include "llvm/Support/ArrayRecycler.h"
@@ -157,37 +158,41 @@ class MachineInstr
157158
MCSymbol *PreInstrSymbol = nullptr,
158159
MCSymbol *PostInstrSymbol = nullptr,
159160
MDNode *HeapAllocMarker = nullptr,
160-
MDNode *PCSections = nullptr,
161-
uint32_t CFIType = 0) {
161+
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
162+
MDNode *MMRAs = nullptr) {
162163
bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
163164
bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
164165
bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
166+
bool HasMMRAs = MMRAs != nullptr;
165167
bool HasCFIType = CFIType != 0;
166168
bool HasPCSections = PCSections != nullptr;
167169
auto *Result = new (Allocator.Allocate(
168170
totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *, uint32_t>(
169171
MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol,
170-
HasHeapAllocMarker + HasPCSections, HasCFIType),
172+
HasHeapAllocMarker + HasPCSections + HasMMRAs, HasCFIType),
171173
alignof(ExtraInfo)))
172174
ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol,
173-
HasHeapAllocMarker, HasPCSections, HasCFIType);
175+
HasHeapAllocMarker, HasPCSections, HasCFIType, HasMMRAs);
174176

175177
// Copy the actual data into the trailing objects.
176178
std::copy(MMOs.begin(), MMOs.end(),
177179
Result->getTrailingObjects<MachineMemOperand *>());
178180

181+
unsigned MDNodeIdx = 0;
182+
179183
if (HasPreInstrSymbol)
180184
Result->getTrailingObjects<MCSymbol *>()[0] = PreInstrSymbol;
181185
if (HasPostInstrSymbol)
182186
Result->getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol] =
183187
PostInstrSymbol;
184188
if (HasHeapAllocMarker)
185-
Result->getTrailingObjects<MDNode *>()[0] = HeapAllocMarker;
189+
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = HeapAllocMarker;
186190
if (HasPCSections)
187-
Result->getTrailingObjects<MDNode *>()[HasHeapAllocMarker] =
188-
PCSections;
191+
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = PCSections;
189192
if (HasCFIType)
190193
Result->getTrailingObjects<uint32_t>()[0] = CFIType;
194+
if (HasMMRAs)
195+
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = MMRAs;
191196

192197
return Result;
193198
}
@@ -220,6 +225,12 @@ class MachineInstr
220225
return HasCFIType ? getTrailingObjects<uint32_t>()[0] : 0;
221226
}
222227

228+
MDNode *getMMRAMetadata() const {
229+
return HasMMRAs ? getTrailingObjects<MDNode *>()[HasHeapAllocMarker +
230+
HasPCSections]
231+
: nullptr;
232+
}
233+
223234
private:
224235
friend TrailingObjects;
225236

@@ -234,6 +245,7 @@ class MachineInstr
234245
const bool HasHeapAllocMarker;
235246
const bool HasPCSections;
236247
const bool HasCFIType;
248+
const bool HasMMRAs;
237249

238250
// Implement the `TrailingObjects` internal API.
239251
size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const {
@@ -248,15 +260,19 @@ class MachineInstr
248260
size_t numTrailingObjects(OverloadToken<uint32_t>) const {
249261
return HasCFIType;
250262
}
263+
size_t numTrailingObjects(OverloadToken<MMRAMetadata>) const {
264+
return HasMMRAs;
265+
}
251266

252267
// Just a boring constructor to allow us to initialize the sizes. Always use
253268
// the `create` routine above.
254269
ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol,
255-
bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType)
270+
bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType,
271+
bool HasMMRAs)
256272
: NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol),
257273
HasPostInstrSymbol(HasPostInstrSymbol),
258274
HasHeapAllocMarker(HasHeapAllocMarker), HasPCSections(HasPCSections),
259-
HasCFIType(HasCFIType) {}
275+
HasCFIType(HasCFIType), HasMMRAs(HasMMRAs) {}
260276
};
261277

262278
/// Enumeration of the kinds of inline extra info available. It is important
@@ -835,6 +851,15 @@ class MachineInstr
835851
return nullptr;
836852
}
837853

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

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

@@ -2010,7 +2037,7 @@ class MachineInstr
20102037
void setExtraInfo(MachineFunction &MF, ArrayRef<MachineMemOperand *> MMOs,
20112038
MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol,
20122039
MDNode *HeapAllocMarker, MDNode *PCSections,
2013-
uint32_t CFIType);
2040+
uint32_t CFIType, MDNode *MMRAs);
20142041
};
20152042

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

llvm/include/llvm/CodeGen/MachineInstrBuilder.h

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/CodeGen/TargetRegisterInfo.h"
3030
#include "llvm/IR/InstrTypes.h"
3131
#include "llvm/IR/Intrinsics.h"
32+
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
3233
#include "llvm/Support/ErrorHandling.h"
3334
#include <cassert>
3435
#include <cstdint>
@@ -322,6 +323,12 @@ class MachineInstrBuilder {
322323
return *this;
323324
}
324325

326+
const MachineInstrBuilder &setMMRAMetadata(MDNode *MMRA) const {
327+
if (MMRA)
328+
MI->setMMRAMetadata(*MF, MMRA);
329+
return *this;
330+
}
331+
325332
/// Copy all the implicit operands from OtherMI onto this one.
326333
const MachineInstrBuilder &
327334
copyImplicitOps(const MachineInstr &OtherMI) const {
@@ -337,14 +344,15 @@ class MachineInstrBuilder {
337344
};
338345

339346
/// Set of metadata that should be preserved when using BuildMI(). This provides
340-
/// a more convenient way of preserving DebugLoc and PCSections.
347+
/// a more convenient way of preserving DebugLoc, PCSections and MMRA.
341348
class MIMetadata {
342349
public:
343350
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) {}
351+
MIMetadata(DebugLoc DL, MDNode *PCSections = nullptr, MDNode *MMRA = nullptr)
352+
: DL(std::move(DL)), PCSections(PCSections), MMRA(MMRA) {}
353+
MIMetadata(const DILocation *DI, MDNode *PCSections = nullptr,
354+
MDNode *MMRA = nullptr)
355+
: DL(DI), PCSections(PCSections), MMRA(MMRA) {}
348356
explicit MIMetadata(const Instruction &From)
349357
: DL(From.getDebugLoc()),
350358
PCSections(From.getMetadata(LLVMContext::MD_pcsections)) {}
@@ -353,26 +361,30 @@ class MIMetadata {
353361

354362
const DebugLoc &getDL() const { return DL; }
355363
MDNode *getPCSections() const { return PCSections; }
364+
MDNode *getMMRAMetadata() const { return MMRA; }
356365

357366
private:
358367
DebugLoc DL;
359368
MDNode *PCSections = nullptr;
369+
MDNode *MMRA = nullptr;
360370
};
361371

362372
/// Builder interface. Specify how to create the initial instruction itself.
363373
inline MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD,
364374
const MCInstrDesc &MCID) {
365375
return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, MIMD.getDL()))
366-
.setPCSections(MIMD.getPCSections());
376+
.setPCSections(MIMD.getPCSections())
377+
.setMMRAMetadata(MIMD.getMMRAMetadata());
367378
}
368379

369380
/// This version of the builder sets up the first operand as a
370381
/// destination virtual register.
371382
inline MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD,
372383
const MCInstrDesc &MCID, Register DestReg) {
373384
return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, MIMD.getDL()))
374-
.setPCSections(MIMD.getPCSections())
375-
.addReg(DestReg, RegState::Define);
385+
.setPCSections(MIMD.getPCSections())
386+
.setMMRAMetadata(MIMD.getMMRAMetadata())
387+
.addReg(DestReg, RegState::Define);
376388
}
377389

378390
/// This version of the builder inserts the newly-built instruction before
@@ -386,8 +398,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
386398
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
387399
BB.insert(I, MI);
388400
return MachineInstrBuilder(MF, MI)
389-
.setPCSections(MIMD.getPCSections())
390-
.addReg(DestReg, RegState::Define);
401+
.setPCSections(MIMD.getPCSections())
402+
.setMMRAMetadata(MIMD.getMMRAMetadata())
403+
.addReg(DestReg, RegState::Define);
391404
}
392405

393406
/// This version of the builder inserts the newly-built instruction before
@@ -404,8 +417,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
404417
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
405418
BB.insert(I, MI);
406419
return MachineInstrBuilder(MF, MI)
407-
.setPCSections(MIMD.getPCSections())
408-
.addReg(DestReg, RegState::Define);
420+
.setPCSections(MIMD.getPCSections())
421+
.setMMRAMetadata(MIMD.getMMRAMetadata())
422+
.addReg(DestReg, RegState::Define);
409423
}
410424

411425
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineInstr &I,
@@ -435,7 +449,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
435449
MachineFunction &MF = *BB.getParent();
436450
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
437451
BB.insert(I, MI);
438-
return MachineInstrBuilder(MF, MI).setPCSections(MIMD.getPCSections());
452+
return MachineInstrBuilder(MF, MI)
453+
.setPCSections(MIMD.getPCSections())
454+
.setMMRAMetadata(MIMD.getMMRAMetadata());
439455
}
440456

441457
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
@@ -445,7 +461,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
445461
MachineFunction &MF = *BB.getParent();
446462
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
447463
BB.insert(I, MI);
448-
return MachineInstrBuilder(MF, MI).setPCSections(MIMD.getPCSections());
464+
return MachineInstrBuilder(MF, MI)
465+
.setPCSections(MIMD.getPCSections())
466+
.setMMRAMetadata(MIMD.getMMRAMetadata());
449467
}
450468

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

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "llvm/CodeGen/SelectionDAGNodes.h"
3434
#include "llvm/CodeGen/ValueTypes.h"
3535
#include "llvm/IR/DebugLoc.h"
36+
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
3637
#include "llvm/IR/Metadata.h"
3738
#include "llvm/Support/Allocator.h"
3839
#include "llvm/Support/ArrayRecycler.h"
@@ -285,6 +286,7 @@ class SelectionDAG {
285286
CallSiteInfo CSInfo;
286287
MDNode *HeapAllocSite = nullptr;
287288
MDNode *PCSections = nullptr;
289+
MDNode *MMRA = nullptr;
288290
bool NoMerge = false;
289291
};
290292
/// Out-of-line extra information for SDNodes.
@@ -2326,11 +2328,21 @@ class SelectionDAG {
23262328
void addPCSections(const SDNode *Node, MDNode *MD) {
23272329
SDEI[Node].PCSections = MD;
23282330
}
2331+
/// Set MMRAMetadata to be associated with Node.
2332+
void addMMRAMetadata(const SDNode *Node, MDNode *MMRA) {
2333+
SDEI[Node].MMRA = MMRA;
2334+
}
23292335
/// Return PCSections associated with Node, or nullptr if none exists.
23302336
MDNode *getPCSections(const SDNode *Node) const {
23312337
auto It = SDEI.find(Node);
23322338
return It != SDEI.end() ? It->second.PCSections : nullptr;
23332339
}
2340+
/// Return the MMRA MDNode associated with Node, or nullptr if none
2341+
/// exists.
2342+
MDNode *getMMRAMetadata(const SDNode *Node) const {
2343+
auto It = SDEI.find(Node);
2344+
return It != SDEI.end() ? It->second.MMRA : nullptr;
2345+
}
23342346
/// Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
23352347
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge) {
23362348
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)