Skip to content

Commit 3bc4157

Browse files
committed
Add a default address space for globals to DataLayout
This is similar to the existing alloca and program address spaces (D37052) and should be used when creating/accessing global variables. We need this in our CHERI fork of LLVM to place all globals in address space 200. This ensures that values are accessed using CHERI load/store instructions instead of the normal MIPS/RISC-V ones. The problem this is trying to fix is that most of the time the type of globals is created using a simple PointerType::getUnqual() (or ::get() with the default address-space value of 0). This does not work for us and we get assertion/compilation/instruction selection failures whenever a new call is added that uses the default value of zero. In our fork we have removed the default parameter value of zero for most address space arguments and use DL.getProgramAddressSpace() or DL.getGlobalsAddressSpace() whenever possible. If this change is accepted, I will upstream follow-up patches to use DL.getGlobalsAddressSpace() instead of relying on the default value of 0 for PointerType::get(), etc. This patch and the follow-up changes will not have any functional changes for existing backends with the default globals address space of zero. A follow-up commit will change the default globals address space for AMDGPU to 1. Reviewed By: dylanmckay Differential Revision: https://reviews.llvm.org/D70947
1 parent 4766a86 commit 3bc4157

File tree

7 files changed

+69
-7
lines changed

7 files changed

+69
-7
lines changed

llvm/docs/LangRef.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2370,6 +2370,14 @@ as follows:
23702370
program memory space defaults to the default address space of 0,
23712371
which corresponds to a Von Neumann architecture that has code
23722372
and data in the same space.
2373+
``G<address space>``
2374+
Specifies the address space to be used by default when creating global
2375+
variables. If omitted, the globals address space defaults to the default
2376+
address space 0.
2377+
Note: variable declarations without an address space are always created in
2378+
address space 0, this property only affects the default value to be used
2379+
when creating globals without additional contextual information (e.g. in
2380+
LLVM passes).
23732381
``A<address space>``
23742382
Specifies the address space of objects created by '``alloca``'.
23752383
Defaults to the default address space of 0.

llvm/include/llvm/IR/DataLayout.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class DataLayout {
123123
unsigned AllocaAddrSpace;
124124
MaybeAlign StackNaturalAlign;
125125
unsigned ProgramAddrSpace;
126+
unsigned DefaultGlobalsAddrSpace;
126127

127128
MaybeAlign FunctionPtrAlign;
128129
FunctionPtrAlignType TheFunctionPtrAlignType;
@@ -219,6 +220,7 @@ class DataLayout {
219220
FunctionPtrAlign = DL.FunctionPtrAlign;
220221
TheFunctionPtrAlignType = DL.TheFunctionPtrAlignType;
221222
ProgramAddrSpace = DL.ProgramAddrSpace;
223+
DefaultGlobalsAddrSpace = DL.DefaultGlobalsAddrSpace;
222224
ManglingMode = DL.ManglingMode;
223225
LegalIntWidths = DL.LegalIntWidths;
224226
Alignments = DL.Alignments;
@@ -295,6 +297,9 @@ class DataLayout {
295297
}
296298

297299
unsigned getProgramAddressSpace() const { return ProgramAddrSpace; }
300+
unsigned getDefaultGlobalsAddressSpace() const {
301+
return DefaultGlobalsAddrSpace;
302+
}
298303

299304
bool hasMicrosoftFastStdCallMangling() const {
300305
return ManglingMode == MM_WinCOFFX86;

llvm/include/llvm/IR/GlobalVariable.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
5656
bool isExternallyInitialized = false);
5757
/// GlobalVariable ctor - This creates a global and inserts it before the
5858
/// specified other global.
59-
GlobalVariable(Module &M, Type *Ty, bool isConstant,
60-
LinkageTypes Linkage, Constant *Initializer,
61-
const Twine &Name = "", GlobalVariable *InsertBefore = nullptr,
62-
ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
59+
GlobalVariable(Module &M, Type *Ty, bool isConstant, LinkageTypes Linkage,
60+
Constant *Initializer, const Twine &Name = "",
61+
GlobalVariable *InsertBefore = nullptr,
62+
ThreadLocalMode = NotThreadLocal,
63+
Optional<unsigned> AddressSpace = None,
6364
bool isExternallyInitialized = false);
6465
GlobalVariable(const GlobalVariable &) = delete;
6566
GlobalVariable &operator=(const GlobalVariable &) = delete;

llvm/lib/IR/DataLayout.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ void DataLayout::reset(StringRef Desc) {
182182
AllocaAddrSpace = 0;
183183
StackNaturalAlign.reset();
184184
ProgramAddrSpace = 0;
185+
DefaultGlobalsAddrSpace = 0;
185186
FunctionPtrAlign.reset();
186187
TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
187188
ManglingMode = MM_None;
@@ -479,6 +480,11 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
479480
return Err;
480481
break;
481482
}
483+
case 'G': { // Default address space for global variables.
484+
if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace))
485+
return Err;
486+
break;
487+
}
482488
case 'm':
483489
if (!Tok.empty())
484490
return reportError("Unexpected trailing characters after mangling "
@@ -530,6 +536,7 @@ bool DataLayout::operator==(const DataLayout &Other) const {
530536
AllocaAddrSpace == Other.AllocaAddrSpace &&
531537
StackNaturalAlign == Other.StackNaturalAlign &&
532538
ProgramAddrSpace == Other.ProgramAddrSpace &&
539+
DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
533540
FunctionPtrAlign == Other.FunctionPtrAlign &&
534541
TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType &&
535542
ManglingMode == Other.ManglingMode &&

llvm/lib/IR/Globals.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,11 +352,15 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
352352
GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
353353
LinkageTypes Link, Constant *InitVal,
354354
const Twine &Name, GlobalVariable *Before,
355-
ThreadLocalMode TLMode, unsigned AddressSpace,
355+
ThreadLocalMode TLMode,
356+
Optional<unsigned> AddressSpace,
356357
bool isExternallyInitialized)
357358
: GlobalObject(Ty, Value::GlobalVariableVal,
358359
OperandTraits<GlobalVariable>::op_begin(this),
359-
InitVal != nullptr, Link, Name, AddressSpace),
360+
InitVal != nullptr, Link, Name,
361+
AddressSpace
362+
? *AddressSpace
363+
: M.getDataLayout().getDefaultGlobalsAddressSpace()),
360364
isConstantGlobal(constant),
361365
isExternallyInitializedConstant(isExternallyInitialized) {
362366
assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) &&
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
; RUN: not --crash llvm-as < %s 2>&1 | FileCheck %s
2+
3+
; CHECK: Invalid address space, must be a 24-bit integer
4+
target datalayout = "G16777216"

llvm/unittests/IR/DataLayoutTest.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/IR/DataLayout.h"
10+
#include "llvm/IR/GlobalVariable.h"
1011
#include "llvm/IR/LLVMContext.h"
12+
#include "llvm/IR/Module.h"
1113
#include "llvm/IR/Type.h"
1214
#include "gtest/gtest.h"
1315

@@ -56,4 +58,35 @@ TEST(DataLayoutTest, ValueOrABITypeAlignment) {
5658
DL.getValueOrABITypeAlignment(MaybeAlign(), FourByteAlignType));
5759
}
5860

59-
} // anonymous namespace
61+
TEST(DataLayoutTest, GlobalsAddressSpace) {
62+
// When not explicitly defined the globals address space should be zero:
63+
EXPECT_EQ(DataLayout("").getDefaultGlobalsAddressSpace(), 0u);
64+
EXPECT_EQ(DataLayout("P1-A2").getDefaultGlobalsAddressSpace(), 0u);
65+
EXPECT_EQ(DataLayout("G2").getDefaultGlobalsAddressSpace(), 2u);
66+
// Check that creating a GlobalVariable without an explicit address space
67+
// in a module with a default globals address space respects that default:
68+
LLVMContext Context;
69+
std::unique_ptr<Module> M(new Module("MyModule", Context));
70+
// Default is globals in address space zero:
71+
auto *Int32 = Type::getInt32Ty(Context);
72+
auto *DefaultGlobal1 = new GlobalVariable(
73+
*M, Int32, false, GlobalValue::ExternalLinkage, nullptr);
74+
EXPECT_EQ(DefaultGlobal1->getAddressSpace(), 0u);
75+
auto *ExplicitGlobal1 = new GlobalVariable(
76+
*M, Int32, false, GlobalValue::ExternalLinkage, nullptr, "", nullptr,
77+
GlobalValue::NotThreadLocal, 123);
78+
EXPECT_EQ(ExplicitGlobal1->getAddressSpace(), 123u);
79+
80+
// When using a datalayout with the global address space set to 200, global
81+
// variables should default to 200
82+
M->setDataLayout("G200");
83+
auto *DefaultGlobal2 = new GlobalVariable(
84+
*M, Int32, false, GlobalValue::ExternalLinkage, nullptr);
85+
EXPECT_EQ(DefaultGlobal2->getAddressSpace(), 200u);
86+
auto *ExplicitGlobal2 = new GlobalVariable(
87+
*M, Int32, false, GlobalValue::ExternalLinkage, nullptr, "", nullptr,
88+
GlobalValue::NotThreadLocal, 123);
89+
EXPECT_EQ(ExplicitGlobal2->getAddressSpace(), 123u);
90+
}
91+
92+
} // anonymous namespace

0 commit comments

Comments
 (0)