Implement review feedback. Aliasees can be either GlobalValue's or
bitcasts of them.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36537 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Bytecode/Reader/Analyzer.cpp b/lib/Bytecode/Reader/Analyzer.cpp
index dde73df..2d90c93 100644
--- a/lib/Bytecode/Reader/Analyzer.cpp
+++ b/lib/Bytecode/Reader/Analyzer.cpp
@@ -179,6 +179,27 @@
 
   }
 
+  virtual void handleGlobalAlias(
+    const Type* ElemType,
+    GlobalValue::LinkageTypes Linkage,
+    unsigned TypeSlotNum,
+    unsigned AliaseeSlot) {
+    if (os) {
+      *os << "      GA: "
+          << " Linkage=" << Linkage
+          << " Type=";
+      //WriteTypeSymbolic(*os, ElemType, M);
+      *os << " Slot=" << TypeSlotNum << " AliaseeSlot=" << AliaseeSlot
+          << "\n";
+    }
+
+    bca.numValues++;
+    if (TypeSlotNum > bca.maxValueSlot)
+      bca.maxValueSlot = TypeSlotNum;
+    if (AliaseeSlot > bca.maxValueSlot)
+      bca.maxValueSlot = AliaseeSlot;
+  }
+
   virtual void handleTypeList(unsigned numEntries) {
     bca.maxTypeSlot = numEntries - 1;
   }
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp
index f7606c6..99aac05 100644
--- a/lib/Bytecode/Reader/Reader.cpp
+++ b/lib/Bytecode/Reader/Reader.cpp
@@ -1923,12 +1923,10 @@
     // Read aliases...
     unsigned VarType = read_vbr_uint();
     while (VarType != Type::VoidTyID) { // List is terminated by Void
-      unsigned TypeSlotNo = VarType >> 2;
+      unsigned TypeSlotNo     = VarType >> 3;
       unsigned EncodedLinkage = VarType & 3;
-      unsigned AliaseeTypeSlotNo, AliaseeSlotNo;
-
-      AliaseeTypeSlotNo = read_vbr_uint();
-      AliaseeSlotNo = read_vbr_uint();
+      bool isConstantAliasee  = (VarType >> 2) & 1;
+      unsigned AliaseeSlotNo  = read_vbr_uint();
 
       const Type *Ty = getType(TypeSlotNo);
       if (!Ty)
@@ -1937,11 +1935,11 @@
       if (!isa<PointerType>(Ty))
         error("Alias not a pointer type! Ty= " + Ty->getDescription());
       
-      Value* V = getValue(AliaseeTypeSlotNo, AliaseeSlotNo, false);
-      if (!V)
-        error("Invalid aliasee! TypeSlotNo=" + utostr(AliaseeTypeSlotNo) +
+      Value* V = getValue(TypeSlotNo, AliaseeSlotNo, false);
+      if (!V && !isConstantAliasee)
+        error("Invalid aliasee! TypeSlotNo=" + utostr(TypeSlotNo) +
               " SlotNo=" + utostr(AliaseeSlotNo));
-      if (!isa<GlobalValue>(V))
+      if (!isConstantAliasee && !isa<GlobalValue>(V))
         error("Aliasee is not global value! SlotNo=" + utostr(AliaseeSlotNo));
 
       GlobalValue::LinkageTypes Linkage;
@@ -1960,8 +1958,14 @@
       }
       
       GlobalAlias *GA = new GlobalAlias(Ty, Linkage, "",
-                                        dyn_cast<GlobalValue>(V), TheModule);
+                                        dyn_cast_or_null<Constant>(V),
+                                        TheModule);
       insertValue(GA, TypeSlotNo, ModuleValues);
+      if (!V && isConstantAliasee)
+        Aliasees.push_back(std::make_pair(GA, AliaseeSlotNo));
+
+      if (Handler) Handler->handleGlobalAlias(Ty, Linkage,
+                                              TypeSlotNo, AliaseeSlotNo);
       VarType = read_vbr_uint();
     }
   }  
@@ -2068,6 +2072,23 @@
       error("Cannot find initializer value.");
   }
 
+  // And aliasees
+  while (!Aliasees.empty()) {
+    GlobalAlias *GA = Aliasees.back().first;
+    unsigned Slot = Aliasees.back().second;
+    Aliasees.pop_back();
+
+    // Look up the aliasee value...
+    const llvm::PointerType* GAType = GA->getType();
+    unsigned TypeSlot = getTypeSlot(GAType);
+    if (Constant *CV = getConstantValue(TypeSlot, Slot)) {
+      if (GA->getAliasee())
+        error("Aliasee was *already* set?!");
+      GA->setAliasee(CV);
+    } else
+      error("Cannot find aliasee value.");
+  }
+
   if (!ConstantFwdRefs.empty())
     error("Use of undefined constants in a module");
 
diff --git a/lib/Bytecode/Reader/Reader.h b/lib/Bytecode/Reader/Reader.h
index c852cce..95cf58c 100644
--- a/lib/Bytecode/Reader/Reader.h
+++ b/lib/Bytecode/Reader/Reader.h
@@ -129,6 +129,9 @@
   /// them.
   typedef std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitsList;
 
+  /// @brief A list of global aliases and the slot number for constant aliasees
+  typedef std::vector<std::pair<GlobalAlias*, unsigned> > AliaseeList;
+
   /// This type maps a typeslot/valueslot pair to the corresponding Value*.
   /// It is used for dealing with forward references as values are read in.
   /// @brief A map for dealing with forward references of values.
@@ -338,6 +341,12 @@
   /// of what we must do.
   GlobalInitsList GlobalInits;
 
+  /// Constant values are read in after global aliases. Because of this, we must
+  /// defer setting the constant aliasees until after module level constants
+  /// have been read. In the mean time, this list keeps track of what we must
+  /// do.
+  AliaseeList Aliasees;
+  
   // For lazy reading-in of functions, we need to save away several pieces of
   // information about each function: its begin and end pointer in the buffer
   // and its FunctionSlot.
diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp
index 85ccad5..3a038cd 100644
--- a/lib/Bytecode/Writer/SlotCalculator.cpp
+++ b/lib/Bytecode/Writer/SlotCalculator.cpp
@@ -89,6 +89,12 @@
        I != E; ++I)
     CreateSlotIfNeeded(I);
 
+  // Add all of the global aliases to the value table...
+  //
+  for (Module::const_alias_iterator I = TheModule->alias_begin(),
+         E = TheModule->alias_end(); I != E; ++I)
+    CreateSlotIfNeeded(I);
+
   // Add all of the module level constants used as initializers
   //
   for (Module::const_global_iterator I = TheModule->global_begin(),
@@ -96,6 +102,13 @@
     if (I->hasInitializer())
       CreateSlotIfNeeded(I->getInitializer());
 
+  // Add all of the module level constants used as aliasees
+  //
+  for (Module::const_alias_iterator I = TheModule->alias_begin(),
+         E = TheModule->alias_end(); I != E; ++I)
+    if (I->getAliasee())
+      CreateSlotIfNeeded(I->getAliasee());
+
   // Now that all global constants have been added, rearrange constant planes
   // that contain constant strings so that the strings occur at the start of the
   // plane, not somewhere in the middle.
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp
index 7295239..f1c6f6c 100644
--- a/lib/Bytecode/Writer/Writer.cpp
+++ b/lib/Bytecode/Writer/Writer.cpp
@@ -1095,9 +1095,11 @@
   // Output aliases
   for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
        I != E; ++I) {
-    unsigned Slot = Table.getTypeSlot(I->getType());
-    assert(((Slot << 2) >> 2) == Slot && "Slot # too big!");
+    unsigned TypeSlotNo    = Table.getTypeSlot(I->getType());
+    unsigned AliaseeSlotNo = Table.getSlot(I->getAliasee());
+    assert(((TypeSlotNo << 3) >> 3) == TypeSlotNo && "Slot # too big!");
     unsigned aliasLinkage = 0;
+    unsigned isConstantAliasee = ((!isa<GlobalValue>(I->getAliasee())) << 2);
     switch (I->getLinkage()) {
      case GlobalValue::ExternalLinkage:
       aliasLinkage = 0;
@@ -1111,9 +1113,8 @@
      default:
       assert(0 && "Invalid alias linkage");
     }    
-    output_vbr((Slot << 2) | aliasLinkage);
-    output_vbr(Table.getTypeSlot(I->getAliasee()->getType()));
-    output_vbr(Table.getSlot(I->getAliasee()));
+    output_vbr((TypeSlotNo << 3) | isConstantAliasee | aliasLinkage);
+    output_vbr(AliaseeSlotNo);
   }
   output_typeid(Table.getTypeSlot(Type::VoidTy));
 }