aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/llvmAsmParser.y31
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp28
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp16
-rw-r--r--lib/VMCore/AsmWriter.cpp11
-rw-r--r--lib/VMCore/Constants.cpp3
-rw-r--r--lib/VMCore/Globals.cpp10
-rw-r--r--lib/VMCore/Instructions.cpp6
-rw-r--r--lib/VMCore/Type.cpp31
9 files changed, 103 insertions, 34 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index ef8d27c8a3..750529451a 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -463,6 +463,7 @@ int LLLexer::LexIdentifier() {
KEYWORD("datalayout", DATALAYOUT);
KEYWORD("volatile", VOLATILE);
KEYWORD("align", ALIGN);
+ KEYWORD("addrspace", ADDRSPACE);
KEYWORD("section", SECTION);
KEYWORD("alias", ALIAS);
KEYWORD("module", MODULE);
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 57b6f81d8f..cd3a7edb50 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -491,7 +491,8 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
if (const FunctionType *FTy = dyn_cast<FunctionType>(ElTy))
V = new Function(FTy, GlobalValue::ExternalLinkage);
else
- V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage);
+ V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage, 0, "",
+ (Module*)0, false, PTy->getAddressSpace());
break;
}
default:
@@ -722,13 +723,14 @@ ParseGlobalVariable(std::string *NameStr,
GlobalValue::LinkageTypes Linkage,
GlobalValue::VisibilityTypes Visibility,
bool isConstantGlobal, const Type *Ty,
- Constant *Initializer, bool IsThreadLocal) {
+ Constant *Initializer, bool IsThreadLocal,
+ unsigned AddressSpace = 0) {
if (isa<FunctionType>(Ty)) {
GenerateError("Cannot declare global vars of function type");
return 0;
}
- const PointerType *PTy = PointerType::get(Ty);
+ const PointerType *PTy = PointerType::get(Ty, AddressSpace);
std::string Name;
if (NameStr) {
@@ -780,7 +782,7 @@ ParseGlobalVariable(std::string *NameStr,
// Otherwise there is no existing GV to use, create one now.
GlobalVariable *GV =
new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
- CurModule.CurrentModule, IsThreadLocal);
+ CurModule.CurrentModule, IsThreadLocal, AddressSpace);
GV->setVisibility(Visibility);
InsertValue(GV, CurModule.Values);
return GV;
@@ -1054,7 +1056,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
%token DECLARE DEFINE GLOBAL CONSTANT SECTION ALIAS VOLATILE THREAD_LOCAL
%token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING
%token DLLIMPORT DLLEXPORT EXTERN_WEAK
-%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN
+%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE
%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
%token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
%token DATALAYOUT
@@ -1268,6 +1270,7 @@ OptCAlign : /*empty*/ { $$ = 0; } |
};
+
SectionString : SECTION STRINGCONSTANT {
for (unsigned i = 0, e = $2->length(); i != e; ++i)
if ((*$2)[i] == '"' || (*$2)[i] == '\\')
@@ -1320,6 +1323,13 @@ Types
delete $1;
CHECK_FOR_ERROR
}
+ | Types ADDRSPACE '(' EUINT64VAL ')' '*' { // Pointer type?
+ if (*$1 == Type::LabelTy)
+ GEN_ERROR("Cannot form a pointer to a basic block");
+ $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1, $4)));
+ delete $1;
+ CHECK_FOR_ERROR
+ }
| SymbolicValueRef { // Named types are also simple types...
const Type* tmp = getTypeVal($1);
CHECK_FOR_ERROR
@@ -2073,6 +2083,17 @@ Definition
} GlobalVarAttributes {
CurGV = 0;
}
+ | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal
+ ADDRSPACE '(' EUINT64VAL ')' {
+ /* "Externally Visible" Linkage with address space qualifier */
+ if ($5 == 0)
+ GEN_ERROR("Global value initializer is not a constant");
+ CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
+ $2, $4, $5->getType(), $5, $3, $8);
+ CHECK_FOR_ERROR
+ } GlobalVarAttributes {
+ CurGV = 0;
+ }
| OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType
ConstVal {
if ($6 == 0)
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index fd3ec9e698..72756ef6cd 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -323,11 +323,16 @@ bool BitcodeReader::ParseTypeTable() {
ResultTy = IntegerType::get(Record[0]);
break;
- case bitc::TYPE_CODE_POINTER: // POINTER: [pointee type]
+ case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
+ // [pointee type, address space]
if (Record.size() < 1)
return Error("Invalid POINTER type record");
- ResultTy = PointerType::get(getTypeByID(Record[0], true));
+ unsigned AddressSpace = 0;
+ if (Record.size() == 2)
+ AddressSpace = Record[1];
+ ResultTy = PointerType::get(getTypeByID(Record[0], true), AddressSpace);
break;
+ }
case bitc::TYPE_CODE_FUNCTION: {
// FIXME: attrid is dead, remove it in LLVM 3.0
// FUNCTION: [vararg, attrid, retty, paramty x N]
@@ -982,7 +987,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
CollectorTable.push_back(S);
break;
}
- // GLOBALVAR: [type, isconst, initid,
+ // GLOBALVAR: [pointer type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal]
case bitc::MODULE_CODE_GLOBALVAR: {
if (Record.size() < 6)
@@ -990,6 +995,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
const Type *Ty = getTypeByID(Record[0]);
if (!isa<PointerType>(Ty))
return Error("Global not a pointer type!");
+ unsigned AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
Ty = cast<PointerType>(Ty)->getElementType();
bool isConstant = Record[1];
@@ -1009,7 +1015,8 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
isThreadLocal = Record[7];
GlobalVariable *NewGV =
- new GlobalVariable(Ty, isConstant, Linkage, 0, "", TheModule);
+ new GlobalVariable(Ty, isConstant, Linkage, 0, "", TheModule,
+ isThreadLocal, AddressSpace);
NewGV->setAlignment(Alignment);
if (!Section.empty())
NewGV->setSection(Section);
@@ -1485,7 +1492,20 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
break;
}
+ case bitc::FUNC_CODE_INST_STORE2: { // STORE2:[ptrty, ptr, val, align, vol]
+ unsigned OpNum = 0;
+ Value *Val, *Ptr;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
+ getValue(Record, OpNum,
+ cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
+ OpNum+2 != Record.size())
+ return Error("Invalid STORE record");
+
+ I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+ break;
+ }
case bitc::FUNC_CODE_INST_STORE: { // STORE:[val, valty, ptr, align, vol]
+ // FIXME: Legacy form of store instruction. Should be removed in LLVM 3.0.
unsigned OpNum = 0;
Value *Val, *Ptr;
if (getValueTypePair(Record, OpNum, NextValueNo, Val) ||
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 612d89338b..c58d23ada2 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -197,10 +197,14 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
TypeVals.push_back(cast<IntegerType>(T)->getBitWidth());
break;
case Type::PointerTyID:
- // POINTER: [pointee type]
+ const PointerType *PTy = cast<PointerType>(T);
+ // POINTER: [pointee type] or [pointee type, address space]
Code = bitc::TYPE_CODE_POINTER;
- TypeVals.push_back(VE.getTypeID(cast<PointerType>(T)->getElementType()));
- AbbrevToUse = PtrAbbrev;
+ TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
+ if (unsigned AddressSpace = PTy->getAddressSpace())
+ TypeVals.push_back(AddressSpace);
+ else
+ AbbrevToUse = PtrAbbrev;
break;
case Type::FunctionTyID: {
@@ -829,9 +833,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
Vals.push_back(cast<LoadInst>(I).isVolatile());
break;
case Instruction::Store:
- Code = bitc::FUNC_CODE_INST_STORE;
- PushValueAndType(I.getOperand(0), InstID, Vals, VE); // val.
- Vals.push_back(VE.getValueID(I.getOperand(1))); // ptr.
+ Code = bitc::FUNC_CODE_INST_STORE2;
+ PushValueAndType(I.getOperand(1), InstID, Vals, VE); // ptrty + ptr
+ Vals.push_back(VE.getValueID(I.getOperand(0))); // val.
Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1);
Vals.push_back(cast<StoreInst>(I).isVolatile());
break;
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 008c1daee1..e35b14fbc1 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -334,11 +334,15 @@ static void calcTypeName(const Type *Ty,
Result += '>';
break;
}
- case Type::PointerTyID:
- calcTypeName(cast<PointerType>(Ty)->getElementType(),
+ case Type::PointerTyID: {
+ const PointerType *PTy = cast<PointerType>(Ty);
+ calcTypeName(PTy->getElementType(),
TypeStack, TypeNames, Result);
+ if (unsigned AddressSpace = PTy->getAddressSpace())
+ Result += " addrspace(" + utostr(AddressSpace) + ")";
Result += "*";
break;
+ }
case Type::ArrayTyID: {
const ArrayType *ATy = cast<ArrayType>(Ty);
Result += "[" + utostr(ATy->getNumElements()) + " x ";
@@ -951,6 +955,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
writeOperand(GV->getInitializer(), false);
}
+ if (unsigned AddressSpace = GV->getType()->getAddressSpace())
+ Out << " addrspace(" << AddressSpace << ") ";
+
if (GV->hasSection())
Out << ", section \"" << GV->getSection() << '"';
if (GV->getAlignment())
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 49c27b82cc..964d8880e8 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -1860,7 +1860,8 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
const Type *Ty =
GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true);
assert(Ty && "GEP indices invalid!");
- return getGetElementPtrTy(PointerType::get(Ty), C, Idxs, NumIdx);
+ unsigned As = cast<PointerType>(C->getType())->getAddressSpace();
+ return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
}
Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp
index eb0df60757..0155915146 100644
--- a/lib/VMCore/Globals.cpp
+++ b/lib/VMCore/Globals.cpp
@@ -85,8 +85,9 @@ void GlobalValue::destroyConstant() {
GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
Constant *InitVal, const std::string &Name,
- Module *ParentModule, bool ThreadLocal)
- : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
+ Module *ParentModule, bool ThreadLocal,
+ unsigned AddressSpace)
+ : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
&Initializer, InitVal != 0, Link, Name),
isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
if (InitVal) {
@@ -105,8 +106,9 @@ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
Constant *InitVal, const std::string &Name,
- GlobalVariable *Before, bool ThreadLocal)
- : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
+ GlobalVariable *Before, bool ThreadLocal,
+ unsigned AddressSpace)
+ : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
&Initializer, InitVal != 0, Link, Name),
isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
if (InitVal) {
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 0df0466112..5207ea52f4 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -937,7 +937,8 @@ void GetElementPtrInst::init(Value *Ptr, Value *Idx) {
GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
const std::string &Name, Instruction *InBe)
- : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx))),
+ : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)),
+ cast<PointerType>(Ptr->getType())->getAddressSpace()),
GetElementPtr, 0, 0, InBe) {
init(Ptr, Idx);
setName(Name);
@@ -945,7 +946,8 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
const std::string &Name, BasicBlock *IAE)
- : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx))),
+ : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)),
+ cast<PointerType>(Ptr->getType())->getAddressSpace()),
GetElementPtr, 0, 0, IAE) {
init(Ptr, Idx);
setName(Name);
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 1e58477042..62de6f4fa5 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -338,7 +338,10 @@ static std::string getTypeDescription(const Type *Ty,
}
case Type::PointerTyID: {
const PointerType *PTy = cast<PointerType>(Ty);
- Result = getTypeDescription(PTy->getElementType(), TypeStack) + " *";
+ Result = getTypeDescription(PTy->getElementType(), TypeStack);
+ if (unsigned AddressSpace = PTy->getAddressSpace())
+ Result += " addrspace(" + utostr(AddressSpace) + ")";
+ Result += " *";
break;
}
case Type::ArrayTyID: {
@@ -492,7 +495,9 @@ VectorType::VectorType(const Type *ElType, unsigned NumEl)
}
-PointerType::PointerType(const Type *E) : SequentialType(PointerTyID, E) {
+PointerType::PointerType(const Type *E, unsigned AddrSpace)
+ : SequentialType(PointerTyID, E) {
+ AddressSpace = AddrSpace;
// Calculate whether or not this type is abstract
setAbstract(E->isAbstract());
}
@@ -634,8 +639,9 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
const IntegerType *ITy2 = cast<IntegerType>(Ty2);
return ITy->getBitWidth() == ITy2->getBitWidth();
} else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
- return TypesEqual(PTy->getElementType(),
- cast<PointerType>(Ty2)->getElementType(), EqTypes);
+ const PointerType *PTy2 = cast<PointerType>(Ty2);
+ return PTy->getAddressSpace() == PTy2->getAddressSpace() &&
+ TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes);
} else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
const StructType *STy2 = cast<StructType>(Ty2);
if (STy->getNumElements() != STy2->getNumElements()) return false;
@@ -756,6 +762,9 @@ static unsigned getSubElementHash(const Type *Ty) {
case Type::StructTyID:
HashVal ^= cast<StructType>(SubTy)->getNumElements();
break;
+ case Type::PointerTyID:
+ HashVal ^= cast<PointerType>(SubTy)->getAddressSpace();
+ break;
}
}
return HashVal ? HashVal : 1; // Do not return zero unless opaque subty.
@@ -1251,11 +1260,12 @@ StructType *StructType::get(const std::vector<const Type*> &ETypes,
namespace llvm {
class PointerValType {
const Type *ValTy;
+ unsigned AddressSpace;
public:
- PointerValType(const Type *val) : ValTy(val) {}
+ PointerValType(const Type *val, unsigned as) : ValTy(val), AddressSpace(as) {}
static PointerValType get(const PointerType *PT) {
- return PointerValType(PT->getElementType());
+ return PointerValType(PT->getElementType(), PT->getAddressSpace());
}
static unsigned hashTypeStructure(const PointerType *PT) {
@@ -1263,25 +1273,26 @@ public:
}
bool operator<(const PointerValType &MTV) const {
- return ValTy < MTV.ValTy;
+ if (AddressSpace < MTV.AddressSpace) return true;
+ return AddressSpace == MTV.AddressSpace && ValTy < MTV.ValTy;
}
};
}
static ManagedStatic<TypeMap<PointerValType, PointerType> > PointerTypes;
-PointerType *PointerType::get(const Type *ValueType) {
+PointerType *PointerType::get(const Type *ValueType, unsigned AddressSpace) {
assert(ValueType && "Can't get a pointer to <null> type!");
assert(ValueType != Type::VoidTy &&
"Pointer to void is not valid, use sbyte* instead!");
assert(ValueType != Type::LabelTy && "Pointer to label is not valid!");
- PointerValType PVT(ValueType);
+ PointerValType PVT(ValueType, AddressSpace);
PointerType *PT = PointerTypes->get(PVT);
if (PT) return PT;
// Value not found. Derive a new type!
- PointerTypes->add(PVT, PT = new PointerType(ValueType));
+ PointerTypes->add(PVT, PT = new PointerType(ValueType, AddressSpace));
#ifdef DEBUG_MERGE_TYPES
DOUT << "Derived new type: " << *PT << "\n";