llvm.org GIT mirror llvm / fe63fb9
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 Christopher Lamb 11 years ago
15 changed file(s) with 152 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
4545 MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N]
4646 MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N]
4747
48 // GLOBALVAR: [type, isconst, initid,
48 // GLOBALVAR: [pointer type, isconst, initid,
4949 // linkage, alignment, section, visibility, threadlocal]
5050 MODULE_CODE_GLOBALVAR = 7,
5151
193193 FUNC_CODE_INST_FREE = 18, // FREE: [opty, op]
194194 FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align]
195195 FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol]
196 FUNC_CODE_INST_STORE = 21, // STORE: [ptrty,val,ptr, align, vol]
196 FUNC_CODE_INST_STORE = 21, // STORE: [valty,val,ptr, align, vol]
197197 FUNC_CODE_INST_CALL = 22, // CALL: [attr, fnty, fnid, args...]
198 FUNC_CODE_INST_VAARG = 23 // VAARG: [valistty, valist, instty]
198 FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty]
199 // This store code encodes the pointer type, rather than the value type
200 // this is so information only available in the pointer type (e.g. address
201 // spaces) is retained.
202 FUNC_CODE_INST_STORE2 = 24 // STORE: [ptrty,ptr,val, align, vol]
199203 };
200204 } // End bitc namespace
201205 } // End llvm namespace
362362 ///
363363 class PointerType : public SequentialType {
364364 friend class TypeMap;
365 unsigned AddressSpace;
366
365367 PointerType(const PointerType &); // Do not implement
366368 const PointerType &operator=(const PointerType &); // Do not implement
367 explicit PointerType(const Type *ElType);
369 explicit PointerType(const Type *ElType, unsigned AddrSpace);
368370 public:
369371 /// PointerType::get - This is the only way to construct a new pointer type.
370 static PointerType *get(const Type *ElementType);
372 static PointerType *get(const Type *ElementType, unsigned AddressSpace = 0);
373
374 /// @brief Return the address space of the Pointer type.
375 inline unsigned getAddressSpace() const { return AddressSpace; }
371376
372377 // Implement the AbstractTypeUser interface.
373378 virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
4949 /// automatically inserted into the end of the specified modules global list.
5050 GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage,
5151 Constant *Initializer = 0, const std::string &Name = "",
52 Module *Parent = 0, bool ThreadLocal = false);
52 Module *Parent = 0, bool ThreadLocal = false,
53 unsigned AddressSpace = 0);
5354 /// GlobalVariable ctor - This creates a global and inserts it before the
5455 /// specified other global.
5556 GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage,
5657 Constant *Initializer, const std::string &Name,
57 GlobalVariable *InsertBefore, bool ThreadLocal = false);
58 GlobalVariable *InsertBefore, bool ThreadLocal = false,
59 unsigned AddressSpace = 0);
5860
5961 /// isDeclaration - Is this global variable lacking an initializer? If so,
6062 /// the global variable is defined in some other translation unit, and is thus
454454 Instruction *InsertBefore =0)
455455 : Instruction(PointerType::get(
456456 checkType(getIndexedType(Ptr->getType(),
457 IdxBegin, IdxEnd, true))),
457 IdxBegin, IdxEnd, true)),
458 cast(Ptr->getType())->getAddressSpace()),
458459 GetElementPtr, 0, 0, InsertBefore) {
459460 init(Ptr, IdxBegin, IdxEnd, Name,
460461 typename std::iterator_traits::iterator_category());
464465 const std::string &Name, BasicBlock *InsertAtEnd)
465466 : Instruction(PointerType::get(
466467 checkType(getIndexedType(Ptr->getType(),
467 IdxBegin, IdxEnd, true))),
468 IdxBegin, IdxEnd, true)),
469 cast(Ptr->getType())->getAddressSpace()),
468470 GetElementPtr, 0, 0, InsertAtEnd) {
469471 init(Ptr, IdxBegin, IdxEnd, Name,
470472 typename std::iterator_traits::iterator_category());
462462 KEYWORD("datalayout", DATALAYOUT);
463463 KEYWORD("volatile", VOLATILE);
464464 KEYWORD("align", ALIGN);
465 KEYWORD("addrspace", ADDRSPACE);
465466 KEYWORD("section", SECTION);
466467 KEYWORD("alias", ALIAS);
467468 KEYWORD("module", MODULE);
490490 if (const FunctionType *FTy = dyn_cast(ElTy))
491491 V = new Function(FTy, GlobalValue::ExternalLinkage);
492492 else
493 V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage);
493 V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage, 0, "",
494 (Module*)0, false, PTy->getAddressSpace());
494495 break;
495496 }
496497 default:
721722 GlobalValue::LinkageTypes Linkage,
722723 GlobalValue::VisibilityTypes Visibility,
723724 bool isConstantGlobal, const Type *Ty,
724 Constant *Initializer, bool IsThreadLocal) {
725 Constant *Initializer, bool IsThreadLocal,
726 unsigned AddressSpace = 0) {
725727 if (isa(Ty)) {
726728 GenerateError("Cannot declare global vars of function type");
727729 return 0;
728730 }
729731
730 const PointerType *PTy = PointerType::get(Ty);
732 const PointerType *PTy = PointerType::get(Ty, AddressSpace);
731733
732734 std::string Name;
733735 if (NameStr) {
779781 // Otherwise there is no existing GV to use, create one now.
780782 GlobalVariable *GV =
781783 new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
782 CurModule.CurrentModule, IsThreadLocal);
784 CurModule.CurrentModule, IsThreadLocal, AddressSpace);
783785 GV->setVisibility(Visibility);
784786 InsertValue(GV, CurModule.Values);
785787 return GV;
10531055 %token DECLARE DEFINE GLOBAL CONSTANT SECTION ALIAS VOLATILE THREAD_LOCAL
10541056 %token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING
10551057 %token DLLIMPORT DLLEXPORT EXTERN_WEAK
1056 %token OPAQUE EXTERNAL TARGET TRIPLE ALIGN
1058 %token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE
10571059 %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
10581060 %token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
10591061 %token DATALAYOUT
12671269 };
12681270
12691271
1272
12701273 SectionString : SECTION STRINGCONSTANT {
12711274 for (unsigned i = 0, e = $2->length(); i != e; ++i)
12721275 if ((*$2)[i] == '"' || (*$2)[i] == '\\')
13161319 if (*$1 == Type::LabelTy)
13171320 GEN_ERROR("Cannot form a pointer to a basic block");
13181321 $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1)));
1322 delete $1;
1323 CHECK_FOR_ERROR
1324 }
1325 | Types ADDRSPACE '(' EUINT64VAL ')' '*' { // Pointer type?
1326 if (*$1 == Type::LabelTy)
1327 GEN_ERROR("Cannot form a pointer to a basic block");
1328 $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1, $4)));
13191329 delete $1;
13201330 CHECK_FOR_ERROR
13211331 }
20682078 GEN_ERROR("Global value initializer is not a constant");
20692079 CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
20702080 $2, $4, $5->getType(), $5, $3);
2081 CHECK_FOR_ERROR
2082 } GlobalVarAttributes {
2083 CurGV = 0;
2084 }
2085 | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal
2086 ADDRSPACE '(' EUINT64VAL ')' {
2087 /* "Externally Visible" Linkage with address space qualifier */
2088 if ($5 == 0)
2089 GEN_ERROR("Global value initializer is not a constant");
2090 CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
2091 $2, $4, $5->getType(), $5, $3, $8);
20712092 CHECK_FOR_ERROR
20722093 } GlobalVarAttributes {
20732094 CurGV = 0;
322322
323323 ResultTy = IntegerType::get(Record[0]);
324324 break;
325 case bitc::TYPE_CODE_POINTER: // POINTER: [pointee type]
325 case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
326 // [pointee type, address space]
326327 if (Record.size() < 1)
327328 return Error("Invalid POINTER type record");
328 ResultTy = PointerType::get(getTypeByID(Record[0], true));
329 break;
329 unsigned AddressSpace = 0;
330 if (Record.size() == 2)
331 AddressSpace = Record[1];
332 ResultTy = PointerType::get(getTypeByID(Record[0], true), AddressSpace);
333 break;
334 }
330335 case bitc::TYPE_CODE_FUNCTION: {
331336 // FIXME: attrid is dead, remove it in LLVM 3.0
332337 // FUNCTION: [vararg, attrid, retty, paramty x N]
981986 CollectorTable.push_back(S);
982987 break;
983988 }
984 // GLOBALVAR: [type, isconst, initid,
989 // GLOBALVAR: [pointer type, isconst, initid,
985990 // linkage, alignment, section, visibility, threadlocal]
986991 case bitc::MODULE_CODE_GLOBALVAR: {
987992 if (Record.size() < 6)
989994 const Type *Ty = getTypeByID(Record[0]);
990995 if (!isa(Ty))
991996 return Error("Global not a pointer type!");
997 unsigned AddressSpace = cast(Ty)->getAddressSpace();
992998 Ty = cast(Ty)->getElementType();
993999
9941000 bool isConstant = Record[1];
10081014 isThreadLocal = Record[7];
10091015
10101016 GlobalVariable *NewGV =
1011 new GlobalVariable(Ty, isConstant, Linkage, 0, "", TheModule);
1017 new GlobalVariable(Ty, isConstant, Linkage, 0, "", TheModule,
1018 isThreadLocal, AddressSpace);
10121019 NewGV->setAlignment(Alignment);
10131020 if (!Section.empty())
10141021 NewGV->setSection(Section);
14841491 I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
14851492 break;
14861493 }
1494 case bitc::FUNC_CODE_INST_STORE2: { // STORE2:[ptrty, ptr, val, align, vol]
1495 unsigned OpNum = 0;
1496 Value *Val, *Ptr;
1497 if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
1498 getValue(Record, OpNum,
1499 cast(Ptr->getType())->getElementType(), Val) ||
1500 OpNum+2 != Record.size())
1501 return Error("Invalid STORE record");
1502
1503 I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
1504 break;
1505 }
14871506 case bitc::FUNC_CODE_INST_STORE: { // STORE:[val, valty, ptr, align, vol]
1507 // FIXME: Legacy form of store instruction. Should be removed in LLVM 3.0.
14881508 unsigned OpNum = 0;
14891509 Value *Val, *Ptr;
14901510 if (getValueTypePair(Record, OpNum, NextValueNo, Val) ||
196196 TypeVals.push_back(cast(T)->getBitWidth());
197197 break;
198198 case Type::PointerTyID:
199 // POINTER: [pointee type]
199 const PointerType *PTy = cast(T);
200 // POINTER: [pointee type] or [pointee type, address space]
200201 Code = bitc::TYPE_CODE_POINTER;
201 TypeVals.push_back(VE.getTypeID(cast(T)->getElementType()));
202 AbbrevToUse = PtrAbbrev;
202 TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
203 if (unsigned AddressSpace = PTy->getAddressSpace())
204 TypeVals.push_back(AddressSpace);
205 else
206 AbbrevToUse = PtrAbbrev;
203207 break;
204208
205209 case Type::FunctionTyID: {
828832 Vals.push_back(cast(I).isVolatile());
829833 break;
830834 case Instruction::Store:
831 Code = bitc::FUNC_CODE_INST_STORE;
832 PushValueAndType(I.getOperand(0), InstID, Vals, VE); // val.
833 Vals.push_back(VE.getValueID(I.getOperand(1))); // ptr.
835 Code = bitc::FUNC_CODE_INST_STORE2;
836 PushValueAndType(I.getOperand(1), InstID, Vals, VE); // ptrty + ptr
837 Vals.push_back(VE.getValueID(I.getOperand(0))); // val.
834838 Vals.push_back(Log2_32(cast(I).getAlignment())+1);
835839 Vals.push_back(cast(I).isVolatile());
836840 break;
333333 Result += '>';
334334 break;
335335 }
336 case Type::PointerTyID:
337 calcTypeName(cast(Ty)->getElementType(),
336 case Type::PointerTyID: {
337 const PointerType *PTy = cast(Ty);
338 calcTypeName(PTy->getElementType(),
338339 TypeStack, TypeNames, Result);
340 if (unsigned AddressSpace = PTy->getAddressSpace())
341 Result += " addrspace(" + utostr(AddressSpace) + ")";
339342 Result += "*";
340343 break;
344 }
341345 case Type::ArrayTyID: {
342346 const ArrayType *ATy = cast(Ty);
343347 Result += "[" + utostr(ATy->getNumElements()) + " x ";
950954 writeOperand(GV->getInitializer(), false);
951955 }
952956
957 if (unsigned AddressSpace = GV->getType()->getAddressSpace())
958 Out << " addrspace(" << AddressSpace << ") ";
959
953960 if (GV->hasSection())
954961 Out << ", section \"" << GV->getSection() << '"';
955962 if (GV->getAlignment())
18591859 const Type *Ty =
18601860 GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true);
18611861 assert(Ty && "GEP indices invalid!");
1862 return getGetElementPtrTy(PointerType::get(Ty), C, Idxs, NumIdx);
1862 unsigned As = cast(C->getType())->getAddressSpace();
1863 return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
18631864 }
18641865
18651866 Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
8484
8585 GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
8686 Constant *InitVal, const std::string &Name,
87 Module *ParentModule, bool ThreadLocal)
88 : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
87 Module *ParentModule, bool ThreadLocal,
88 unsigned AddressSpace)
89 : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
8990 &Initializer, InitVal != 0, Link, Name),
9091 isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
9192 if (InitVal) {
104105
105106 GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
106107 Constant *InitVal, const std::string &Name,
107 GlobalVariable *Before, bool ThreadLocal)
108 : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
108 GlobalVariable *Before, bool ThreadLocal,
109 unsigned AddressSpace)
110 : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
109111 &Initializer, InitVal != 0, Link, Name),
110112 isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
111113 if (InitVal) {
936936
937937 GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
938938 const std::string &Name, Instruction *InBe)
939 : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx))),
939 : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)),
940 cast(Ptr->getType())->getAddressSpace()),
940941 GetElementPtr, 0, 0, InBe) {
941942 init(Ptr, Idx);
942943 setName(Name);
944945
945946 GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
946947 const std::string &Name, BasicBlock *IAE)
947 : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx))),
948 : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)),
949 cast(Ptr->getType())->getAddressSpace()),
948950 GetElementPtr, 0, 0, IAE) {
949951 init(Ptr, Idx);
950952 setName(Name);
337337 }
338338 case Type::PointerTyID: {
339339 const PointerType *PTy = cast(Ty);
340 Result = getTypeDescription(PTy->getElementType(), TypeStack) + " *";
340 Result = getTypeDescription(PTy->getElementType(), TypeStack);
341 if (unsigned AddressSpace = PTy->getAddressSpace())
342 Result += " addrspace(" + utostr(AddressSpace) + ")";
343 Result += " *";
341344 break;
342345 }
343346 case Type::ArrayTyID: {
491494 }
492495
493496
494 PointerType::PointerType(const Type *E) : SequentialType(PointerTyID, E) {
497 PointerType::PointerType(const Type *E, unsigned AddrSpace)
498 : SequentialType(PointerTyID, E) {
499 AddressSpace = AddrSpace;
495500 // Calculate whether or not this type is abstract
496501 setAbstract(E->isAbstract());
497502 }
633638 const IntegerType *ITy2 = cast(Ty2);
634639 return ITy->getBitWidth() == ITy2->getBitWidth();
635640 } else if (const PointerType *PTy = dyn_cast(Ty)) {
636 return TypesEqual(PTy->getElementType(),
637 cast(Ty2)->getElementType(), EqTypes);
641 const PointerType *PTy2 = cast(Ty2);
642 return PTy->getAddressSpace() == PTy2->getAddressSpace() &&
643 TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes);
638644 } else if (const StructType *STy = dyn_cast(Ty)) {
639645 const StructType *STy2 = cast(Ty2);
640646 if (STy->getNumElements() != STy2->getNumElements()) return false;
755761 case Type::StructTyID:
756762 HashVal ^= cast(SubTy)->getNumElements();
757763 break;
764 case Type::PointerTyID:
765 HashVal ^= cast(SubTy)->getAddressSpace();
766 break;
758767 }
759768 }
760769 return HashVal ? HashVal : 1; // Do not return zero unless opaque subty.
12501259 namespace llvm {
12511260 class PointerValType {
12521261 const Type *ValTy;
1262 unsigned AddressSpace;
12531263 public:
1254 PointerValType(const Type *val) : ValTy(val) {}
1264 PointerValType(const Type *val, unsigned as) : ValTy(val), AddressSpace(as) {}
12551265
12561266 static PointerValType get(const PointerType *PT) {
1257 return PointerValType(PT->getElementType());
1267 return PointerValType(PT->getElementType(), PT->getAddressSpace());
12581268 }
12591269
12601270 static unsigned hashTypeStructure(const PointerType *PT) {
12621272 }
12631273
12641274 bool operator<(const PointerValType &MTV) const {
1265 return ValTy < MTV.ValTy;
1275 if (AddressSpace < MTV.AddressSpace) return true;
1276 return AddressSpace == MTV.AddressSpace && ValTy < MTV.ValTy;
12661277 }
12671278 };
12681279 }
12691280
12701281 static ManagedStatic > PointerTypes;
12711282
1272 PointerType *PointerType::get(const Type *ValueType) {
1283 PointerType *PointerType::get(const Type *ValueType, unsigned AddressSpace) {
12731284 assert(ValueType && "Can't get a pointer to type!");
12741285 assert(ValueType != Type::VoidTy &&
12751286 "Pointer to void is not valid, use sbyte* instead!");
12761287 assert(ValueType != Type::LabelTy && "Pointer to label is not valid!");
1277 PointerValType PVT(ValueType);
1288 PointerValType PVT(ValueType, AddressSpace);
12781289
12791290 PointerType *PT = PointerTypes->get(PVT);
12801291 if (PT) return PT;
12811292
12821293 // Value not found. Derive a new type!
1283 PointerTypes->add(PVT, PT = new PointerType(ValueType));
1294 PointerTypes->add(PVT, PT = new PointerType(ValueType, AddressSpace));
12841295
12851296 #ifdef DEBUG_MERGE_TYPES
12861297 DOUT << "Derived new type: " << *PT << "\n";
0 ; RUN: llvm-as < %s | llvm-dis |& grep {addrspace(33)} | count 7
1 ; RUN: llvm-as < %s | llvm-dis |& grep {addrspace(42)} | count 2
2 ; RUN: llvm-as < %s | llvm-dis |& grep {addrspace(66)} | count 2
3 ; RUN: llvm-as < %s | llvm-dis |& grep {addrspace(11)} | count 6
4 ; RUN: llvm-as < %s | llvm-dis |& grep {addrspace(22)} | count 5
5
6 %struct.mystruct = type { i32, i32 addrspace(33)*, i32, i32 addrspace(33)* }
7 @input = global %struct.mystruct zeroinitializer addrspace(42) ; <%struct.mystruct addrspace(42)*> [#uses=1]
8 @output = global %struct.mystruct zeroinitializer addrspace(66) ; <%struct.mystruct addrspace(66)*> [#uses=1]
9 @y = global i32 addrspace(11)* addrspace(22)* null addrspace(33) ; [#uses=1]
10
11 define void @foo() {
12 entry:
13 %tmp1 = load i32 addrspace(33)* addrspace(42)* getelementptr (%struct.mystruct addrspace(42)* @input, i32 0, i32 3), align 4 ; [#uses=1]
14 store i32 addrspace(33)* %tmp1, i32 addrspace(33)* addrspace(66)* getelementptr (%struct.mystruct addrspace(66)* @output, i32 0, i32 1), align 4
15 ret void
16 }
17
18 define i32 addrspace(11)* @bar(i32 addrspace(11)* addrspace(22)* addrspace(33)* %x) {
19 entry:
20 %tmp1 = load i32 addrspace(11)* addrspace(22)* addrspace(33)* @y, align 4 ; [#uses=2]
21 store i32 addrspace(11)* addrspace(22)* %tmp1, i32 addrspace(11)* addrspace(22)* addrspace(33)* %x, align 4
22 %tmp5 = load i32 addrspace(11)* addrspace(22)* %tmp1, align 4 ; [#uses=1]
23 ret i32 addrspace(11)* %tmp5
24 }
196196 case bitc::FUNC_CODE_INST_STORE: return "INST_STORE";
197197 case bitc::FUNC_CODE_INST_CALL: return "INST_CALL";
198198 case bitc::FUNC_CODE_INST_VAARG: return "INST_VAARG";
199 case bitc::FUNC_CODE_INST_STORE2: return "INST_STORE2";
199200 }
200201 case bitc::TYPE_SYMTAB_BLOCK_ID:
201202 switch (CodeID) {