From fe63fb986dc9510c5d68f2442edab9574e9e50d0 Mon Sep 17 00:00:00 2001 From: Christopher Lamb Date: Tue, 11 Dec 2007 08:59:05 +0000 Subject: Implement address space attribute for LLVM pointer types. Address spaces are regions of memory that have a target specific relationship, as described in the Embedded C Technical Report. This also implements the 2007-12-11-AddressSpaces test, which demonstrates how address space attributes can be used in LLVM IR. In addition, this patch changes the bitcode signature for stores (in a backwards compatible manner), such that the pointer type, rather than the pointee type, is encoded. This permits type information in the pointer (e.g. address space) to be preserved for stores. LangRef updates are forthcoming. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44858 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 28 ++++++++++++++++++++++++---- lib/Bitcode/Writer/BitcodeWriter.cpp | 16 ++++++++++------ 2 files changed, 34 insertions(+), 10 deletions(-) (limited to 'lib/Bitcode') 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(Ty)) return Error("Global not a pointer type!"); + unsigned AddressSpace = cast(Ty)->getAddressSpace(); Ty = cast(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(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(T)->getBitWidth()); break; case Type::PointerTyID: - // POINTER: [pointee type] + const PointerType *PTy = cast(T); + // POINTER: [pointee type] or [pointee type, address space] Code = bitc::TYPE_CODE_POINTER; - TypeVals.push_back(VE.getTypeID(cast(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(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(I).getAlignment())+1); Vals.push_back(cast(I).isVolatile()); break; -- cgit v1.2.3-18-g5258