Skip to content

Commit 3c1fc76

Browse files
committed
Allow DataLayout to specify addrspace for allocas.
LLVM makes several assumptions about address space 0. However, alloca is presently constrained to always return this address space. There's no real way to avoid using alloca, so without this there is no way to opt out of these assumptions. The problematic assumptions include: - That the pointer size used for the stack is the same size as the code size pointer, which is also the maximum sized pointer. - That 0 is an invalid, non-dereferencable pointer value. These are problems for AMDGPU because alloca is used to implement the private address space, which uses a 32-bit index as the pointer value. Other pointers are 64-bit and behave more like LLVM's notion of generic address space. By changing the address space used for allocas, we can change our generic pointer type to be LLVM's generic pointer type which does have similar properties. llvm-svn: 299888
1 parent d78bd57 commit 3c1fc76

34 files changed

+382
-72
lines changed

llvm/docs/LangRef.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,6 +1812,9 @@ as follows:
18121812
must be a multiple of 8-bits. If omitted, the natural stack
18131813
alignment defaults to "unspecified", which does not prevent any
18141814
alignment promotions.
1815+
``A<address space>``
1816+
Specifies the address space of objects created by '``alloca``'.
1817+
Defaults to the default address space of 0.
18151818
``p[n]:<size>:<abi>:<pref>``
18161819
This specifies the *size* of a pointer and its ``<abi>`` and
18171820
``<pref>``\erred alignments for address space ``n``. All sizes are in
@@ -7192,15 +7195,15 @@ Syntax:
71927195

71937196
::
71947197

7195-
<result> = alloca [inalloca] <type> [, <ty> <NumElements>] [, align <alignment>] ; yields type*:result
7198+
<result> = alloca [inalloca] <type> [, <ty> <NumElements>] [, align <alignment>] [, addrspace(<num>)] ; yields type addrspace(num)*:result
71967199

71977200
Overview:
71987201
"""""""""
71997202

72007203
The '``alloca``' instruction allocates memory on the stack frame of the
72017204
currently executing function, to be automatically released when this
72027205
function returns to its caller. The object is always allocated in the
7203-
default address space (address space zero).
7206+
address space for allocas indicated in the datalayout.
72047207

72057208
Arguments:
72067209
""""""""""

llvm/include/llvm/IR/DataLayout.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class DataLayout {
104104
/// Defaults to false.
105105
bool BigEndian;
106106

107+
unsigned AllocaAddrSpace;
107108
unsigned StackNaturalAlign;
108109

109110
enum ManglingModeT {
@@ -186,6 +187,7 @@ class DataLayout {
186187
clear();
187188
StringRepresentation = DL.StringRepresentation;
188189
BigEndian = DL.isBigEndian();
190+
AllocaAddrSpace = DL.AllocaAddrSpace;
189191
StackNaturalAlign = DL.StackNaturalAlign;
190192
ManglingMode = DL.ManglingMode;
191193
LegalIntWidths = DL.LegalIntWidths;
@@ -241,6 +243,7 @@ class DataLayout {
241243
}
242244

243245
unsigned getStackAlignment() const { return StackNaturalAlign; }
246+
unsigned getAllocaAddrSpace() const { return AllocaAddrSpace; }
244247

245248
bool hasMicrosoftFastStdCallMangling() const {
246249
return ManglingMode == MM_WinCOFFX86;

llvm/include/llvm/IR/IRBuilder.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "llvm/IR/Instructions.h"
3434
#include "llvm/IR/Intrinsics.h"
3535
#include "llvm/IR/LLVMContext.h"
36+
#include "llvm/IR/Module.h"
3637
#include "llvm/IR/Operator.h"
3738
#include "llvm/IR/Type.h"
3839
#include "llvm/IR/Value.h"
@@ -1089,9 +1090,15 @@ class IRBuilder : public IRBuilderBase, public Inserter {
10891090
// Instruction creation methods: Memory Instructions
10901091
//===--------------------------------------------------------------------===//
10911092

1093+
AllocaInst *CreateAlloca(Type *Ty, unsigned AddrSpace,
1094+
Value *ArraySize = nullptr, const Twine &Name = "") {
1095+
return Insert(new AllocaInst(Ty, AddrSpace, ArraySize), Name);
1096+
}
1097+
10921098
AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = nullptr,
10931099
const Twine &Name = "") {
1094-
return Insert(new AllocaInst(Ty, ArraySize), Name);
1100+
const DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
1101+
return Insert(new AllocaInst(Ty, DL.getAllocaAddrSpace(), ArraySize), Name);
10951102
}
10961103
// \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
10971104
// converting the string to 'bool' for the isVolatile parameter.

llvm/include/llvm/IR/Instructions.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,21 @@ class AllocaInst : public UnaryInstruction {
6767
AllocaInst *cloneImpl() const;
6868

6969
public:
70-
explicit AllocaInst(Type *Ty, Value *ArraySize = nullptr,
70+
explicit AllocaInst(Type *Ty, unsigned AddrSpace,
71+
Value *ArraySize = nullptr,
7172
const Twine &Name = "",
7273
Instruction *InsertBefore = nullptr);
73-
AllocaInst(Type *Ty, Value *ArraySize,
74+
AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize,
7475
const Twine &Name, BasicBlock *InsertAtEnd);
7576

76-
AllocaInst(Type *Ty, const Twine &Name, Instruction *InsertBefore = nullptr);
77-
AllocaInst(Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd);
77+
AllocaInst(Type *Ty, unsigned AddrSpace,
78+
const Twine &Name, Instruction *InsertBefore = nullptr);
79+
AllocaInst(Type *Ty, unsigned AddrSpace,
80+
const Twine &Name, BasicBlock *InsertAtEnd);
7881

79-
AllocaInst(Type *Ty, Value *ArraySize, unsigned Align,
82+
AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align,
8083
const Twine &Name = "", Instruction *InsertBefore = nullptr);
81-
AllocaInst(Type *Ty, Value *ArraySize, unsigned Align,
84+
AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align,
8285
const Twine &Name, BasicBlock *InsertAtEnd);
8386

8487
// Out of line virtual method, so the vtable, etc. has a home.

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,6 +1852,34 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
18521852
return false;
18531853
}
18541854

1855+
/// ParseOptionalCommaAddrSpace
1856+
/// ::=
1857+
/// ::= ',' addrspace(1)
1858+
///
1859+
/// This returns with AteExtraComma set to true if it ate an excess comma at the
1860+
/// end.
1861+
bool LLParser::ParseOptionalCommaAddrSpace(unsigned &AddrSpace,
1862+
LocTy &Loc,
1863+
bool &AteExtraComma) {
1864+
AteExtraComma = false;
1865+
while (EatIfPresent(lltok::comma)) {
1866+
// Metadata at the end is an early exit.
1867+
if (Lex.getKind() == lltok::MetadataVar) {
1868+
AteExtraComma = true;
1869+
return false;
1870+
}
1871+
1872+
Loc = Lex.getLoc();
1873+
if (Lex.getKind() != lltok::kw_addrspace)
1874+
return Error(Lex.getLoc(), "expected metadata or 'addrspace'");
1875+
1876+
if (ParseOptionalAddrSpace(AddrSpace))
1877+
return true;
1878+
}
1879+
1880+
return false;
1881+
}
1882+
18551883
bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg,
18561884
Optional<unsigned> &HowManyArg) {
18571885
Lex.Lex();
@@ -6033,8 +6061,9 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
60336061
/// (',' 'align' i32)?
60346062
int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
60356063
Value *Size = nullptr;
6036-
LocTy SizeLoc, TyLoc;
6064+
LocTy SizeLoc, TyLoc, ASLoc;
60376065
unsigned Alignment = 0;
6066+
unsigned AddrSpace = 0;
60386067
Type *Ty = nullptr;
60396068

60406069
bool IsInAlloca = EatIfPresent(lltok::kw_inalloca);
@@ -6048,20 +6077,36 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
60486077
bool AteExtraComma = false;
60496078
if (EatIfPresent(lltok::comma)) {
60506079
if (Lex.getKind() == lltok::kw_align) {
6051-
if (ParseOptionalAlignment(Alignment)) return true;
6080+
if (ParseOptionalAlignment(Alignment))
6081+
return true;
6082+
if (ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
6083+
return true;
6084+
} else if (Lex.getKind() == lltok::kw_addrspace) {
6085+
ASLoc = Lex.getLoc();
6086+
if (ParseOptionalAddrSpace(AddrSpace))
6087+
return true;
60526088
} else if (Lex.getKind() == lltok::MetadataVar) {
60536089
AteExtraComma = true;
60546090
} else {
60556091
if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
6056-
ParseOptionalCommaAlign(Alignment, AteExtraComma))
6092+
ParseOptionalCommaAlign(Alignment, AteExtraComma) ||
6093+
(!AteExtraComma &&
6094+
ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma)))
60576095
return true;
60586096
}
60596097
}
60606098

60616099
if (Size && !Size->getType()->isIntegerTy())
60626100
return Error(SizeLoc, "element count must have integer type");
60636101

6064-
AllocaInst *AI = new AllocaInst(Ty, Size, Alignment);
6102+
const DataLayout &DL = M->getDataLayout();
6103+
unsigned AS = DL.getAllocaAddrSpace();
6104+
if (AS != AddrSpace) {
6105+
// TODO: In the future it should be possible to specify addrspace per-alloca.
6106+
return Error(ASLoc, "address space must match datalayout");
6107+
}
6108+
6109+
AllocaInst *AI = new AllocaInst(Ty, AS, Size, Alignment);
60656110
AI->setUsedWithInAlloca(IsInAlloca);
60666111
AI->setSwiftError(IsSwiftError);
60676112
Inst = AI;

llvm/lib/AsmParser/LLParser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ namespace llvm {
246246
bool ParseOrdering(AtomicOrdering &Ordering);
247247
bool ParseOptionalStackAlignment(unsigned &Alignment);
248248
bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma);
249+
bool ParseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc,
250+
bool &AteExtraComma);
249251
bool ParseOptionalCommaInAlloca(bool &IsInAlloca);
250252
bool parseAllocSizeArguments(unsigned &ElemSizeArg,
251253
Optional<unsigned> &HowManyArg);

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4006,7 +4006,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
40064006
}
40074007
if (!Ty || !Size)
40084008
return error("Invalid record");
4009-
AllocaInst *AI = new AllocaInst(Ty, Size, Align);
4009+
4010+
// FIXME: Make this an optional field.
4011+
const DataLayout &DL = TheModule->getDataLayout();
4012+
unsigned AS = DL.getAllocaAddrSpace();
4013+
4014+
AllocaInst *AI = new AllocaInst(Ty, AS, Size, Align);
40104015
AI->setUsedWithInAlloca(InAlloca);
40114016
AI->setSwiftError(SwiftError);
40124017
I = AI;

llvm/lib/CodeGen/SjLjEHPrepare.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ Value *SjLjEHPrepare::setupFunctionContext(Function &F,
175175
// because the value needs to be added to the global context list.
176176
auto &DL = F.getParent()->getDataLayout();
177177
unsigned Align = DL.getPrefTypeAlignment(FunctionContextTy);
178-
FuncCtx = new AllocaInst(FunctionContextTy, nullptr, Align, "fn_context",
179-
&EntryBB->front());
178+
FuncCtx = new AllocaInst(FunctionContextTy, DL.getAllocaAddrSpace(),
179+
nullptr, Align, "fn_context", &EntryBB->front());
180180

181181
// Fill in the function context structure.
182182
for (LandingPadInst *LPI : LPads) {

llvm/lib/CodeGen/WinEHPrepare.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class WinEHPrepare : public FunctionPass {
8686
// All fields are reset by runOnFunction.
8787
EHPersonality Personality = EHPersonality::Unknown;
8888

89+
const DataLayout *DL = nullptr;
8990
DenseMap<BasicBlock *, ColorVector> BlockColors;
9091
MapVector<BasicBlock *, std::vector<BasicBlock *>> FuncletBlocks;
9192
};
@@ -111,6 +112,7 @@ bool WinEHPrepare::runOnFunction(Function &Fn) {
111112
if (!isFuncletEHPersonality(Personality))
112113
return false;
113114

115+
DL = &Fn.getParent()->getDataLayout();
114116
return prepareExplicitEH(Fn);
115117
}
116118

@@ -1070,7 +1072,7 @@ AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
10701072
if (!isa<TerminatorInst>(EHPad)) {
10711073
// If the EHPad isn't a terminator, then we can insert a load in this block
10721074
// that will dominate all uses.
1073-
SpillSlot = new AllocaInst(PN->getType(), nullptr,
1075+
SpillSlot = new AllocaInst(PN->getType(), DL->getAllocaAddrSpace(), nullptr,
10741076
Twine(PN->getName(), ".wineh.spillslot"),
10751077
&F.getEntryBlock().front());
10761078
Value *V = new LoadInst(SpillSlot, Twine(PN->getName(), ".wineh.reload"),
@@ -1157,7 +1159,7 @@ void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
11571159
Function &F) {
11581160
// Lazilly create the spill slot.
11591161
if (!SpillSlot)
1160-
SpillSlot = new AllocaInst(V->getType(), nullptr,
1162+
SpillSlot = new AllocaInst(V->getType(), DL->getAllocaAddrSpace(), nullptr,
11611163
Twine(V->getName(), ".wineh.spillslot"),
11621164
&F.getEntryBlock().front());
11631165

llvm/lib/IR/AsmWriter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3117,6 +3117,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
31173117
if (AI->getAlignment()) {
31183118
Out << ", align " << AI->getAlignment();
31193119
}
3120+
3121+
unsigned AddrSpace = AI->getType()->getAddressSpace();
3122+
if (AddrSpace != 0) {
3123+
Out << ", addrspace(" << AddrSpace << ')';
3124+
}
3125+
31203126
} else if (isa<CastInst>(I)) {
31213127
if (Operand) {
31223128
Out << ' ';

0 commit comments

Comments
 (0)