Skip to content
Open
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
19 changes: 15 additions & 4 deletions llvm/include/llvm/IR/DataLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
Expand Down Expand Up @@ -92,6 +93,9 @@ class DataLayout {
/// of this would be CHERI capabilities where the validity bit is stored
/// separately from the pointer address+bounds information.
bool HasExternalState;
// Symbolic name of the address space.
std::string AddrSpaceName;

LLVM_ABI bool operator==(const PointerSpec &Other) const;
};

Expand Down Expand Up @@ -158,7 +162,8 @@ class DataLayout {
/// Sets or updates the specification for pointer in the given address space.
void setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth, Align ABIAlign,
Align PrefAlign, uint32_t IndexBitWidth,
bool HasUnstableRepr, bool HasExternalState);
bool HasUnstableRepr, bool HasExternalState,
StringRef AddrSpaceName);

/// Internal helper to get alignment for integer of given bitwidth.
LLVM_ABI Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const;
Expand All @@ -173,11 +178,13 @@ class DataLayout {
Error parseAggregateSpec(StringRef Spec);

/// Attempts to parse pointer specification ('p').
Error parsePointerSpec(StringRef Spec);
Error parsePointerSpec(StringRef Spec,
SmallDenseSet<StringRef, 8> &AddrSpaceNames);

/// Attempts to parse a single specification.
Error parseSpecification(StringRef Spec,
SmallVectorImpl<unsigned> &NonIntegralAddressSpaces);
SmallVectorImpl<unsigned> &NonIntegralAddressSpaces,
SmallDenseSet<StringRef, 8> &AddrSpaceNames);

/// Attempts to parse a data layout string.
Error parseLayoutString(StringRef LayoutString);
Expand Down Expand Up @@ -324,9 +331,13 @@ class DataLayout {
return false;
}

/// Layout pointer alignment
/// Layout pointer alignment.
LLVM_ABI Align getPointerABIAlignment(unsigned AS) const;

LLVM_ABI StringRef getAddressSpaceName(unsigned AS) const;

LLVM_ABI std::optional<unsigned> getNamedAddressSpace(StringRef Name) const;

/// Return target's alignment for stack-based pointers
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1958,13 +1958,16 @@ bool LLParser::parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS) {

auto ParseAddrspaceValue = [&](unsigned &AddrSpace) -> bool {
if (Lex.getKind() == lltok::StringConstant) {
auto AddrSpaceStr = Lex.getStrVal();
const std::string &AddrSpaceStr = Lex.getStrVal();
if (AddrSpaceStr == "A") {
AddrSpace = M->getDataLayout().getAllocaAddrSpace();
} else if (AddrSpaceStr == "G") {
AddrSpace = M->getDataLayout().getDefaultGlobalsAddressSpace();
} else if (AddrSpaceStr == "P") {
AddrSpace = M->getDataLayout().getProgramAddressSpace();
} else if (std::optional<unsigned> AS =
M->getDataLayout().getNamedAddressSpace(AddrSpaceStr)) {
AddrSpace = *AS;
} else {
return tokError("invalid symbolic addrspace '" + AddrSpaceStr + "'");
}
Expand Down
71 changes: 42 additions & 29 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,8 @@ namespace {

class TypePrinting {
public:
TypePrinting(const Module *M = nullptr) : DeferredM(M) {}
TypePrinting(const Module *M = nullptr)
: M(M), TypesIncorporated(M == nullptr) {}

TypePrinting(const TypePrinting &) = delete;
TypePrinting &operator=(const TypePrinting &) = delete;
Expand All @@ -563,8 +564,9 @@ class TypePrinting {
private:
void incorporateTypes();

/// A module to process lazily when needed. Set to nullptr as soon as used.
const Module *DeferredM;
/// A module to process lazily.
const Module *M;
bool TypesIncorporated;

TypeFinder NamedTypes;

Expand Down Expand Up @@ -605,11 +607,11 @@ bool TypePrinting::empty() {
}

void TypePrinting::incorporateTypes() {
if (!DeferredM)
if (TypesIncorporated)
return;

NamedTypes.run(*DeferredM, false);
DeferredM = nullptr;
NamedTypes.run(*M, false);
TypesIncorporated = true;

// The list of struct types we got back includes all the struct types, split
// the unnamed ones out to a numbering and remove the anonymous structs.
Expand All @@ -630,6 +632,20 @@ void TypePrinting::incorporateTypes() {
NamedTypes.erase(NextToUse, NamedTypes.end());
}

static void printAddressSpace(const Module *M, unsigned AS, raw_ostream &OS,
StringRef Prefix = " ", StringRef Suffix = "",
bool ForcePrint = false) {
if (AS == 0 && !ForcePrint)
return;
OS << Prefix << "addrspace(";
StringRef ASName = M ? M->getDataLayout().getAddressSpaceName(AS) : "";
if (!ASName.empty())
OS << "\"" << ASName << "\"";
else
OS << AS;
OS << ")" << Suffix;
}

/// Write the specified type to the specified raw_ostream, making use of type
/// names or up references to shorten the type name where possible.
void TypePrinting::print(Type *Ty, raw_ostream &OS) {
Expand Down Expand Up @@ -686,8 +702,7 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
case Type::PointerTyID: {
PointerType *PTy = cast<PointerType>(Ty);
OS << "ptr";
if (unsigned AddressSpace = PTy->getAddressSpace())
OS << " addrspace(" << AddressSpace << ')';
printAddressSpace(M, PTy->getAddressSpace(), OS);
return;
}
case Type::ArrayTyID: {
Expand Down Expand Up @@ -3896,10 +3911,10 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
printThreadLocalModel(GV->getThreadLocalMode(), Out);
StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr());
if (!UA.empty())
Out << UA << ' ';
Out << UA << ' ';

if (unsigned AddressSpace = GV->getType()->getAddressSpace())
Out << "addrspace(" << AddressSpace << ") ";
printAddressSpace(GV->getParent(), GV->getType()->getAddressSpace(), Out,
/*Prefix=*/"", /*Suffix=*/" ");
if (GV->isExternallyInitialized()) Out << "externally_initialized ";
Out << (GV->isConstant() ? "constant " : "global ");
TypePrinter.print(GV->getValueType(), Out);
Expand Down Expand Up @@ -4174,9 +4189,10 @@ void AssemblyWriter::printFunction(const Function *F) {
// a module with a non-zero program address space or if there is no valid
// Module* so that the file can be parsed without the datalayout string.
const Module *Mod = F->getParent();
if (F->getAddressSpace() != 0 || !Mod ||
Mod->getDataLayout().getProgramAddressSpace() != 0)
Out << " addrspace(" << F->getAddressSpace() << ")";
bool ForcePrintAddressSpace =
!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0;
printAddressSpace(Mod, F->getAddressSpace(), Out, /*Prefix=*/" ",
/*Suffix=*/"", ForcePrintAddressSpace);
if (Attrs.hasFnAttrs())
Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttrs());
if (F->hasSection()) {
Expand Down Expand Up @@ -4352,23 +4368,21 @@ void AssemblyWriter::printInfoComment(const Value &V, bool isMaterializable) {

static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I,
raw_ostream &Out) {
// We print the address space of the call if it is non-zero.
if (Operand == nullptr) {
Out << " <cannot get addrspace!>";
return;
}

// We print the address space of the call if it is non-zero.
// We also print it if it is zero but not equal to the program address space
// or if we can't find a valid Module* to make it possible to parse
// the resulting file even without a datalayout string.
unsigned CallAddrSpace = Operand->getType()->getPointerAddressSpace();
bool PrintAddrSpace = CallAddrSpace != 0;
if (!PrintAddrSpace) {
const Module *Mod = getModuleFromVal(I);
// We also print it if it is zero but not equal to the program address space
// or if we can't find a valid Module* to make it possible to parse
// the resulting file even without a datalayout string.
if (!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0)
PrintAddrSpace = true;
}
if (PrintAddrSpace)
Out << " addrspace(" << CallAddrSpace << ")";
const Module *Mod = getModuleFromVal(I);
bool ForcePrintAddrSpace =
!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0;
printAddressSpace(Mod, CallAddrSpace, Out, /*Prefix=*/" ", /*Suffix=*/"",
ForcePrintAddrSpace);
}

// This member is called for each Instruction in a function..
Expand Down Expand Up @@ -4735,9 +4749,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ", align " << A->value();
}

unsigned AddrSpace = AI->getAddressSpace();
if (AddrSpace != 0)
Out << ", addrspace(" << AddrSpace << ')';
printAddressSpace(AI->getModule(), AI->getAddressSpace(), Out,
/*Prefix=*/", ");
} else if (isa<CastInst>(I)) {
if (Operand) {
Out << ' ';
Expand Down
Loading
Loading