Skip to content

Commit 2e5522f

Browse files
committed
[LLVM] Add support for printing and parsing symbolic address spaces
1 parent 3dcdb4c commit 2e5522f

File tree

6 files changed

+130
-39
lines changed

6 files changed

+130
-39
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Address space definitions for NVPTX target.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_TARGETPARSER_NVPTX_ADDRESS_SPACES_H
14+
#define LLVM_TARGETPARSER_NVPTX_ADDRESS_SPACES_H
15+
16+
namespace llvm::NVPTX {
17+
18+
using AddressSpaceUnderlyingType = unsigned int;
19+
enum AddressSpace : AddressSpaceUnderlyingType {
20+
Generic = 0,
21+
Global = 1,
22+
Shared = 3,
23+
Const = 4,
24+
Local = 5,
25+
SharedCluster = 7,
26+
27+
// NVPTX Backend Private:
28+
Param = 101
29+
};
30+
31+
} // namespace llvm::NVPTX
32+
33+
#endif // LLVM_TARGETPARSER_NVPTX_ADDRESS_SPACES_H

llvm/include/llvm/TargetParser/Triple.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,9 @@ class Triple {
13621362
/// Compute the LLVM IR data layout string based on the triple. Some targets
13631363
/// customize the layout based on the ABIName string.
13641364
LLVM_ABI std::string computeDataLayout(StringRef ABIName = "") const;
1365+
1366+
LLVM_ABI StringRef getAddressSpaceName(unsigned AS) const;
1367+
LLVM_ABI std::optional<unsigned> getAddressSpaceNumber(StringRef Name) const;
13651368
};
13661369

13671370
} // End llvm namespace

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1965,6 +1965,9 @@ bool LLParser::parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS) {
19651965
AddrSpace = M->getDataLayout().getDefaultGlobalsAddressSpace();
19661966
} else if (AddrSpaceStr == "P") {
19671967
AddrSpace = M->getDataLayout().getProgramAddressSpace();
1968+
} else if (std::optional<unsigned> AS =
1969+
M->getTargetTriple().getAddressSpaceNumber(AddrSpaceStr)) {
1970+
AddrSpace = *AS;
19681971
} else {
19691972
return tokError("invalid symbolic addrspace '" + AddrSpaceStr + "'");
19701973
}

llvm/lib/IR/AsmWriter.cpp

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ namespace {
543543

544544
class TypePrinting {
545545
public:
546-
TypePrinting(const Module *M = nullptr) : DeferredM(M) {}
546+
TypePrinting(const Module *M = nullptr)
547+
: M(M), TypesIncorporated(M == nullptr) {}
547548

548549
TypePrinting(const TypePrinting &) = delete;
549550
TypePrinting &operator=(const TypePrinting &) = delete;
@@ -564,7 +565,8 @@ class TypePrinting {
564565
void incorporateTypes();
565566

566567
/// A module to process lazily when needed. Set to nullptr as soon as used.
567-
const Module *DeferredM;
568+
const Module *M;
569+
bool TypesIncorporated;
568570

569571
TypeFinder NamedTypes;
570572

@@ -605,11 +607,11 @@ bool TypePrinting::empty() {
605607
}
606608

607609
void TypePrinting::incorporateTypes() {
608-
if (!DeferredM)
610+
if (TypesIncorporated)
609611
return;
610612

611-
NamedTypes.run(*DeferredM, false);
612-
DeferredM = nullptr;
613+
NamedTypes.run(*M, false);
614+
TypesIncorporated = true;
613615

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

635+
static void printAddressSpace(const Module *M, unsigned AS, raw_ostream &OS,
636+
bool ForcePrint = false) {
637+
if (AS == 0 && !ForcePrint)
638+
return;
639+
OS << " addrspace(";
640+
StringRef ASName = M ? M->getTargetTriple().getAddressSpaceName(AS) : "";
641+
if (!ASName.empty())
642+
OS << "\"" << ASName << "\"";
643+
else
644+
OS << AS;
645+
OS << ")";
646+
}
647+
633648
/// Write the specified type to the specified raw_ostream, making use of type
634649
/// names or up references to shorten the type name where possible.
635650
void TypePrinting::print(Type *Ty, raw_ostream &OS) {
@@ -686,8 +701,7 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
686701
case Type::PointerTyID: {
687702
PointerType *PTy = cast<PointerType>(Ty);
688703
OS << "ptr";
689-
if (unsigned AddressSpace = PTy->getAddressSpace())
690-
OS << " addrspace(" << AddressSpace << ')';
704+
printAddressSpace(M, PTy->getAddressSpace(), OS);
691705
return;
692706
}
693707
case Type::ArrayTyID: {
@@ -3894,12 +3908,12 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
38943908
printThreadLocalModel(GV->getThreadLocalMode(), Out);
38953909
StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr());
38963910
if (!UA.empty())
3897-
Out << UA << ' ';
3911+
Out << UA;
38983912

38993913
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
3900-
Out << "addrspace(" << AddressSpace << ") ";
3914+
printAddressSpace(GV->getParent(), AddressSpace, Out);
39013915
if (GV->isExternallyInitialized()) Out << "externally_initialized ";
3902-
Out << (GV->isConstant() ? "constant " : "global ");
3916+
Out << (GV->isConstant() ? " constant " : " global ");
39033917
TypePrinter.print(GV->getValueType(), Out);
39043918

39053919
if (GV->hasInitializer()) {
@@ -4172,9 +4186,9 @@ void AssemblyWriter::printFunction(const Function *F) {
41724186
// a module with a non-zero program address space or if there is no valid
41734187
// Module* so that the file can be parsed without the datalayout string.
41744188
const Module *Mod = F->getParent();
4175-
if (F->getAddressSpace() != 0 || !Mod ||
4176-
Mod->getDataLayout().getProgramAddressSpace() != 0)
4177-
Out << " addrspace(" << F->getAddressSpace() << ")";
4189+
bool ForcePrintAddressSpace =
4190+
!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0;
4191+
printAddressSpace(Mod, F->getAddressSpace(), Out, ForcePrintAddressSpace);
41784192
if (Attrs.hasFnAttrs())
41794193
Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttrs());
41804194
if (F->hasSection()) {
@@ -4356,17 +4370,13 @@ static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I,
43564370
return;
43574371
}
43584372
unsigned CallAddrSpace = Operand->getType()->getPointerAddressSpace();
4359-
bool PrintAddrSpace = CallAddrSpace != 0;
4360-
if (!PrintAddrSpace) {
4361-
const Module *Mod = getModuleFromVal(I);
4362-
// We also print it if it is zero but not equal to the program address space
4363-
// or if we can't find a valid Module* to make it possible to parse
4364-
// the resulting file even without a datalayout string.
4365-
if (!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0)
4366-
PrintAddrSpace = true;
4367-
}
4368-
if (PrintAddrSpace)
4369-
Out << " addrspace(" << CallAddrSpace << ")";
4373+
const Module *Mod = getModuleFromVal(I);
4374+
// We also print it if it is zero but not equal to the program address space
4375+
// or if we can't find a valid Module* to make it possible to parse
4376+
// the resulting file even without a datalayout string.
4377+
bool ForcePrintAddrSpace =
4378+
!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0;
4379+
printAddressSpace(Mod, CallAddrSpace, Out, ForcePrintAddrSpace);
43704380
}
43714381

43724382
// This member is called for each Instruction in a function..
@@ -4734,8 +4744,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
47344744
}
47354745

47364746
unsigned AddrSpace = AI->getAddressSpace();
4737-
if (AddrSpace != 0)
4738-
Out << ", addrspace(" << AddrSpace << ')';
4747+
if (AddrSpace != 0) {
4748+
Out << ",";
4749+
printAddressSpace(AI->getModule(), AddrSpace, Out);
4750+
}
47394751
} else if (isa<CastInst>(I)) {
47404752
if (Operand) {
47414753
Out << ' ';

llvm/lib/Target/NVPTX/NVPTX.h

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "llvm/Support/AtomicOrdering.h"
2121
#include "llvm/Support/CodeGen.h"
2222
#include "llvm/Target/TargetMachine.h"
23+
#include "llvm/TargetParser/NVPTXAddressSpaces.h"
24+
2325
namespace llvm {
2426
class FunctionPass;
2527
class MachineFunctionPass;
@@ -176,19 +178,6 @@ enum Scope : ScopeUnderlyingType {
176178
LASTSCOPE = DefaultDevice
177179
};
178180

179-
using AddressSpaceUnderlyingType = unsigned int;
180-
enum AddressSpace : AddressSpaceUnderlyingType {
181-
Generic = 0,
182-
Global = 1,
183-
Shared = 3,
184-
Const = 4,
185-
Local = 5,
186-
SharedCluster = 7,
187-
188-
// NVPTX Backend Private:
189-
Param = 101
190-
};
191-
192181
namespace PTXLdStInstCode {
193182
enum FromType { Unsigned = 0, Signed, Float, Untyped };
194183
} // namespace PTXLdStInstCode

llvm/lib/TargetParser/Triple.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/TargetParser/ARMTargetParser.h"
1818
#include "llvm/TargetParser/ARMTargetParserCommon.h"
1919
#include "llvm/TargetParser/Host.h"
20+
#include "llvm/TargetParser/NVPTXAddressSpaces.h"
2021
#include <cassert>
2122
#include <cstring>
2223
using namespace llvm;
@@ -2361,6 +2362,56 @@ ExceptionHandling Triple::getDefaultExceptionHandling() const {
23612362
return ExceptionHandling::None;
23622363
}
23632364

2365+
static StringRef getNVPTXAddressSpaceName(unsigned AS) {
2366+
switch (AS) {
2367+
case NVPTX::Generic:
2368+
return "generic";
2369+
case NVPTX::Global:
2370+
return "global";
2371+
case NVPTX::Shared:
2372+
return "shared";
2373+
case NVPTX::Const:
2374+
return "const";
2375+
case NVPTX::Local:
2376+
return "local";
2377+
case NVPTX::SharedCluster:
2378+
return "shared_cluster";
2379+
default:
2380+
return "";
2381+
}
2382+
}
2383+
2384+
static std::optional<unsigned> getNVPTXAddressSpaceNumber(StringRef Name) {
2385+
return StringSwitch<std::optional<unsigned>>(Name)
2386+
.Case("generic", NVPTX::Generic)
2387+
.Case("global", NVPTX::Global)
2388+
.Case("shared", NVPTX::Shared)
2389+
.Case("const", NVPTX::Const)
2390+
.Case("local", NVPTX::Local)
2391+
.Case("shared_cluster", NVPTX::SharedCluster)
2392+
.Default(std::nullopt);
2393+
}
2394+
2395+
StringRef Triple::getAddressSpaceName(unsigned AS) const {
2396+
switch (getArch()) {
2397+
case Triple::nvptx:
2398+
case Triple::nvptx64:
2399+
return getNVPTXAddressSpaceName(AS);
2400+
default:
2401+
return "";
2402+
}
2403+
}
2404+
2405+
std::optional<unsigned> Triple::getAddressSpaceNumber(StringRef Name) const {
2406+
switch (getArch()) {
2407+
case Triple::nvptx:
2408+
case Triple::nvptx64:
2409+
return getNVPTXAddressSpaceNumber(Name);
2410+
default:
2411+
return std::nullopt;
2412+
}
2413+
}
2414+
23642415
// HLSL triple environment orders are relied on in the front end
23652416
static_assert(Triple::Vertex - Triple::Pixel == 1,
23662417
"incorrect HLSL stage order");

0 commit comments

Comments
 (0)