mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-03 11:24:18 +00:00
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:
@ -1212,14 +1212,18 @@ the first <a href="#uint32_vbr">uint32_vbr</a> which describes alias itself.</p>
|
|||||||
linkage, 2 - Weak linkage.</td>
|
linkage, 2 - Weak linkage.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<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>
|
<td class="td_left">Type slot number of type for the alias itself.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p>The next two <a href="#uint32_vbr">uint32_vbr's</a> describes the
|
<p>The next <a href="#uint32_vbr">uint32_vbr</a> describes the aliasee. </p>
|
||||||
aliasee. </p>
|
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<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><b>Type</b></th>
|
||||||
<th class="td_left"><b>Description</b></th>
|
<th class="td_left"><b>Description</b></th>
|
||||||
</tr>
|
</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>
|
<tr>
|
||||||
<td><a href="#uint32_vbr">uint32_vbr</a></td>
|
<td><a href="#uint32_vbr">uint32_vbr</a></td>
|
||||||
<td class="td_left">Slot number of the aliasee.</td>
|
<td class="td_left">Slot number of the aliasee.</td>
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
<li><a href="#callingconv">Calling Conventions</a></li>
|
<li><a href="#callingconv">Calling Conventions</a></li>
|
||||||
<li><a href="#globalvars">Global Variables</a></li>
|
<li><a href="#globalvars">Global Variables</a></li>
|
||||||
<li><a href="#functionstructure">Functions</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="#paramattrs">Parameter Attributes</a></li>
|
||||||
<li><a href="#moduleasm">Module-Level Inline Assembly</a></li>
|
<li><a href="#moduleasm">Module-Level Inline Assembly</a></li>
|
||||||
<li><a href="#datalayout">Data Layout</a></li>
|
<li><a href="#datalayout">Data Layout</a></li>
|
||||||
@ -705,7 +706,7 @@ a power of 2.</p>
|
|||||||
</div>
|
</div>
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
<p>Aliases act as "second name" for the aliasee value (which can be either
|
<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="#linkage">linkage type</a>, and an
|
||||||
optional <a href="#visibility">visibility style</a>.</p>
|
optional <a href="#visibility">visibility style</a>.</p>
|
||||||
|
|
||||||
|
@ -116,6 +116,12 @@ public:
|
|||||||
bool isThreadLocal ///< Whether the GV is thread local or not
|
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
|
/// This method is called when a type list is recognized. It simply
|
||||||
/// provides the number of types that the list contains. The handler
|
/// provides the number of types that the list contains. The handler
|
||||||
/// should expect that number of calls to handleType.
|
/// should expect that number of calls to handleType.
|
||||||
|
@ -81,6 +81,15 @@ private:
|
|||||||
void setNext(Function *N) { Next = N; }
|
void setNext(Function *N) { Next = N; }
|
||||||
void setPrev(Function *N) { Prev = 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:
|
public:
|
||||||
/// Function ctor - If the (optional) Module argument is specified, the
|
/// Function ctor - If the (optional) Module argument is specified, the
|
||||||
/// function is automatically inserted into the end of the function list for
|
/// function is automatically inserted into the end of the function list for
|
||||||
@ -243,15 +252,6 @@ public:
|
|||||||
Function *Obj = 0;
|
Function *Obj = 0;
|
||||||
return unsigned(reinterpret_cast<uintptr_t>(&Obj->ArgumentList));
|
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 *
|
inline ValueSymbolTable *
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//===______-- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===//
|
//===-------- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
@ -8,7 +8,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This file contains the declaration of the GlobalAlias class, which
|
// 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 setNext(GlobalAlias *N) { Next = N; }
|
||||||
void setPrev(GlobalAlias *N) { Prev = N; }
|
void setPrev(GlobalAlias *N) { Prev = N; }
|
||||||
|
|
||||||
const GlobalValue* Aliasee;
|
// getNext/Prev - Return the next or previous alias in the list.
|
||||||
std::string Target;
|
GlobalAlias *getNext() { return Next; }
|
||||||
|
const GlobalAlias *getNext() const { return Next; }
|
||||||
|
GlobalAlias *getPrev() { return Prev; }
|
||||||
|
const GlobalAlias *getPrev() const { return Prev; }
|
||||||
|
|
||||||
|
Use Aliasee;
|
||||||
public:
|
public:
|
||||||
/// GlobalAlias ctor - If a parent module is specified, the alias is
|
/// 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 = "",
|
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,
|
/// isDeclaration - Is this global variable lacking an initializer? If so,
|
||||||
/// the global variable is defined in some other translation unit, and is thus
|
/// 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,
|
/// removeFromParent - This method unlinks 'this' from the containing module,
|
||||||
/// but does not delete it.
|
/// but does not delete it.
|
||||||
///
|
///
|
||||||
virtual void removeFromParent();
|
void removeFromParent();
|
||||||
|
|
||||||
/// eraseFromParent - This method unlinks 'this' from the containing module
|
/// eraseFromParent - This method unlinks 'this' from the containing module
|
||||||
/// and deletes it.
|
/// and deletes it.
|
||||||
///
|
///
|
||||||
virtual void eraseFromParent();
|
void eraseFromParent();
|
||||||
|
|
||||||
virtual void print(std::ostream &OS) const;
|
virtual void print(std::ostream &OS) const;
|
||||||
void print(std::ostream *OS) const { if (OS) print(*OS); }
|
void print(std::ostream *OS) const { if (OS) print(*OS); }
|
||||||
|
|
||||||
void setAliasee(const GlobalValue* GV);
|
/// set/getAliasee - These methods retrive and set alias target.
|
||||||
const GlobalValue* getAliasee() const { return Aliasee; }
|
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:
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||||
static inline bool classof(const GlobalAlias *) { return true; }
|
static inline bool classof(const GlobalAlias *) { return true; }
|
||||||
static inline bool classof(const Value *V) {
|
static inline bool classof(const Value *V) {
|
||||||
return V->getValueID() == Value::GlobalAliasVal;
|
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
|
} // End llvm namespace
|
||||||
|
@ -121,16 +121,6 @@ public:
|
|||||||
/// value is outside of the current translation unit...
|
/// value is outside of the current translation unit...
|
||||||
virtual bool isDeclaration() const = 0;
|
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
|
/// getParent - Get the module that this global value is contained inside
|
||||||
/// of...
|
/// of...
|
||||||
inline Module *getParent() { return Parent; }
|
inline Module *getParent() { return Parent; }
|
||||||
|
@ -107,12 +107,12 @@ public:
|
|||||||
/// removeFromParent - This method unlinks 'this' from the containing module,
|
/// removeFromParent - This method unlinks 'this' from the containing module,
|
||||||
/// but does not delete it.
|
/// but does not delete it.
|
||||||
///
|
///
|
||||||
virtual void removeFromParent();
|
void removeFromParent();
|
||||||
|
|
||||||
/// eraseFromParent - This method unlinks 'this' from the containing module
|
/// eraseFromParent - This method unlinks 'this' from the containing module
|
||||||
/// and deletes it.
|
/// and deletes it.
|
||||||
///
|
///
|
||||||
virtual void eraseFromParent();
|
void eraseFromParent();
|
||||||
|
|
||||||
/// Override Constant's implementation of this method so we can
|
/// Override Constant's implementation of this method so we can
|
||||||
/// replace constant initializers.
|
/// replace constant initializers.
|
||||||
|
@ -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
|
// 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...
|
// 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
|
// Remember where this forward reference came from. FIXME, shouldn't we try
|
||||||
// to recycle these things??
|
// to recycle these things??
|
||||||
CurModule.PlaceHolderInfo.insert(std::make_pair(V, std::make_pair(ID,
|
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 <BasicBlockVal> BasicBlock InstructionList
|
||||||
%type <TermInstVal> BBTerminatorInst
|
%type <TermInstVal> BBTerminatorInst
|
||||||
%type <InstVal> Inst InstVal MemoryInst
|
%type <InstVal> Inst InstVal MemoryInst
|
||||||
%type <ConstVal> ConstVal ConstExpr
|
%type <ConstVal> ConstVal ConstExpr AliaseeRef
|
||||||
%type <ConstVector> ConstVector
|
%type <ConstVector> ConstVector
|
||||||
%type <ArgList> ArgList ArgListH
|
%type <ArgList> ArgList ArgListH
|
||||||
%type <PHIList> PHIList
|
%type <PHIList> PHIList
|
||||||
@ -1943,6 +1959,30 @@ GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; };
|
|||||||
// ThreadLocal
|
// ThreadLocal
|
||||||
ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; };
|
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
|
// Rules to match Modules
|
||||||
@ -2045,34 +2085,20 @@ Definition
|
|||||||
CurGV = 0;
|
CurGV = 0;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| OptGlobalAssign GVVisibilityStyle ALIAS AliasLinkage ResultTypes
|
| OptGlobalAssign GVVisibilityStyle ALIAS AliasLinkage AliaseeRef {
|
||||||
SymbolicValueRef {
|
|
||||||
std::string Name($1);
|
std::string Name($1);
|
||||||
if (Name.empty())
|
if (Name.empty())
|
||||||
GEN_ERROR("Alias name cannot be empty")
|
GEN_ERROR("Alias name cannot be empty");
|
||||||
const PointerType *PFTy = 0;
|
|
||||||
const FunctionType *Ty = 0;
|
Constant* Aliasee = $5;
|
||||||
Value* V = 0;
|
if (Aliasee == 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(std::string("Invalid aliasee for alias: ") + $1);
|
GEN_ERROR(std::string("Invalid aliasee for alias: ") + $1);
|
||||||
if (GlobalValue* Aliasee = dyn_cast<GlobalValue>(V)) {
|
|
||||||
GlobalAlias* GA = new GlobalAlias(VTy, $4, Name, Aliasee,
|
GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), $4, Name, Aliasee,
|
||||||
CurModule.CurrentModule);
|
CurModule.CurrentModule);
|
||||||
GA->setVisibility($2);
|
GA->setVisibility($2);
|
||||||
InsertValue(GA, CurModule.Values);
|
InsertValue(GA, CurModule.Values);
|
||||||
} else
|
|
||||||
GEN_ERROR("Aliases can be created only to global values");
|
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
delete $5;
|
|
||||||
}
|
}
|
||||||
| TARGET TargetDefinition {
|
| TARGET TargetDefinition {
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
|
@ -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) {
|
virtual void handleTypeList(unsigned numEntries) {
|
||||||
bca.maxTypeSlot = numEntries - 1;
|
bca.maxTypeSlot = numEntries - 1;
|
||||||
}
|
}
|
||||||
|
@ -1923,12 +1923,10 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
|||||||
// Read aliases...
|
// Read aliases...
|
||||||
unsigned VarType = read_vbr_uint();
|
unsigned VarType = read_vbr_uint();
|
||||||
while (VarType != Type::VoidTyID) { // List is terminated by Void
|
while (VarType != Type::VoidTyID) { // List is terminated by Void
|
||||||
unsigned TypeSlotNo = VarType >> 2;
|
unsigned TypeSlotNo = VarType >> 3;
|
||||||
unsigned EncodedLinkage = VarType & 3;
|
unsigned EncodedLinkage = VarType & 3;
|
||||||
unsigned AliaseeTypeSlotNo, AliaseeSlotNo;
|
bool isConstantAliasee = (VarType >> 2) & 1;
|
||||||
|
unsigned AliaseeSlotNo = read_vbr_uint();
|
||||||
AliaseeTypeSlotNo = read_vbr_uint();
|
|
||||||
AliaseeSlotNo = read_vbr_uint();
|
|
||||||
|
|
||||||
const Type *Ty = getType(TypeSlotNo);
|
const Type *Ty = getType(TypeSlotNo);
|
||||||
if (!Ty)
|
if (!Ty)
|
||||||
@ -1937,11 +1935,11 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
|||||||
if (!isa<PointerType>(Ty))
|
if (!isa<PointerType>(Ty))
|
||||||
error("Alias not a pointer type! Ty= " + Ty->getDescription());
|
error("Alias not a pointer type! Ty= " + Ty->getDescription());
|
||||||
|
|
||||||
Value* V = getValue(AliaseeTypeSlotNo, AliaseeSlotNo, false);
|
Value* V = getValue(TypeSlotNo, AliaseeSlotNo, false);
|
||||||
if (!V)
|
if (!V && !isConstantAliasee)
|
||||||
error("Invalid aliasee! TypeSlotNo=" + utostr(AliaseeTypeSlotNo) +
|
error("Invalid aliasee! TypeSlotNo=" + utostr(TypeSlotNo) +
|
||||||
" SlotNo=" + utostr(AliaseeSlotNo));
|
" SlotNo=" + utostr(AliaseeSlotNo));
|
||||||
if (!isa<GlobalValue>(V))
|
if (!isConstantAliasee && !isa<GlobalValue>(V))
|
||||||
error("Aliasee is not global value! SlotNo=" + utostr(AliaseeSlotNo));
|
error("Aliasee is not global value! SlotNo=" + utostr(AliaseeSlotNo));
|
||||||
|
|
||||||
GlobalValue::LinkageTypes Linkage;
|
GlobalValue::LinkageTypes Linkage;
|
||||||
@ -1960,8 +1958,14 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GlobalAlias *GA = new GlobalAlias(Ty, Linkage, "",
|
GlobalAlias *GA = new GlobalAlias(Ty, Linkage, "",
|
||||||
dyn_cast<GlobalValue>(V), TheModule);
|
dyn_cast_or_null<Constant>(V),
|
||||||
|
TheModule);
|
||||||
insertValue(GA, TypeSlotNo, ModuleValues);
|
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();
|
VarType = read_vbr_uint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2068,6 +2072,23 @@ void BytecodeReader::ParseModule() {
|
|||||||
error("Cannot find initializer value.");
|
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())
|
if (!ConstantFwdRefs.empty())
|
||||||
error("Use of undefined constants in a module");
|
error("Use of undefined constants in a module");
|
||||||
|
|
||||||
|
@ -129,6 +129,9 @@ public:
|
|||||||
/// them.
|
/// them.
|
||||||
typedef std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitsList;
|
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*.
|
/// This type maps a typeslot/valueslot pair to the corresponding Value*.
|
||||||
/// It is used for dealing with forward references as values are read in.
|
/// It is used for dealing with forward references as values are read in.
|
||||||
/// @brief A map for dealing with forward references of values.
|
/// @brief A map for dealing with forward references of values.
|
||||||
@ -338,6 +341,12 @@ private:
|
|||||||
/// of what we must do.
|
/// of what we must do.
|
||||||
GlobalInitsList GlobalInits;
|
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
|
// 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
|
// information about each function: its begin and end pointer in the buffer
|
||||||
// and its FunctionSlot.
|
// and its FunctionSlot.
|
||||||
|
@ -89,6 +89,12 @@ void SlotCalculator::processModule() {
|
|||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
CreateSlotIfNeeded(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
|
// Add all of the module level constants used as initializers
|
||||||
//
|
//
|
||||||
for (Module::const_global_iterator I = TheModule->global_begin(),
|
for (Module::const_global_iterator I = TheModule->global_begin(),
|
||||||
@ -96,6 +102,13 @@ void SlotCalculator::processModule() {
|
|||||||
if (I->hasInitializer())
|
if (I->hasInitializer())
|
||||||
CreateSlotIfNeeded(I->getInitializer());
|
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
|
// 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
|
// that contain constant strings so that the strings occur at the start of the
|
||||||
// plane, not somewhere in the middle.
|
// plane, not somewhere in the middle.
|
||||||
|
@ -1095,9 +1095,11 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
|
|||||||
// Output aliases
|
// Output aliases
|
||||||
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
|
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
unsigned Slot = Table.getTypeSlot(I->getType());
|
unsigned TypeSlotNo = Table.getTypeSlot(I->getType());
|
||||||
assert(((Slot << 2) >> 2) == Slot && "Slot # too big!");
|
unsigned AliaseeSlotNo = Table.getSlot(I->getAliasee());
|
||||||
|
assert(((TypeSlotNo << 3) >> 3) == TypeSlotNo && "Slot # too big!");
|
||||||
unsigned aliasLinkage = 0;
|
unsigned aliasLinkage = 0;
|
||||||
|
unsigned isConstantAliasee = ((!isa<GlobalValue>(I->getAliasee())) << 2);
|
||||||
switch (I->getLinkage()) {
|
switch (I->getLinkage()) {
|
||||||
case GlobalValue::ExternalLinkage:
|
case GlobalValue::ExternalLinkage:
|
||||||
aliasLinkage = 0;
|
aliasLinkage = 0;
|
||||||
@ -1111,9 +1113,8 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
|
|||||||
default:
|
default:
|
||||||
assert(0 && "Invalid alias linkage");
|
assert(0 && "Invalid alias linkage");
|
||||||
}
|
}
|
||||||
output_vbr((Slot << 2) | aliasLinkage);
|
output_vbr((TypeSlotNo << 3) | isConstantAliasee | aliasLinkage);
|
||||||
output_vbr(Table.getTypeSlot(I->getAliasee()->getType()));
|
output_vbr(AliaseeSlotNo);
|
||||||
output_vbr(Table.getSlot(I->getAliasee()));
|
|
||||||
}
|
}
|
||||||
output_typeid(Table.getTypeSlot(Type::VoidTy));
|
output_typeid(Table.getTypeSlot(Type::VoidTy));
|
||||||
}
|
}
|
||||||
|
@ -123,18 +123,29 @@ bool AsmPrinter::doFinalization(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (TAI->getSetDirective()) {
|
if (TAI->getSetDirective()) {
|
||||||
if (M.alias_size())
|
if (!M.alias_empty())
|
||||||
SwitchToTextSection(TAI->getTextSection());
|
SwitchToTextSection(TAI->getTextSection());
|
||||||
|
|
||||||
O << "\n";
|
O << "\n";
|
||||||
for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
|
for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
|
||||||
I!=E; ++I) {
|
I!=E; ++I) {
|
||||||
const GlobalValue *Aliasee = I->getAliasee();
|
const Constant *Aliasee = dyn_cast_or_null<Constant>(I->getAliasee());
|
||||||
assert(Aliasee && "Aliasee cannot be null!");
|
assert(Aliasee && "Aliasee cannot be null");
|
||||||
std::string Target = Mang->getValueName(Aliasee);
|
|
||||||
std::string Name = Mang->getValueName(I);
|
|
||||||
|
|
||||||
// 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())
|
if (I->hasExternalLinkage())
|
||||||
O << "\t.globl\t" << Name << "\n";
|
O << "\t.globl\t" << Name << "\n";
|
||||||
else if (I->hasWeakLinkage())
|
else if (I->hasWeakLinkage())
|
||||||
|
@ -75,9 +75,8 @@ bool GlobalDCE::runOnModule(Module &M) {
|
|||||||
|
|
||||||
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
|
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
Changed |= RemoveUnusedGlobalValue(*I);
|
|
||||||
// Aliases are always needed even if they are not used.
|
// 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
|
// 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.
|
// referenced by the initializer to the alive set.
|
||||||
if (GV->hasInitializer())
|
if (GV->hasInitializer())
|
||||||
MarkUsedGlobalsAsNeeded(GV->getInitializer());
|
MarkUsedGlobalsAsNeeded(GV->getInitializer());
|
||||||
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(G)) {
|
} else if (!isa<GlobalAlias>(G)) {
|
||||||
// If this is a global alias we also need it's aliasee
|
|
||||||
GlobalIsNeeded(const_cast<GlobalValue*>(GA->getAliasee()));
|
|
||||||
} else {
|
|
||||||
// Otherwise this must be a function object. We have to scan the body of
|
// 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
|
// the function looking for constants and global values which are used as
|
||||||
// operands. Any operands of these types must be processed to ensure that
|
// operands. Any operands of these types must be processed to ensure that
|
||||||
|
@ -926,7 +926,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
|
|||||||
assert(0 && "Invalid alias linkage");
|
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");
|
assert(Aliasee && "Aliasee cannot be null");
|
||||||
|
|
||||||
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
|
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
|
||||||
@ -940,9 +940,15 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
|
|||||||
Out << getLLVMName(F->getName(), GlobalPrefix);
|
Out << getLLVMName(F->getName(), GlobalPrefix);
|
||||||
else
|
else
|
||||||
Out << "@\"\"";
|
Out << "@\"\"";
|
||||||
} else
|
} else {
|
||||||
assert(0 && "Unsupported aliasee");
|
const ConstantExpr *CE = 0;
|
||||||
|
if ((CE = dyn_cast<ConstantExpr>(Aliasee)) &&
|
||||||
|
(CE->getOpcode() == Instruction::BitCast)) {
|
||||||
|
writeOperand(CE, false);
|
||||||
|
} else
|
||||||
|
assert(0 && "Unsupported aliasee");
|
||||||
|
}
|
||||||
|
|
||||||
printInfoComment(*GA);
|
printInfoComment(*GA);
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
}
|
}
|
||||||
|
@ -163,12 +163,15 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
|
GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
|
||||||
const std::string &Name, const GlobalValue* aliasee,
|
const std::string &Name, Constant* aliasee,
|
||||||
Module *ParentModule)
|
Module *ParentModule)
|
||||||
: GlobalValue(Ty, Value::GlobalAliasVal, 0, 0,
|
: GlobalValue(Ty, Value::GlobalAliasVal, &Aliasee, 1, Link, Name) {
|
||||||
Link, Name), Aliasee(aliasee) {
|
|
||||||
LeakDetector::addGarbageObject(this);
|
LeakDetector::addGarbageObject(this);
|
||||||
|
|
||||||
|
if (aliasee)
|
||||||
|
assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
|
||||||
|
Aliasee.init(aliasee, this);
|
||||||
|
|
||||||
if (ParentModule)
|
if (ParentModule)
|
||||||
ParentModule->getAliasList().push_back(this);
|
ParentModule->getAliasList().push_back(this);
|
||||||
}
|
}
|
||||||
@ -190,12 +193,16 @@ void GlobalAlias::eraseFromParent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GlobalAlias::isDeclaration() const {
|
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?
|
if (Aliasee) {
|
||||||
Aliasee = GV;
|
assert(Aliasee->getType() == getType() &&
|
||||||
|
"Alias and aliasee types should match!");
|
||||||
|
setOperand(0, Aliasee);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,6 +298,9 @@ void Module::dropAllReferences() {
|
|||||||
|
|
||||||
for(Module::global_iterator I = global_begin(), E = global_end(); I != E; ++I)
|
for(Module::global_iterator I = global_begin(), E = global_end(); I != E; ++I)
|
||||||
I->dropAllReferences();
|
I->dropAllReferences();
|
||||||
|
|
||||||
|
for(Module::alias_iterator I = alias_begin(), E = alias_end(); I != E; ++I)
|
||||||
|
I->dropAllReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::addLibrary(const std::string& Lib) {
|
void Module::addLibrary(const std::string& Lib) {
|
||||||
|
@ -316,7 +316,9 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) {
|
|||||||
Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() ||
|
Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() ||
|
||||||
GA.hasWeakLinkage(),
|
GA.hasWeakLinkage(),
|
||||||
"Alias should have external or external weak linkage!", &GA);
|
"Alias should have external or external weak linkage!", &GA);
|
||||||
|
Assert1(GA.getType() == GA.getAliasee()->getType(),
|
||||||
|
"Alias and aliasee types should match!", &GA);
|
||||||
|
|
||||||
visitGlobalValue(GA);
|
visitGlobalValue(GA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
|
; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
|
||||||
; RUN: diff %t1.ll %t2.ll
|
; RUN: diff %t1.ll %t2.ll
|
||||||
|
|
||||||
; XFAIL: *
|
|
||||||
|
|
||||||
@bar = external global i32
|
@bar = external global i32
|
||||||
@foo1 = alias i32* @bar
|
@foo1 = alias i32* @bar
|
||||||
@foo2 = alias i32* @bar
|
@foo2 = alias i32* @bar
|
||||||
@ -15,6 +13,8 @@ declare i32 @foo_f()
|
|||||||
|
|
||||||
@bar_i = alias internal i32* @bar
|
@bar_i = alias internal i32* @bar
|
||||||
|
|
||||||
|
@A = alias bitcast (i32* @bar to i64*)
|
||||||
|
|
||||||
define i32 @test() {
|
define i32 @test() {
|
||||||
entry:
|
entry:
|
||||||
%tmp = load i32* @foo1
|
%tmp = load i32* @foo1
|
||||||
|
Reference in New Issue
Block a user