diff options
| author | Christopher Lamb <christopher.lamb@gmail.com> | 2007-12-11 08:59:05 +0000 |
|---|---|---|
| committer | Christopher Lamb <christopher.lamb@gmail.com> | 2007-12-11 08:59:05 +0000 |
| commit | 54dd24c2a723be37f032567bfc41a4b4307bd4a0 (patch) | |
| tree | 71609a83b2d8f992701ce17da00735dab7065794 /llvm/lib/VMCore | |
| parent | 8975f49065992ea2da7e5bdc117befc12615be58 (diff) | |
| download | bcm5719-llvm-54dd24c2a723be37f032567bfc41a4b4307bd4a0.tar.gz bcm5719-llvm-54dd24c2a723be37f032567bfc41a4b4307bd4a0.zip | |
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.
llvm-svn: 44858
Diffstat (limited to 'llvm/lib/VMCore')
| -rw-r--r-- | llvm/lib/VMCore/AsmWriter.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Constants.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Globals.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Instructions.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Type.cpp | 31 |
5 files changed, 42 insertions, 19 deletions
diff --git a/llvm/lib/VMCore/AsmWriter.cpp b/llvm/lib/VMCore/AsmWriter.cpp index 008c1daee19..e35b14fbc1a 100644 --- a/llvm/lib/VMCore/AsmWriter.cpp +++ b/llvm/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/llvm/lib/VMCore/Constants.cpp b/llvm/lib/VMCore/Constants.cpp index 49c27b82ccd..964d8880e87 100644 --- a/llvm/lib/VMCore/Constants.cpp +++ b/llvm/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/llvm/lib/VMCore/Globals.cpp b/llvm/lib/VMCore/Globals.cpp index eb0df60757b..0155915146a 100644 --- a/llvm/lib/VMCore/Globals.cpp +++ b/llvm/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/llvm/lib/VMCore/Instructions.cpp b/llvm/lib/VMCore/Instructions.cpp index 0df0466112b..5207ea52f49 100644 --- a/llvm/lib/VMCore/Instructions.cpp +++ b/llvm/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/llvm/lib/VMCore/Type.cpp b/llvm/lib/VMCore/Type.cpp index 1e584770420..62de6f4fa57 100644 --- a/llvm/lib/VMCore/Type.cpp +++ b/llvm/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"; |

