diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 31 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 28 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 16 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 11 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 3 | ||||
-rw-r--r-- | lib/VMCore/Globals.cpp | 10 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 6 | ||||
-rw-r--r-- | lib/VMCore/Type.cpp | 31 |
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"; |