Implement review feedback. Aliasees can be either GlobalValue's or
authorAnton Korobeynikov <asl@math.spbu.ru>
Sat, 28 Apr 2007 13:45:00 +0000 (13:45 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Sat, 28 Apr 2007 13:45:00 +0000 (13:45 +0000)
bitcasts of them.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36537 91177308-0d34-0410-b5e6-96231b3b80d8

20 files changed:
docs/BytecodeFormat.html
docs/LangRef.html
include/llvm/Bytecode/BytecodeHandler.h
include/llvm/Function.h
include/llvm/GlobalAlias.h
include/llvm/GlobalValue.h
include/llvm/GlobalVariable.h
lib/AsmParser/llvmAsmParser.y
lib/Bytecode/Reader/Analyzer.cpp
lib/Bytecode/Reader/Reader.cpp
lib/Bytecode/Reader/Reader.h
lib/Bytecode/Writer/SlotCalculator.cpp
lib/Bytecode/Writer/Writer.cpp
lib/CodeGen/AsmPrinter.cpp
lib/Transforms/IPO/GlobalDCE.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Globals.cpp
lib/VMCore/Module.cpp
lib/VMCore/Verifier.cpp
test/Feature/aliases.ll

index 396bf2f12498dc8af4ee88988abf0eda09cf0c2d..f479ca57b5f6ca56a09dedec25e0c2834143275d 100644 (file)
@@ -1212,14 +1212,18 @@ the first <a href="#uint32_vbr">uint32_vbr</a> which describes alias itself.</p>
       linkage, 2 - Weak linkage.</td>
     </tr>
     <tr>
-      <td><a href="#bit">bit(2-31)</a></td>
+      <td><a href="#bit">bit(2)</a></td>
+      <td class="td_left">0 - Aliasee is global value. 1 - Aliasee is constant
+      expression (bitcast of global value)</td>
+    </tr>    
+    <tr>
+      <td><a href="#bit">bit(3-31)</a></td>
       <td class="td_left">Type slot number of type for the alias itself.</td>
     </tr>
   </tbody>
 </table>
 
-  <p>The next two <a href="#uint32_vbr">uint32_vbr's</a> describes the
-  aliasee. </p>
+  <p>The next <a href="#uint32_vbr">uint32_vbr</a> describes the aliasee. </p>
 
 <table>
   <tbody>
@@ -1227,10 +1231,6 @@ the first <a href="#uint32_vbr">uint32_vbr</a> which describes alias itself.</p>
       <th><b>Type</b></th>
       <th class="td_left"><b>Description</b></th>
     </tr>
-    <tr>
-      <td><a href="#uint32_vbr">uint32_vbr</a></td>
-      <td class="td_left">Type slot number of type for the aliasee.</td>
-    </tr>
     <tr>
       <td><a href="#uint32_vbr">uint32_vbr</a></td>
       <td class="td_left">Slot number of the aliasee.</td>
index 807d1047f61dc2c306089215ef0a851410b06d96..54b01eae87464f16d66c1dbdb38ced1eb2dbd651 100644 (file)
@@ -24,6 +24,7 @@
       <li><a href="#callingconv">Calling Conventions</a></li>
       <li><a href="#globalvars">Global Variables</a></li>
       <li><a href="#functionstructure">Functions</a></li>
+      <li><a href="aliasstructure">Aliases</a>
       <li><a href="#paramattrs">Parameter Attributes</a></li>
       <li><a href="#moduleasm">Module-Level Inline Assembly</a></li>
       <li><a href="#datalayout">Data Layout</a></li>
@@ -705,7 +706,7 @@ a power of 2.</p>
 </div>
 <div class="doc_text">
   <p>Aliases act as "second name" for the aliasee value (which can be either
-  function or global variable). Aliases may have an
+  function or global variable or bitcast of global value). Aliases may have an
   optional <a href="#linkage">linkage type</a>, and an
   optional <a href="#visibility">visibility style</a>.</p>
 
index 3d885e123fbb02976748df673ec7d96b0ec35849..e45266bb2c3ca03511124cc45fec0602ff69eb66 100644 (file)
@@ -116,6 +116,12 @@ public:
     bool isThreadLocal        ///< Whether the GV is thread local or not
   ) {}
 
+  virtual void handleGlobalAlias(
+    const Type* ElemType,
+    GlobalValue::LinkageTypes Linkage,
+    unsigned TypeSlotNum,
+    unsigned AliaseeSlot) { }
+  
   /// This method is called when a type list is recognized. It simply
   /// provides the number of types that the list contains. The handler
   /// should expect that number of calls to handleType.
index c0984f636789daafe505cfe0681560b9e243ffcc..71fb87ea6671bad175bd4ed1ea15127792e6fe2c 100644 (file)
@@ -81,6 +81,15 @@ private:
   void setNext(Function *N) { Next = N; }
   void setPrev(Function *N) { Prev = N; }
 
+  // getNext/Prev - Return the next or previous function in the list.  These
+  // methods should never be used directly, and are only used to implement the
+  // function list as part of the module.
+  //
+  Function *getNext()             { return Next; }
+  const Function *getNext() const { return Next; }
+  Function *getPrev()             { return Prev; }
+  const Function *getPrev() const { return Prev; }
+
 public:
   /// Function ctor - If the (optional) Module argument is specified, the
   /// function is automatically inserted into the end of the function list for
@@ -243,15 +252,6 @@ public:
     Function *Obj = 0;
     return unsigned(reinterpret_cast<uintptr_t>(&Obj->ArgumentList));
   }
-private:
-  // getNext/Prev - Return the next or previous function in the list.  These
-  // methods should never be used directly, and are only used to implement the
-  // function list as part of the module.
-  //
-  Function *getNext()             { return Next; }
-  const Function *getNext() const { return Next; }
-  Function *getPrev()             { return Prev; }
-  const Function *getPrev() const { return Prev; }
 };
 
 inline ValueSymbolTable *
index ec6ea77060529f44e5d19456992169d8049605bc..04bd5fbd7fee3bc69adf0978c0caaad5a64b7c52 100644 (file)
@@ -1,4 +1,4 @@
-//===______-- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===//
+//===-------- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // This file contains the declaration of the GlobalAlias class, which
-// represents a single function or variable alias in the VM.
+// represents a single function or variable alias in the IR.
 //
 //===----------------------------------------------------------------------===//
 
@@ -36,13 +36,18 @@ class GlobalAlias : public GlobalValue {
   void setNext(GlobalAlias *N) { Next = N; }
   void setPrev(GlobalAlias *N) { Prev = N; }
 
-  const GlobalValue* Aliasee;
-  std::string Target;
+  // getNext/Prev - Return the next or previous alias in the list.
+        GlobalAlias *getNext()       { return Next; }
+  const GlobalAlias *getNext() const { return Next; }
+        GlobalAlias *getPrev()       { return Prev; }
+  const GlobalAlias *getPrev() const { return Prev; }
+
+  Use Aliasee;
 public:
   /// GlobalAlias ctor - If a parent module is specified, the alias is
-  /// automatically inserted into the end of the specified modules alias list.
+  /// automatically inserted into the end of the specified module's alias list.
   GlobalAlias(const Type *Ty, LinkageTypes Linkage, const std::string &Name = "",
-              const GlobalValue* Aliasee = 0, Module *Parent = 0);
+              Constant* Aliasee = 0, Module *Parent = 0);
 
   /// isDeclaration - Is this global variable lacking an initializer?  If so, 
   /// the global variable is defined in some other translation unit, and is thus
@@ -52,30 +57,30 @@ public:
   /// removeFromParent - This method unlinks 'this' from the containing module,
   /// but does not delete it.
   ///
-  virtual void removeFromParent();
+  void removeFromParent();
 
   /// eraseFromParent - This method unlinks 'this' from the containing module
   /// and deletes it.
   ///
-  virtual void eraseFromParent();
+  void eraseFromParent();
 
   virtual void print(std::ostream &OS) const;
   void print(std::ostream *OS) const { if (OS) print(*OS); }
 
-  void setAliasee(const GlobalValue* GV);
-  const GlobalValue* getAliasee() const { return Aliasee; }
+  /// set/getAliasee - These methods retrive and set alias target.
+  void setAliasee(Constant* GV);
+  const Constant* getAliasee() const {
+    return cast_or_null<Constant>(getOperand(0));
+  }
+  Constant* getAliasee() {
+    return cast_or_null<Constant>(getOperand(0));
+  }
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const GlobalAlias *) { return true; }
   static inline bool classof(const Value *V) {
     return V->getValueID() == Value::GlobalAliasVal;
   }
-private:
-  // getNext/Prev - Return the next or previous alias in the list.
-        GlobalAlias *getNext()       { return Next; }
-  const GlobalAlias *getNext() const { return Next; }
-        GlobalAlias *getPrev()       { return Prev; }
-  const GlobalAlias *getPrev() const { return Prev; }
 };
 
 } // End llvm namespace
index 317aa486a4070d9b2cf84a630796c3d2ff552b0a..014cdbe82af2dd6f9b9e55904be2898d559fc130 100644 (file)
@@ -121,16 +121,6 @@ public:
   /// value is outside of the current translation unit...
   virtual bool isDeclaration() const = 0;
 
-  /// removeFromParent - This method unlinks 'this' from the containing module,
-  /// but does not delete it.
-  ///
-  virtual void removeFromParent() = 0;
-
-  /// eraseFromParent - This method unlinks 'this' from the containing module
-  /// and deletes it.
-  ///
-  virtual void eraseFromParent() = 0;
-
   /// getParent - Get the module that this global value is contained inside
   /// of...
   inline Module *getParent() { return Parent; }
index 303e57f99a584d6a524317c41d9c72bd31e87b65..00d4acb66daf53d5886cc5af540a8bfa74f4f59e 100644 (file)
@@ -107,12 +107,12 @@ public:
   /// removeFromParent - This method unlinks 'this' from the containing module,
   /// but does not delete it.
   ///
-  virtual void removeFromParent();
+  void removeFromParent();
 
   /// eraseFromParent - This method unlinks 'this' from the containing module
   /// and deletes it.
   ///
-  virtual void eraseFromParent();
+  void eraseFromParent();
 
   /// Override Constant's implementation of this method so we can
   /// replace constant initializers.
index 14524cb4a583c5f53918038b3899d660aa558623..f2b9fb0d2f6f694794961a07e39cb4a1dad48e26 100644 (file)
@@ -480,8 +480,24 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
   // or an id number that hasn't been read yet.  We may be referencing something
   // forward, so just create an entry to be resolved later and get to it...
   //
-  V = new Argument(Ty);
-
+  switch (ID.Type) {
+  case ValID::GlobalName:
+  case ValID::GlobalID:
+   const PointerType *PTy = dyn_cast<PointerType>(Ty);
+   if (!PTy) {
+     GenerateError("Invalid type for reference to global" );
+     return 0;
+   }
+   const Type* ElTy = PTy->getElementType();
+   if (const FunctionType *FTy = dyn_cast<FunctionType>(ElTy))
+     V = new Function(FTy, GlobalValue::ExternalLinkage);
+   else
+     V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage);
+   break;
+  default:
+   V = new Argument(Ty);
+  }
+  
   // Remember where this forward reference came from.  FIXME, shouldn't we try
   // to recycle these things??
   CurModule.PlaceHolderInfo.insert(std::make_pair(V, std::make_pair(ID,
@@ -987,7 +1003,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 %type <BasicBlockVal> BasicBlock InstructionList
 %type <TermInstVal>   BBTerminatorInst
 %type <InstVal>       Inst InstVal MemoryInst
-%type <ConstVal>      ConstVal ConstExpr
+%type <ConstVal>      ConstVal ConstExpr AliaseeRef
 %type <ConstVector>   ConstVector
 %type <ArgList>       ArgList ArgListH
 %type <PHIList>       PHIList
@@ -1943,6 +1959,30 @@ GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; };
 // ThreadLocal 
 ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; };
 
+// AliaseeRef - Match either GlobalValue or bitcast to GlobalValue.
+AliaseeRef : ResultTypes SymbolicValueRef {
+    const Type* VTy = $1->get();
+    Value *V = getVal(VTy, $2);
+    GlobalValue* Aliasee = dyn_cast<GlobalValue>(V);
+    if (!Aliasee)
+      GEN_ERROR("Aliases can be created only to global values");
+
+    $$ = Aliasee;
+    CHECK_FOR_ERROR
+    delete $1;
+   }
+   | BITCAST '(' AliaseeRef TO Types ')' {
+    Constant *Val = $3;
+    const Type *DestTy = $5->get();
+    if (!CastInst::castIsValid($1, $3, DestTy))
+      GEN_ERROR("invalid cast opcode for cast from '" +
+                Val->getType()->getDescription() + "' to '" +
+                DestTy->getDescription() + "'");
+    
+    $$ = ConstantExpr::getCast($1, $3, DestTy);
+    CHECK_FOR_ERROR
+    delete $5;
+   };
 
 //===----------------------------------------------------------------------===//
 //                             Rules to match Modules
@@ -2045,34 +2085,20 @@ Definition
     CurGV = 0;
     CHECK_FOR_ERROR
   }
-  | OptGlobalAssign GVVisibilityStyle ALIAS AliasLinkage ResultTypes
-    SymbolicValueRef {
+  | OptGlobalAssign GVVisibilityStyle ALIAS AliasLinkage AliaseeRef {
     std::string Name($1);
     if (Name.empty())
-      GEN_ERROR("Alias name cannot be empty")
-    const PointerType *PFTy = 0;
-    const FunctionType *Ty = 0;
-    Value* V = 0;
-    const Type* VTy = 0;
-    if (!(PFTy = dyn_cast<PointerType>($5->get())) ||
-        !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
-      VTy = $5->get();
-      V = getExistingVal(VTy, $6);
-    } else {
-      VTy = PFTy;
-      V = getExistingVal(PFTy, $6);
-    }
-    if (V == 0)
+      GEN_ERROR("Alias name cannot be empty");
+    
+    Constant* Aliasee = $5;
+    if (Aliasee == 0)
       GEN_ERROR(std::string("Invalid aliasee for alias: ") + $1);
-    if (GlobalValue* Aliasee = dyn_cast<GlobalValue>(V)) {
-      GlobalAlias* GA = new GlobalAlias(VTy, $4, Name, Aliasee,
-                                        CurModule.CurrentModule);
-      GA->setVisibility($2);
-      InsertValue(GA, CurModule.Values);
-    } else
-      GEN_ERROR("Aliases can be created only to global values");
+
+    GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), $4, Name, Aliasee,
+                                      CurModule.CurrentModule);
+    GA->setVisibility($2);
+    InsertValue(GA, CurModule.Values);
     CHECK_FOR_ERROR
-    delete $5;
   }
   | TARGET TargetDefinition { 
     CHECK_FOR_ERROR
index dde73dfb1a8333bd11ac310a16fa052fd009a334..2d90c938263d136f96e58230f13922e66798104a 100644 (file)
@@ -179,6 +179,27 @@ public:
 
   }
 
+  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;
   }
index f7606c6e5af2aac89979b0ce5e451969b3275376..99aac056ff3bc7fea80e10b0b11698789986b656 100644 (file)
@@ -1923,12 +1923,10 @@ void BytecodeReader::ParseModuleGlobalInfo() {
     // 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 @@ void BytecodeReader::ParseModuleGlobalInfo() {
       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 @@ void BytecodeReader::ParseModuleGlobalInfo() {
       }
       
       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 @@ void BytecodeReader::ParseModule() {
       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");
 
index c852cce6babdc18873c73d462ff39887c7e45d44..95cf58c2b3cbfadf0f8a078e8e2dba5bc6aadb45 100644 (file)
@@ -129,6 +129,9 @@ public:
   /// 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 @@ private:
   /// 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.
index 85ccad58c5ba32f0500c626a49c67f2167553c34..3a038cd449af4413675a8eee4cb4953648276a13 100644 (file)
@@ -89,6 +89,12 @@ void SlotCalculator::processModule() {
        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 @@ void SlotCalculator::processModule() {
     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.
index 7295239fdd066e2114136ddeb9f388e1adbc3707..f1c6f6c56190e2abec870deea131fb16ebaf1245 100644 (file)
@@ -1095,9 +1095,11 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
   // 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 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
      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));
 }
index 90a98cb5a75a9f2fc8043501da95a2695310dc06..f7571831a344184a2163ce8f7dae88cc1ea8544b 100644 (file)
@@ -123,18 +123,29 @@ bool AsmPrinter::doFinalization(Module &M) {
   }
 
   if (TAI->getSetDirective()) {
-    if (M.alias_size())
+    if (!M.alias_empty())
       SwitchToTextSection(TAI->getTextSection());
 
     O << "\n";
     for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
          I!=E; ++I) {
-      const GlobalValue *Aliasee = I->getAliasee();
-      assert(Aliasee && "Aliasee cannot be null!");
-      std::string Target   = Mang->getValueName(Aliasee);
-      std::string Name     = Mang->getValueName(I);
+      const Constant *Aliasee = dyn_cast_or_null<Constant>(I->getAliasee());
+      assert(Aliasee && "Aliasee cannot be null");
 
-      // Aliases with external weak linkage was emitted already
+      std::string Name = Mang->getValueName(I);
+      std::string Target;
+      
+      if (const GlobalValue *GV = dyn_cast<GlobalValue>(Aliasee))
+        Target = Mang->getValueName(GV);
+      else {
+        const ConstantExpr *CE = 0;
+        if ((CE = dyn_cast<ConstantExpr>(Aliasee)) &&
+            (CE->getOpcode() == Instruction::BitCast))
+          Target = Mang->getValueName(CE->getOperand(0));
+        else
+          assert(0 && "Unsupported aliasee");
+      }
+      
       if (I->hasExternalLinkage())
         O << "\t.globl\t" << Name << "\n";
       else if (I->hasWeakLinkage())
index 560bcb56b0f252b7c3f3641a618b60f70e109778..90150689cc87e107cada352fa453706c352bbe74 100644 (file)
@@ -75,9 +75,8 @@ bool GlobalDCE::runOnModule(Module &M) {
 
   for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
        I != E; ++I) {
-    Changed |= RemoveUnusedGlobalValue(*I);
     // Aliases are always needed even if they are not used.
-    GlobalIsNeeded(I);
+    MarkUsedGlobalsAsNeeded(cast<Constant>(I->getAliasee()));
   }
 
   // Now that all globals which are needed are in the AliveGlobals set, we loop
@@ -143,10 +142,7 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
     // referenced by the initializer to the alive set.
     if (GV->hasInitializer())
       MarkUsedGlobalsAsNeeded(GV->getInitializer());
-  } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(G)) {
-    // If this is a global alias we also need it's aliasee
-    GlobalIsNeeded(const_cast<GlobalValue*>(GA->getAliasee()));
-  } else {
+  } else if (!isa<GlobalAlias>(G)) {
     // Otherwise this must be a function object.  We have to scan the body of
     // the function looking for constants and global values which are used as
     // operands.  Any operands of these types must be processed to ensure that
index 8834e1e2a22411eb720a725f29e3926c5eb05257..656a7bed74e2d46013cd1ce7273b93e162ea5fe4 100644 (file)
@@ -926,7 +926,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
    assert(0 && "Invalid alias linkage");
   }
   
-  const GlobalValue *Aliasee = GA->getAliasee();
+  const Constant *Aliasee = dyn_cast_or_null<Constant>(GA->getAliasee());
   assert(Aliasee && "Aliasee cannot be null");
     
   if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
@@ -940,9 +940,15 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
       Out << getLLVMName(F->getName(), GlobalPrefix);
     else
       Out << "@\"\"";
-  } else
-    assert(0 && "Unsupported aliasee");
-
+  } else {
+    const ConstantExpr *CE = 0;
+    if ((CE = dyn_cast<ConstantExpr>(Aliasee)) &&
+        (CE->getOpcode() == Instruction::BitCast)) {
+      writeOperand(CE, false);    
+    } else
+      assert(0 && "Unsupported aliasee");
+  }
+  
   printInfoComment(*GA);
   Out << "\n";
 }
index c64b719095dae422c8b6e587c0e89e5fb680dfc4..88a8c0b2a7ad7d4484456cfc524735a6d282321b 100644 (file)
@@ -163,12 +163,15 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
 //===----------------------------------------------------------------------===//
 
 GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
-                         const std::string &Name, const GlobalValue* aliasee,
+                         const std::string &Name, Constant* aliasee,
                          Module *ParentModule)
-  : GlobalValue(Ty, Value::GlobalAliasVal, 0, 0,
-                Link, Name), Aliasee(aliasee) {
+  : GlobalValue(Ty, Value::GlobalAliasVal, &Aliasee, 1, Link, Name) {
   LeakDetector::addGarbageObject(this);
 
+  if (aliasee)
+    assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
+  Aliasee.init(aliasee, this);
+
   if (ParentModule)
     ParentModule->getAliasList().push_back(this);
 }
@@ -190,12 +193,16 @@ void GlobalAlias::eraseFromParent() {
 }
 
 bool GlobalAlias::isDeclaration() const {
-  return (Aliasee && Aliasee->isDeclaration());
+  const GlobalValue* AV = dyn_cast_or_null<const GlobalValue>(getAliasee());
+  return (AV && AV->isDeclaration());
 }
 
-void GlobalAlias::setAliasee(const GlobalValue *GV
+void GlobalAlias::setAliasee(Constant *Aliasee
 {
-  // FIXME: Some checks?
-  Aliasee = GV;
+  if (Aliasee) {
+    assert(Aliasee->getType() == getType() && 
+           "Alias and aliasee types should match!");
+    setOperand(0, Aliasee);
+  }
 }
 
index c66032388baf4ba23d380f580db06eb0169d46b4..e20dab30be99c4767c93463e13fe22a7b988301d 100644 (file)
@@ -298,6 +298,9 @@ void Module::dropAllReferences() {
 
   for(Module::global_iterator I = global_begin(), E = global_end(); I != E; ++I)
     I->dropAllReferences();
+
+  for(Module::alias_iterator I = alias_begin(), E = alias_end(); I != E; ++I)
+    I->dropAllReferences();
 }
 
 void Module::addLibrary(const std::string& Lib) {
index 1578c2ddd6d911961af345c472a430916799f3d4..01eb860f911b108db91028ebcdcf2389bb12fcbe 100644 (file)
@@ -316,7 +316,9 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) {
   Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() ||
           GA.hasWeakLinkage(),
           "Alias should have external or external weak linkage!", &GA);
-
+  Assert1(GA.getType() == GA.getAliasee()->getType(),
+          "Alias and aliasee types should match!", &GA);
+  
   visitGlobalValue(GA);
 }
 
index c099cc90802162af7f84a21f2f257407f6c3418f..fc5e7685ca6c047e9fdc2adcf09e2faa62937e60 100644 (file)
@@ -2,8 +2,6 @@
 ; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
 ; RUN: diff %t1.ll %t2.ll
 
-; XFAIL: *
-
 @bar = external global i32
 @foo1 = alias i32* @bar
 @foo2 = alias i32* @bar
@@ -15,6 +13,8 @@ declare i32 @foo_f()
 
 @bar_i = alias internal i32* @bar
 
+@A = alias bitcast (i32* @bar to i64*)
+
 define i32 @test() {
 entry:
    %tmp = load i32* @foo1