aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Attributes.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-10-10 14:33:13 +0200
committerNikita Popov <npopov@redhat.com>2022-10-21 12:11:25 +0200
commite9754f0211076bab34e5a070cb8eb392a21c0540 (patch)
treed4c30fa37bdf7959507d30a5184e3bc63c4cfb4f /llvm/lib/IR/Attributes.cpp
parent9d9de5a5df05df1abbd35351ded9c74cf4fc5ba6 (diff)
downloadllvm-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.cpp67
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));
}