summaryrefslogtreecommitdiffstats
path: root/llvm/lib/AsmParser
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2017-04-10 22:27:50 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2017-04-10 22:27:50 +0000
commit3c1fc768ed6cf2b01463df036ae6ae3b1f0de632 (patch)
tree7893b430cd0be51c8e7e2db97e49415820615c83 /llvm/lib/AsmParser
parentd78bd57b3f24ba97c2b0112d2cf6b5a6896fd67d (diff)
downloadbcm5719-llvm-3c1fc768ed6cf2b01463df036ae6ae3b1f0de632.tar.gz
bcm5719-llvm-3c1fc768ed6cf2b01463df036ae6ae3b1f0de632.zip
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
Diffstat (limited to 'llvm/lib/AsmParser')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp53
-rw-r--r--llvm/lib/AsmParser/LLParser.h2
2 files changed, 51 insertions, 4 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d8f6c1c5146..941ee347a78 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1852,6 +1852,34 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
return false;
}
+/// ParseOptionalCommaAddrSpace
+/// ::=
+/// ::= ',' addrspace(1)
+///
+/// This returns with AteExtraComma set to true if it ate an excess comma at the
+/// end.
+bool LLParser::ParseOptionalCommaAddrSpace(unsigned &AddrSpace,
+ LocTy &Loc,
+ bool &AteExtraComma) {
+ AteExtraComma = false;
+ while (EatIfPresent(lltok::comma)) {
+ // Metadata at the end is an early exit.
+ if (Lex.getKind() == lltok::MetadataVar) {
+ AteExtraComma = true;
+ return false;
+ }
+
+ Loc = Lex.getLoc();
+ if (Lex.getKind() != lltok::kw_addrspace)
+ return Error(Lex.getLoc(), "expected metadata or 'addrspace'");
+
+ if (ParseOptionalAddrSpace(AddrSpace))
+ return true;
+ }
+
+ return false;
+}
+
bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg,
Optional<unsigned> &HowManyArg) {
Lex.Lex();
@@ -6033,8 +6061,9 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
/// (',' 'align' i32)?
int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
Value *Size = nullptr;
- LocTy SizeLoc, TyLoc;
+ LocTy SizeLoc, TyLoc, ASLoc;
unsigned Alignment = 0;
+ unsigned AddrSpace = 0;
Type *Ty = nullptr;
bool IsInAlloca = EatIfPresent(lltok::kw_inalloca);
@@ -6048,12 +6077,21 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
bool AteExtraComma = false;
if (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::kw_align) {
- if (ParseOptionalAlignment(Alignment)) return true;
+ if (ParseOptionalAlignment(Alignment))
+ return true;
+ if (ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
+ return true;
+ } else if (Lex.getKind() == lltok::kw_addrspace) {
+ ASLoc = Lex.getLoc();
+ if (ParseOptionalAddrSpace(AddrSpace))
+ return true;
} else if (Lex.getKind() == lltok::MetadataVar) {
AteExtraComma = true;
} else {
if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
- ParseOptionalCommaAlign(Alignment, AteExtraComma))
+ ParseOptionalCommaAlign(Alignment, AteExtraComma) ||
+ (!AteExtraComma &&
+ ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma)))
return true;
}
}
@@ -6061,7 +6099,14 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
if (Size && !Size->getType()->isIntegerTy())
return Error(SizeLoc, "element count must have integer type");
- AllocaInst *AI = new AllocaInst(Ty, Size, Alignment);
+ const DataLayout &DL = M->getDataLayout();
+ unsigned AS = DL.getAllocaAddrSpace();
+ if (AS != AddrSpace) {
+ // TODO: In the future it should be possible to specify addrspace per-alloca.
+ return Error(ASLoc, "address space must match datalayout");
+ }
+
+ AllocaInst *AI = new AllocaInst(Ty, AS, Size, Alignment);
AI->setUsedWithInAlloca(IsInAlloca);
AI->setSwiftError(IsSwiftError);
Inst = AI;
diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h
index 3a794142172..5293bda1b70 100644
--- a/llvm/lib/AsmParser/LLParser.h
+++ b/llvm/lib/AsmParser/LLParser.h
@@ -246,6 +246,8 @@ namespace llvm {
bool ParseOrdering(AtomicOrdering &Ordering);
bool ParseOptionalStackAlignment(unsigned &Alignment);
bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma);
+ bool ParseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc,
+ bool &AteExtraComma);
bool ParseOptionalCommaInAlloca(bool &IsInAlloca);
bool parseAllocSizeArguments(unsigned &ElemSizeArg,
Optional<unsigned> &HowManyArg);
OpenPOWER on IntegriCloud