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
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index fd3ec9e..72756ef 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -323,11 +323,16 @@
       
       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 @@
       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 @@
       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 @@
         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 @@
       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 612d893..c58d23a 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -197,10 +197,14 @@
       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 @@
     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;