Skip to content

[RFC] Memory Model Relaxation Annotations #78569

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
481 changes: 481 additions & 0 deletions llvm/docs/MemoryModelRelaxationAnnotations.rst

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions llvm/docs/Reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ LLVM and API reference documentation.
PDB/index
PointerAuth
ScudoHardenedAllocator
MemoryModelRelaxationAnnotations
MemTagSanitizer
Security
SecurityTransparencyReports
Expand Down Expand Up @@ -194,6 +195,9 @@ Additional Topics
:doc:`ScudoHardenedAllocator`
A library that implements a security-hardened `malloc()`.

:doc:`MemoryModelRelaxationAnnotations`
Target-defined relaxation to LLVM's concurrency model.

:doc:`MemTagSanitizer`
Security hardening for production code aiming to mitigate memory
related vulnerabilities. Based on the Armv8.5-A Memory Tagging Extension.
Expand Down
4 changes: 3 additions & 1 deletion llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Update on required toolchains to build LLVM
Changes to the LLVM IR
----------------------

- Added Memory Model Relaxation Annotations (MMRAs).

Changes to LLVM infrastructure
------------------------------

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

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

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

Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/VectorUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ MDNode *intersectAccessGroups(const Instruction *Inst1,
const Instruction *Inst2);

/// Specifically, let Kinds = [MD_tbaa, MD_alias_scope, MD_noalias, MD_fpmath,
/// MD_nontemporal, MD_access_group].
/// MD_nontemporal, MD_access_group, MD_mmra].
/// For K in Kinds, we get the MDNode for K from each of the
/// elements of VL, compute their "intersection" (i.e., the most generic
/// metadata value that covers all of the individual values), and set I's
Expand Down
9 changes: 9 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ struct MachineIRBuilderState {
DebugLoc DL;
/// PC sections metadata to be set to any instruction we create.
MDNode *PCSections = nullptr;
/// MMRA Metadata to be set on any instruction we create.
MDNode *MMRA = nullptr;

/// \name Fields describing the insertion point.
/// @{
Expand Down Expand Up @@ -354,6 +356,7 @@ class MachineIRBuilder {
setMBB(*MI.getParent());
State.II = MI.getIterator();
setPCSections(MI.getPCSections());
setMMRAMetadata(MI.getMMRAMetadata());
}
/// @}

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

/// Set the PC sections metadata to \p MD for all the next build instructions.
void setMMRAMetadata(MDNode *MMRA) { State.MMRA = MMRA; }

/// Get the current instruction's MMRA metadata.
MDNode *getMMRAMetadata() { return State.MMRA; }

/// Build and insert <empty> = \p Opcode <empty>.
/// The insertion point is the one set by the last call of either
/// setBasicBlock or setMI.
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/CodeGen/MachineFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,8 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
MachineInstr::ExtraInfo *createMIExtraInfo(
ArrayRef<MachineMemOperand *> MMOs, MCSymbol *PreInstrSymbol = nullptr,
MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr,
MDNode *PCSections = nullptr, uint32_t CFIType = 0);
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
MDNode *MMRAs = nullptr);

/// Allocate a string and populate it with the given external symbol name.
const char *createExternalSymbolName(StringRef Name);
Expand Down
43 changes: 33 additions & 10 deletions llvm/include/llvm/CodeGen/MachineInstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,37 +160,41 @@ class MachineInstr
MCSymbol *PreInstrSymbol = nullptr,
MCSymbol *PostInstrSymbol = nullptr,
MDNode *HeapAllocMarker = nullptr,
MDNode *PCSections = nullptr,
uint32_t CFIType = 0) {
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
MDNode *MMRAs = nullptr) {
bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
bool HasMMRAs = MMRAs != nullptr;
bool HasCFIType = CFIType != 0;
bool HasPCSections = PCSections != nullptr;
auto *Result = new (Allocator.Allocate(
totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *, uint32_t>(
MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol,
HasHeapAllocMarker + HasPCSections, HasCFIType),
HasHeapAllocMarker + HasPCSections + HasMMRAs, HasCFIType),
alignof(ExtraInfo)))
ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol,
HasHeapAllocMarker, HasPCSections, HasCFIType);
HasHeapAllocMarker, HasPCSections, HasCFIType, HasMMRAs);

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

unsigned MDNodeIdx = 0;

if (HasPreInstrSymbol)
Result->getTrailingObjects<MCSymbol *>()[0] = PreInstrSymbol;
if (HasPostInstrSymbol)
Result->getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol] =
PostInstrSymbol;
if (HasHeapAllocMarker)
Result->getTrailingObjects<MDNode *>()[0] = HeapAllocMarker;
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = HeapAllocMarker;
if (HasPCSections)
Result->getTrailingObjects<MDNode *>()[HasHeapAllocMarker] =
PCSections;
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = PCSections;
if (HasCFIType)
Result->getTrailingObjects<uint32_t>()[0] = CFIType;
if (HasMMRAs)
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = MMRAs;

return Result;
}
Expand Down Expand Up @@ -223,6 +227,12 @@ class MachineInstr
return HasCFIType ? getTrailingObjects<uint32_t>()[0] : 0;
}

MDNode *getMMRAMetadata() const {
return HasMMRAs ? getTrailingObjects<MDNode *>()[HasHeapAllocMarker +
HasPCSections]
: nullptr;
}

private:
friend TrailingObjects;

Expand All @@ -237,6 +247,7 @@ class MachineInstr
const bool HasHeapAllocMarker;
const bool HasPCSections;
const bool HasCFIType;
const bool HasMMRAs;

// Implement the `TrailingObjects` internal API.
size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const {
Expand All @@ -255,11 +266,12 @@ class MachineInstr
// Just a boring constructor to allow us to initialize the sizes. Always use
// the `create` routine above.
ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol,
bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType)
bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType,
bool HasMMRAs)
: NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol),
HasPostInstrSymbol(HasPostInstrSymbol),
HasHeapAllocMarker(HasHeapAllocMarker), HasPCSections(HasPCSections),
HasCFIType(HasCFIType) {}
HasCFIType(HasCFIType), HasMMRAs(HasMMRAs) {}
};

/// Enumeration of the kinds of inline extra info available. It is important
Expand Down Expand Up @@ -838,6 +850,15 @@ class MachineInstr
return nullptr;
}

/// Helper to extract mmra.op metadata.
MDNode *getMMRAMetadata() const {
if (!Info)
return nullptr;
if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
return EI->getMMRAMetadata();
return nullptr;
}

/// Helper to extract a CFI type hash if one has been added.
uint32_t getCFIType() const {
if (!Info)
Expand Down Expand Up @@ -1902,6 +1923,8 @@ class MachineInstr
// addresses into.
void setPCSections(MachineFunction &MF, MDNode *MD);

void setMMRAMetadata(MachineFunction &MF, MDNode *MMRAs);

/// Set the CFI type for the instruction.
void setCFIType(MachineFunction &MF, uint32_t Type);

Expand Down Expand Up @@ -2014,7 +2037,7 @@ class MachineInstr
void setExtraInfo(MachineFunction &MF, ArrayRef<MachineMemOperand *> MMOs,
MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol,
MDNode *HeapAllocMarker, MDNode *PCSections,
uint32_t CFIType);
uint32_t CFIType, MDNode *MMRAs);
};

/// Special DenseMapInfo traits to compare MachineInstr* by *value* of the
Expand Down
45 changes: 31 additions & 14 deletions llvm/include/llvm/CodeGen/MachineInstrBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,12 @@ class MachineInstrBuilder {
return *this;
}

const MachineInstrBuilder &setMMRAMetadata(MDNode *MMRA) const {
if (MMRA)
MI->setMMRAMetadata(*MF, MMRA);
return *this;
}

/// Copy all the implicit operands from OtherMI onto this one.
const MachineInstrBuilder &
copyImplicitOps(const MachineInstr &OtherMI) const {
Expand All @@ -337,14 +343,15 @@ class MachineInstrBuilder {
};

/// Set of metadata that should be preserved when using BuildMI(). This provides
/// a more convenient way of preserving DebugLoc and PCSections.
/// a more convenient way of preserving DebugLoc, PCSections and MMRA.
class MIMetadata {
public:
MIMetadata() = default;
MIMetadata(DebugLoc DL, MDNode *PCSections = nullptr)
: DL(std::move(DL)), PCSections(PCSections) {}
MIMetadata(const DILocation *DI, MDNode *PCSections = nullptr)
: DL(DI), PCSections(PCSections) {}
MIMetadata(DebugLoc DL, MDNode *PCSections = nullptr, MDNode *MMRA = nullptr)
: DL(std::move(DL)), PCSections(PCSections), MMRA(MMRA) {}
MIMetadata(const DILocation *DI, MDNode *PCSections = nullptr,
MDNode *MMRA = nullptr)
: DL(DI), PCSections(PCSections), MMRA(MMRA) {}
explicit MIMetadata(const Instruction &From)
: DL(From.getDebugLoc()),
PCSections(From.getMetadata(LLVMContext::MD_pcsections)) {}
Expand All @@ -353,26 +360,30 @@ class MIMetadata {

const DebugLoc &getDL() const { return DL; }
MDNode *getPCSections() const { return PCSections; }
MDNode *getMMRAMetadata() const { return MMRA; }

private:
DebugLoc DL;
MDNode *PCSections = nullptr;
MDNode *MMRA = nullptr;
};

/// Builder interface. Specify how to create the initial instruction itself.
inline MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD,
const MCInstrDesc &MCID) {
return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, MIMD.getDL()))
.setPCSections(MIMD.getPCSections());
.setPCSections(MIMD.getPCSections())
.setMMRAMetadata(MIMD.getMMRAMetadata());
}

/// This version of the builder sets up the first operand as a
/// destination virtual register.
inline MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD,
const MCInstrDesc &MCID, Register DestReg) {
return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, MIMD.getDL()))
.setPCSections(MIMD.getPCSections())
.addReg(DestReg, RegState::Define);
.setPCSections(MIMD.getPCSections())
.setMMRAMetadata(MIMD.getMMRAMetadata())
.addReg(DestReg, RegState::Define);
}

/// This version of the builder inserts the newly-built instruction before
Expand All @@ -386,8 +397,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
BB.insert(I, MI);
return MachineInstrBuilder(MF, MI)
.setPCSections(MIMD.getPCSections())
.addReg(DestReg, RegState::Define);
.setPCSections(MIMD.getPCSections())
.setMMRAMetadata(MIMD.getMMRAMetadata())
.addReg(DestReg, RegState::Define);
}

/// This version of the builder inserts the newly-built instruction before
Expand All @@ -404,8 +416,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
BB.insert(I, MI);
return MachineInstrBuilder(MF, MI)
.setPCSections(MIMD.getPCSections())
.addReg(DestReg, RegState::Define);
.setPCSections(MIMD.getPCSections())
.setMMRAMetadata(MIMD.getMMRAMetadata())
.addReg(DestReg, RegState::Define);
}

inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineInstr &I,
Expand Down Expand Up @@ -435,7 +448,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineFunction &MF = *BB.getParent();
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
BB.insert(I, MI);
return MachineInstrBuilder(MF, MI).setPCSections(MIMD.getPCSections());
return MachineInstrBuilder(MF, MI)
.setPCSections(MIMD.getPCSections())
.setMMRAMetadata(MIMD.getMMRAMetadata());
}

inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
Expand All @@ -445,7 +460,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineFunction &MF = *BB.getParent();
MachineInstr *MI = MF.CreateMachineInstr(MCID, MIMD.getDL());
BB.insert(I, MI);
return MachineInstrBuilder(MF, MI).setPCSections(MIMD.getPCSections());
return MachineInstrBuilder(MF, MI)
.setPCSections(MIMD.getPCSections())
.setMMRAMetadata(MIMD.getMMRAMetadata());
}

inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineInstr &I,
Expand Down
11 changes: 11 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ class SelectionDAG {
CallSiteInfo CSInfo;
MDNode *HeapAllocSite = nullptr;
MDNode *PCSections = nullptr;
MDNode *MMRA = nullptr;
bool NoMerge = false;
};
/// Out-of-line extra information for SDNodes.
Expand Down Expand Up @@ -2279,11 +2280,21 @@ class SelectionDAG {
void addPCSections(const SDNode *Node, MDNode *MD) {
SDEI[Node].PCSections = MD;
}
/// Set MMRAMetadata to be associated with Node.
void addMMRAMetadata(const SDNode *Node, MDNode *MMRA) {
SDEI[Node].MMRA = MMRA;
}
/// Return PCSections associated with Node, or nullptr if none exists.
MDNode *getPCSections(const SDNode *Node) const {
auto It = SDEI.find(Node);
return It != SDEI.end() ? It->second.PCSections : nullptr;
}
/// Return the MMRA MDNode associated with Node, or nullptr if none
/// exists.
MDNode *getMMRAMetadata(const SDNode *Node) const {
auto It = SDEI.find(Node);
return It != SDEI.end() ? It->second.MMRA : nullptr;
}
/// Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge) {
if (NoMerge)
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/FixedMetadataKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ LLVM_FIXED_MD_KIND(MD_kcfi_type, "kcfi_type", 36)
LLVM_FIXED_MD_KIND(MD_pcsections, "pcsections", 37)
LLVM_FIXED_MD_KIND(MD_DIAssignID, "DIAssignID", 38)
LLVM_FIXED_MD_KIND(MD_coro_outside_frame, "coro.outside.frame", 39)
LLVM_FIXED_MD_KIND(MD_mmra, "mmra", 40)
Loading