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
This commit is contained in:
Anton Korobeynikov 2007-04-28 13:45:00 +00:00
parent 44b2c5098f
commit a80e1181b7
20 changed files with 231 additions and 113 deletions

View 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>

View 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>

View 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.

View 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 *

View 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

View 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; }

View 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.

View 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

View 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;
}

View 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");

View 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.

View 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.

View 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));
}

View 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())

View 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

View 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";
}

View 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);
}
}

View 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) {

View 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);
}

View 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