summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/BytecodeFormat.html14
-rw-r--r--docs/LangRef.html3
-rw-r--r--include/llvm/Bytecode/BytecodeHandler.h6
-rw-r--r--include/llvm/Function.h18
-rw-r--r--include/llvm/GlobalAlias.h37
-rw-r--r--include/llvm/GlobalValue.h10
-rw-r--r--include/llvm/GlobalVariable.h4
-rw-r--r--lib/AsmParser/llvmAsmParser.y80
-rw-r--r--lib/Bytecode/Reader/Analyzer.cpp21
-rw-r--r--lib/Bytecode/Reader/Reader.cpp41
-rw-r--r--lib/Bytecode/Reader/Reader.h9
-rw-r--r--lib/Bytecode/Writer/SlotCalculator.cpp13
-rw-r--r--lib/Bytecode/Writer/Writer.cpp11
-rw-r--r--lib/CodeGen/AsmPrinter.cpp23
-rw-r--r--lib/Transforms/IPO/GlobalDCE.cpp8
-rw-r--r--lib/VMCore/AsmWriter.cpp14
-rw-r--r--lib/VMCore/Globals.cpp21
-rw-r--r--lib/VMCore/Module.cpp3
-rw-r--r--lib/VMCore/Verifier.cpp4
-rw-r--r--test/Feature/aliases.ll4
20 files changed, 231 insertions, 113 deletions
diff --git a/docs/BytecodeFormat.html b/docs/BytecodeFormat.html
index 396bf2f124..f479ca57b5 100644
--- a/docs/BytecodeFormat.html
+++ b/docs/BytecodeFormat.html
@@ -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>
@@ -1229,10 +1233,6 @@ the first <a href="#uint32_vbr">uint32_vbr</a> which describes alias itself.</p>
</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>
</tr>
</tbody>
diff --git a/docs/LangRef.html b/docs/LangRef.html
index 807d1047f6..54b01eae87 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -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>
diff --git a/include/llvm/Bytecode/BytecodeHandler.h b/include/llvm/Bytecode/BytecodeHandler.h
index 3d885e123f..e45266bb2c 100644
--- a/include/llvm/Bytecode/BytecodeHandler.h
+++ b/include/llvm/Bytecode/BytecodeHandler.h
@@ -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.
diff --git a/include/llvm/Function.h b/include/llvm/Function.h
index c0984f6367..71fb87ea66 100644
--- a/include/llvm/Function.h
+++ b/include/llvm/Function.h
@@ -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 *
diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h
index ec6ea77060..04bd5fbd7f 100644
--- a/include/llvm/GlobalAlias.h
+++ b/include/llvm/GlobalAlias.h
@@ -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
diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h
index 317aa486a4..014cdbe82a 100644
--- a/include/llvm/GlobalValue.h
+++ b/include/llvm/GlobalValue.h
@@ -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; }
diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h
index 303e57f99a..00d4acb66d 100644
--- a/include/llvm/GlobalVariable.h
+++ b/include/llvm/GlobalVariable.h
@@ -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.
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 14524cb4a5..f2b9fb0d2f 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -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
diff --git a/lib/Bytecode/Reader/Analyzer.cpp b/lib/Bytecode/Reader/Analyzer.cpp
index dde73dfb1a..2d90c93826 100644
--- a/lib/Bytecode/Reader/Analyzer.cpp
+++ b/lib/Bytecode/Reader/Analyzer.cpp
@@ -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;
}
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp
index f7606c6e5a..99aac056ff 100644
--- a/lib/Bytecode/Reader/Reader.cpp
+++ b/lib/Bytecode/Reader/Reader.cpp
@@ -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");
diff --git a/lib/Bytecode/Reader/Reader.h b/lib/Bytecode/Reader/Reader.h
index c852cce6ba..95cf58c2b3 100644
--- a/lib/Bytecode/Reader/Reader.h
+++ b/lib/Bytecode/Reader/Reader.h
@@ -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.
diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp
index 85ccad58c5..3a038cd449 100644
--- a/lib/Bytecode/Writer/SlotCalculator.cpp
+++ b/lib/Bytecode/Writer/SlotCalculator.cpp
@@ -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.
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp
index 7295239fdd..f1c6f6c561 100644
--- a/lib/Bytecode/Writer/Writer.cpp
+++ b/lib/Bytecode/Writer/Writer.cpp
@@ -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));
}
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp
index 90a98cb5a7..f7571831a3 100644
--- a/lib/CodeGen/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter.cpp
@@ -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())
diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp
index 560bcb56b0..90150689cc 100644
--- a/lib/Transforms/IPO/GlobalDCE.cpp
+++ b/lib/Transforms/IPO/GlobalDCE.cpp
@@ -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
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 8834e1e2a2..656a7bed74 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -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";
}
diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp
index c64b719095..88a8c0b2a7 100644
--- a/lib/VMCore/Globals.cpp
+++ b/lib/VMCore/Globals.cpp
@@ -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);
+ }
}
diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp
index c66032388b..e20dab30be 100644
--- a/lib/VMCore/Module.cpp
+++ b/lib/VMCore/Module.cpp
@@ -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) {
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 1578c2ddd6..01eb860f91 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -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);
}
diff --git a/test/Feature/aliases.ll b/test/Feature/aliases.ll
index c099cc9080..fc5e7685ca 100644
--- a/test/Feature/aliases.ll
+++ b/test/Feature/aliases.ll
@@ -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