diff options
author | Nikita Popov <npopov@redhat.com> | 2022-10-10 14:33:13 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2022-10-21 12:11:25 +0200 |
commit | e9754f0211076bab34e5a070cb8eb392a21c0540 (patch) | |
tree | d4c30fa37bdf7959507d30a5184e3bc63c4cfb4f /llvm/lib/IR/Attributes.cpp | |
parent | 9d9de5a5df05df1abbd35351ded9c74cf4fc5ba6 (diff) | |
download | llvm-e9754f0211076bab34e5a070cb8eb392a21c0540.zip llvm-e9754f0211076bab34e5a070cb8eb392a21c0540.tar.gz llvm-e9754f0211076bab34e5a070cb8eb392a21c0540.tar.bz2 |
[IR] Add support for memory attribute
This implements IR and bitcode support for the memory attribute,
as specified in https://reviews.llvm.org/D135597.
The new attribute is not used for anything yet (and as such, the
old memory attributes are unaffected).
Differential Revision: https://reviews.llvm.org/D135592
Diffstat (limited to 'llvm/lib/IR/Attributes.cpp')
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 3ae15b6..333caf7 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -26,6 +26,7 @@ #include "llvm/Config/llvm-config.h" #include "llvm/IR/Function.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/ModRef.h" #include "llvm/IR/Type.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" @@ -383,6 +384,26 @@ AllocFnKind Attribute::getAllocKind() const { return AllocFnKind(pImpl->getValueAsInt()); } +MemoryEffects Attribute::getMemoryEffects() const { + assert(hasAttribute(Attribute::Memory) && + "Can only call getMemoryEffects() on memory attribute"); + return MemoryEffects::createFromIntValue(pImpl->getValueAsInt()); +} + +static const char *getModRefStr(ModRefInfo MR) { + switch (MR) { + case ModRefInfo::NoModRef: + return "none"; + case ModRefInfo::Ref: + return "read"; + case ModRefInfo::Mod: + return "write"; + case ModRefInfo::ModRef: + return "readwrite"; + } + llvm_unreachable("Invalid ModRefInfo"); +} + std::string Attribute::getAsString(bool InAttrGrp) const { if (!pImpl) return {}; @@ -474,6 +495,48 @@ std::string Attribute::getAsString(bool InAttrGrp) const { .str(); } + if (hasAttribute(Attribute::Memory)) { + std::string Result; + raw_string_ostream OS(Result); + bool First = true; + OS << "memory("; + + MemoryEffects ME = getMemoryEffects(); + + // Print access kind for "other" as the default access kind. This way it + // will apply to any new location kinds that get split out of "other". + ModRefInfo OtherMR = ME.getModRef(MemoryEffects::Other); + if (OtherMR != ModRefInfo::NoModRef || ME.getModRef() == OtherMR) { + First = false; + OS << getModRefStr(OtherMR); + } + + for (auto Loc : MemoryEffects::locations()) { + ModRefInfo MR = ME.getModRef(Loc); + if (MR == OtherMR) + continue; + + if (!First) + OS << ", "; + First = false; + + switch (Loc) { + case MemoryEffects::ArgMem: + OS << "argmem: "; + break; + case MemoryEffects::InaccessibleMem: + OS << "inaccessiblemem: "; + break; + case MemoryEffects::Other: + llvm_unreachable("This is represented as the default access kind"); + } + OS << getModRefStr(MR); + } + OS << ")"; + OS.flush(); + return Result; + } + // Convert target-dependent attributes to strings of the form: // // "kind" @@ -1723,6 +1786,10 @@ AttrBuilder &AttrBuilder::addUWTableAttr(UWTableKind Kind) { return addRawIntAttr(Attribute::UWTable, uint64_t(Kind)); } +AttrBuilder &AttrBuilder::addMemoryAttr(MemoryEffects ME) { + return addRawIntAttr(Attribute::Memory, ME.toIntValue()); +} + AttrBuilder &AttrBuilder::addAllocKindAttr(AllocFnKind Kind) { return addRawIntAttr(Attribute::AllocKind, static_cast<uint64_t>(Kind)); } |