mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 14:10:41 +00:00
Implement aliases. This fixes PR1017 and it's dependent bugs. CFE part
will follow. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36435 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
24a3cc4c83
commit
8b0a8c84da
@ -943,11 +943,11 @@ all functions. The format is shown in the table below:</p>
|
|||||||
target triple specified, i.e. a platform-independent module).</td>
|
target triple specified, i.e. a platform-independent module).</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="#string">string</a></td>
|
<td><a href="#string">string</a></td>
|
||||||
<td class="td_left">The data layout string describing the endianness,
|
<td class="td_left">The data layout string describing the endianness,
|
||||||
pointer size, and type alignments for which the module was written
|
pointer size, and type alignments for which the module was written
|
||||||
(blank means no data layout specified, i.e. a platform-independent
|
(blank means no data layout specified, i.e. a platform-independent
|
||||||
module).</td>
|
module).</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="#llist">llist</a>(<a href="#string">string</a>)</td>
|
<td><a href="#llist">llist</a>(<a href="#string">string</a>)</td>
|
||||||
@ -959,6 +959,11 @@ all functions. The format is shown in the table below:</p>
|
|||||||
<td><a href="#string">string</a></td>
|
<td><a href="#string">string</a></td>
|
||||||
<td class="td_left">The inline asm block for this module.</td>
|
<td class="td_left">The inline asm block for this module.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="#zlist">zlist</a>(<a href="#alias">alias</a>)</td>
|
||||||
|
<td class="td_left">A zero terminated list of aliases occurring in the
|
||||||
|
module.</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -1123,7 +1128,7 @@ href="#uint32_vbr">uint32_vbr</a> that describes the function.</p>
|
|||||||
<td><a href="#bit">bit(5-30)</a></td>
|
<td><a href="#bit">bit(5-30)</a></td>
|
||||||
<td class="td_left">Type slot number of type for the function.</td>
|
<td class="td_left">Type slot number of type for the function.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="#bit">bit(31)</a></td>
|
<td><a href="#bit">bit(31)</a></td>
|
||||||
<td class="td_left">Indicates whether an extension word follows.</td>
|
<td class="td_left">Indicates whether an extension word follows.</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -1185,6 +1190,56 @@ follows with the following fields:</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- _______________________________________________________________________ -->
|
||||||
|
<div class="doc_subsubsection"><a name="alias">Alias Field</a>
|
||||||
|
</div>
|
||||||
|
<div class="doc_text">
|
||||||
|
<p>Aliases are written using 3 <a href="#uint32_vbr">uint32_vbr</a>
|
||||||
|
that encode information about alias itself and aliasee.</p>
|
||||||
|
|
||||||
|
<p>The table below provides the bit layout of
|
||||||
|
the first <a href="#uint32_vbr">uint32_vbr</a> which describes alias itself.</p>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th><b>Type</b></th>
|
||||||
|
<th class="td_left"><b>Description</b></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="#bit">bit(0-1)</a></td>
|
||||||
|
<td class="td_left">Alias linkage. 0 - External linkage, 1 - Internal
|
||||||
|
linkage, 2 - Weak linkage.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="#bit">bit(2-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>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- _______________________________________________________________________ -->
|
<!-- _______________________________________________________________________ -->
|
||||||
<div class="doc_subsection"><a name="constantpool">Constant Pool</a> </div>
|
<div class="doc_subsection"><a name="constantpool">Constant Pool</a> </div>
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
|
@ -498,7 +498,8 @@ outside of the current module.</p>
|
|||||||
<p>It is illegal for a function <i>declaration</i>
|
<p>It is illegal for a function <i>declaration</i>
|
||||||
to have any linkage type other than "externally visible", <tt>dllimport</tt>,
|
to have any linkage type other than "externally visible", <tt>dllimport</tt>,
|
||||||
or <tt>extern_weak</tt>.</p>
|
or <tt>extern_weak</tt>.</p>
|
||||||
|
<p>Aliases can have only <tt>external</tt>, <tt>internal</tt> and <tt>weak</tt>
|
||||||
|
linkages.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ======================================================================= -->
|
<!-- ======================================================================= -->
|
||||||
@ -602,12 +603,11 @@ All Global Variables and Functions have one of the following visibility styles:
|
|||||||
|
|
||||||
<p>Global variables define regions of memory allocated at compilation time
|
<p>Global variables define regions of memory allocated at compilation time
|
||||||
instead of run-time. Global variables may optionally be initialized, may have
|
instead of run-time. Global variables may optionally be initialized, may have
|
||||||
an explicit section to be placed in, and may
|
an explicit section to be placed in, and may have an optional explicit alignment
|
||||||
have an optional explicit alignment specified. A variable may be defined as
|
specified. A variable may be defined as "thread_local", which means that it
|
||||||
"thread_local", which means that it will not be shared by threads (each thread
|
will not be shared by threads (each thread will have a separated copy of the
|
||||||
will have a separated copy of the variable).
|
variable). A variable may be defined as a global "constant," which indicates
|
||||||
A variable may be defined as a global "constant," which indicates that the
|
that the contents of the variable will <b>never</b> be modified (enabling better
|
||||||
contents of the variable will <b>never</b> be modified (enabling better
|
|
||||||
optimization, allowing the global data to be placed in the read-only section of
|
optimization, allowing the global data to be placed in the read-only section of
|
||||||
an executable, etc). Note that variables that need runtime initialization
|
an executable, etc). Note that variables that need runtime initialization
|
||||||
cannot be marked "constant" as there is a store to the variable.</p>
|
cannot be marked "constant" as there is a store to the variable.</p>
|
||||||
@ -698,6 +698,27 @@ a power of 2.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ======================================================================= -->
|
||||||
|
<div class="doc_subsection">
|
||||||
|
<a name="aliasstructure">Aliases</a>
|
||||||
|
</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
|
||||||
|
optional <a href="#linkage">linkage type</a>, and an
|
||||||
|
optional <a href="#visibility">visibility style</a>.</p>
|
||||||
|
|
||||||
|
<h5>Syntax:</h5>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
@<Name> = [Linkage] [Visibility] alias <AliaseeTy> @<Aliasee>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ======================================================================= -->
|
<!-- ======================================================================= -->
|
||||||
<div class="doc_subsection"><a name="paramattrs">Parameter Attributes</a></div>
|
<div class="doc_subsection"><a name="paramattrs">Parameter Attributes</a></div>
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
|
@ -24,6 +24,7 @@ namespace llvm {
|
|||||||
class Constant;
|
class Constant;
|
||||||
class ConstantArray;
|
class ConstantArray;
|
||||||
class GlobalVariable;
|
class GlobalVariable;
|
||||||
|
class GlobalAlias;
|
||||||
class MachineConstantPoolEntry;
|
class MachineConstantPoolEntry;
|
||||||
class MachineConstantPoolValue;
|
class MachineConstantPoolValue;
|
||||||
class Mangler;
|
class Mangler;
|
||||||
|
@ -141,12 +141,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.
|
||||||
///
|
///
|
||||||
void removeFromParent();
|
virtual 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.
|
||||||
///
|
///
|
||||||
void eraseFromParent();
|
virtual void eraseFromParent();
|
||||||
|
|
||||||
|
|
||||||
/// Get the underlying elements of the Function... the basic block list is
|
/// Get the underlying elements of the Function... the basic block list is
|
||||||
|
@ -121,6 +121,16 @@ 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; }
|
||||||
@ -136,7 +146,8 @@ public:
|
|||||||
static inline bool classof(const GlobalValue *) { return true; }
|
static inline bool classof(const GlobalValue *) { return true; }
|
||||||
static inline bool classof(const Value *V) {
|
static inline bool classof(const Value *V) {
|
||||||
return V->getValueID() == Value::FunctionVal ||
|
return V->getValueID() == Value::FunctionVal ||
|
||||||
V->getValueID() == Value::GlobalVariableVal;
|
V->getValueID() == Value::GlobalVariableVal ||
|
||||||
|
V->getValueID() == Value::GlobalAliasVal;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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.
|
||||||
///
|
///
|
||||||
void removeFromParent();
|
virtual 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.
|
||||||
///
|
///
|
||||||
void eraseFromParent();
|
virtual 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.
|
||||||
|
@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
|
#include "llvm/GlobalAlias.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class GlobalVariable;
|
|
||||||
class GlobalValueRefMap; // Used by ConstantVals.cpp
|
class GlobalValueRefMap; // Used by ConstantVals.cpp
|
||||||
class FunctionType;
|
class FunctionType;
|
||||||
|
|
||||||
@ -43,6 +43,15 @@ template<> struct ilist_traits<GlobalVariable>
|
|||||||
static inline ValueSymbolTable *getSymTab(Module *M);
|
static inline ValueSymbolTable *getSymTab(Module *M);
|
||||||
static int getListOffset();
|
static int getListOffset();
|
||||||
};
|
};
|
||||||
|
template<> struct ilist_traits<GlobalAlias>
|
||||||
|
: public SymbolTableListTraits<GlobalAlias, Module> {
|
||||||
|
// createSentinel is used to create a node that marks the end of the list.
|
||||||
|
static GlobalAlias *createSentinel();
|
||||||
|
static void destroySentinel(GlobalAlias *GA) { delete GA; }
|
||||||
|
static iplist<GlobalAlias> &getList(Module *M);
|
||||||
|
static inline ValueSymbolTable *getSymTab(Module *M);
|
||||||
|
static int getListOffset();
|
||||||
|
};
|
||||||
|
|
||||||
/// A Module instance is used to store all the information related to an
|
/// A Module instance is used to store all the information related to an
|
||||||
/// LLVM module. Modules are the top level container of all other LLVM
|
/// LLVM module. Modules are the top level container of all other LLVM
|
||||||
@ -63,6 +72,8 @@ public:
|
|||||||
typedef iplist<GlobalVariable> GlobalListType;
|
typedef iplist<GlobalVariable> GlobalListType;
|
||||||
/// The type for the list of functions.
|
/// The type for the list of functions.
|
||||||
typedef iplist<Function> FunctionListType;
|
typedef iplist<Function> FunctionListType;
|
||||||
|
/// The type for the list of aliases.
|
||||||
|
typedef iplist<GlobalAlias> AliasListType;
|
||||||
|
|
||||||
/// The type for the list of dependent libraries.
|
/// The type for the list of dependent libraries.
|
||||||
typedef std::vector<std::string> LibraryListType;
|
typedef std::vector<std::string> LibraryListType;
|
||||||
@ -77,6 +88,11 @@ public:
|
|||||||
/// The Function constant iterator
|
/// The Function constant iterator
|
||||||
typedef FunctionListType::const_iterator const_iterator;
|
typedef FunctionListType::const_iterator const_iterator;
|
||||||
|
|
||||||
|
/// The Global Alias iterators.
|
||||||
|
typedef AliasListType::iterator alias_iterator;
|
||||||
|
/// The Global Alias constant iterator
|
||||||
|
typedef AliasListType::const_iterator const_alias_iterator;
|
||||||
|
|
||||||
/// The Library list iterator.
|
/// The Library list iterator.
|
||||||
typedef LibraryListType::const_iterator lib_iterator;
|
typedef LibraryListType::const_iterator lib_iterator;
|
||||||
|
|
||||||
@ -92,6 +108,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
GlobalListType GlobalList; ///< The Global Variables in the module
|
GlobalListType GlobalList; ///< The Global Variables in the module
|
||||||
FunctionListType FunctionList; ///< The Functions in the module
|
FunctionListType FunctionList; ///< The Functions in the module
|
||||||
|
AliasListType AliasList; ///< The Aliases in the module
|
||||||
LibraryListType LibraryList; ///< The Libraries needed by the module
|
LibraryListType LibraryList; ///< The Libraries needed by the module
|
||||||
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
|
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
|
||||||
ValueSymbolTable *ValSymTab; ///< Symbol table for values
|
ValueSymbolTable *ValSymTab; ///< Symbol table for values
|
||||||
@ -175,10 +192,10 @@ public:
|
|||||||
/// getOrInsertFunction - Look up the specified function in the module symbol
|
/// getOrInsertFunction - Look up the specified function in the module symbol
|
||||||
/// table. If it does not exist, add a prototype for the function and return
|
/// table. If it does not exist, add a prototype for the function and return
|
||||||
/// it. This function guarantees to return a constant of pointer to the
|
/// it. This function guarantees to return a constant of pointer to the
|
||||||
/// specified function type or a ConstantExpr BitCast of that type if the
|
/// specified function type or a ConstantExpr BitCast of that type if the
|
||||||
/// named /// function has a different type. This version of the method
|
/// named function has a different type. This version of the method takes a
|
||||||
/// takes a null terminated list of function arguments, which makes it
|
/// null terminated list of function arguments, which makes it easier for
|
||||||
/// easier for clients to use.
|
/// clients to use.
|
||||||
Constant *getOrInsertFunction(const std::string &Name, const Type *RetTy,...)
|
Constant *getOrInsertFunction(const std::string &Name, const Type *RetTy,...)
|
||||||
END_WITH_NULL;
|
END_WITH_NULL;
|
||||||
|
|
||||||
@ -205,6 +222,15 @@ public:
|
|||||||
GlobalVariable *getNamedGlobal(const std::string &Name) const {
|
GlobalVariable *getNamedGlobal(const std::string &Name) const {
|
||||||
return getGlobalVariable(Name, true);
|
return getGlobalVariable(Name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
/// @name Global Variable Accessors
|
||||||
|
/// @{
|
||||||
|
public:
|
||||||
|
/// getNamedGlobal - Return the first global alias in the module with the
|
||||||
|
/// specified name, of arbitrary type. This method returns null if a global
|
||||||
|
/// with the specified name is not found.
|
||||||
|
GlobalAlias *getNamedAlias(const std::string &Name) const;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Type Accessors
|
/// @name Type Accessors
|
||||||
@ -235,14 +261,18 @@ public:
|
|||||||
const FunctionListType &getFunctionList() const { return FunctionList; }
|
const FunctionListType &getFunctionList() const { return FunctionList; }
|
||||||
/// Get the Module's list of functions.
|
/// Get the Module's list of functions.
|
||||||
FunctionListType &getFunctionList() { return FunctionList; }
|
FunctionListType &getFunctionList() { return FunctionList; }
|
||||||
|
/// Get the Module's list of aliases (constant).
|
||||||
|
const AliasListType &getAliasList() const { return AliasList; }
|
||||||
|
/// Get the Module's list of aliases.
|
||||||
|
AliasListType &getAliasList() { return AliasList; }
|
||||||
/// Get the symbol table of global variable and function identifiers
|
/// Get the symbol table of global variable and function identifiers
|
||||||
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
|
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
|
||||||
/// Get the Module's symbol table of global variable and function identifiers.
|
/// Get the Module's symbol table of global variable and function identifiers.
|
||||||
ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; }
|
ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; }
|
||||||
/// Get the symbol table of types
|
/// Get the symbol table of types
|
||||||
const TypeSymbolTable &getTypeSymbolTable() const { return *TypeSymTab; }
|
const TypeSymbolTable &getTypeSymbolTable() const { return *TypeSymTab; }
|
||||||
/// Get the Module's symbol table of types
|
/// Get the Module's symbol table of types
|
||||||
TypeSymbolTable &getTypeSymbolTable() { return *TypeSymTab; }
|
TypeSymbolTable &getTypeSymbolTable() { return *TypeSymTab; }
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Global Variable Iteration
|
/// @name Global Variable Iteration
|
||||||
@ -272,7 +302,7 @@ public:
|
|||||||
/// Get a constant iterator to the last function.
|
/// Get a constant iterator to the last function.
|
||||||
const_iterator end () const { return FunctionList.end(); }
|
const_iterator end () const { return FunctionList.end(); }
|
||||||
/// Determine how many functions are in the Module's list of functions.
|
/// Determine how many functions are in the Module's list of functions.
|
||||||
size_t size() const { return FunctionList.size(); }
|
size_t size() const { return FunctionList.size(); }
|
||||||
/// Determine if the list of functions is empty.
|
/// Determine if the list of functions is empty.
|
||||||
bool empty() const { return FunctionList.empty(); }
|
bool empty() const { return FunctionList.empty(); }
|
||||||
|
|
||||||
@ -283,9 +313,9 @@ public:
|
|||||||
/// @brief Get a constant iterator to beginning of dependent library list.
|
/// @brief Get a constant iterator to beginning of dependent library list.
|
||||||
inline lib_iterator lib_begin() const { return LibraryList.begin(); }
|
inline lib_iterator lib_begin() const { return LibraryList.begin(); }
|
||||||
/// @brief Get a constant iterator to end of dependent library list.
|
/// @brief Get a constant iterator to end of dependent library list.
|
||||||
inline lib_iterator lib_end() const { return LibraryList.end(); }
|
inline lib_iterator lib_end() const { return LibraryList.end(); }
|
||||||
/// @brief Returns the number of items in the list of libraries.
|
/// @brief Returns the number of items in the list of libraries.
|
||||||
inline size_t lib_size() const { return LibraryList.size(); }
|
inline size_t lib_size() const { return LibraryList.size(); }
|
||||||
/// @brief Add a library to the list of dependent libraries
|
/// @brief Add a library to the list of dependent libraries
|
||||||
void addLibrary(const std::string& Lib);
|
void addLibrary(const std::string& Lib);
|
||||||
/// @brief Remove a library from the list of dependent libraries
|
/// @brief Remove a library from the list of dependent libraries
|
||||||
@ -293,6 +323,23 @@ public:
|
|||||||
/// @brief Get all the libraries
|
/// @brief Get all the libraries
|
||||||
inline const LibraryListType& getLibraries() const { return LibraryList; }
|
inline const LibraryListType& getLibraries() const { return LibraryList; }
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
/// @name Alias Iteration
|
||||||
|
/// @{
|
||||||
|
public:
|
||||||
|
/// Get an iterator to the first alias.
|
||||||
|
alias_iterator alias_begin() { return AliasList.begin(); }
|
||||||
|
/// Get a constant iterator to the first alias.
|
||||||
|
const_alias_iterator alias_begin() const { return AliasList.begin(); }
|
||||||
|
/// Get an iterator to the last alias.
|
||||||
|
alias_iterator alias_end () { return AliasList.end(); }
|
||||||
|
/// Get a constant iterator to the last alias.
|
||||||
|
const_alias_iterator alias_end () const { return AliasList.end(); }
|
||||||
|
/// Determine how many functions are in the Module's list of aliases.
|
||||||
|
size_t alias_size () const { return AliasList.size(); }
|
||||||
|
/// Determine if the list of aliases is empty.
|
||||||
|
bool alias_empty() const { return AliasList.empty(); }
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Utility functions for printing and dumping Module objects
|
/// @name Utility functions for printing and dumping Module objects
|
||||||
/// @{
|
/// @{
|
||||||
@ -324,6 +371,10 @@ public:
|
|||||||
Module *Obj = 0;
|
Module *Obj = 0;
|
||||||
return unsigned(reinterpret_cast<uintptr_t>(&Obj->GlobalList));
|
return unsigned(reinterpret_cast<uintptr_t>(&Obj->GlobalList));
|
||||||
}
|
}
|
||||||
|
static unsigned getAliasListOffset() {
|
||||||
|
Module *Obj = 0;
|
||||||
|
return unsigned(reinterpret_cast<uintptr_t>(&Obj->AliasList));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An iostream inserter for modules.
|
/// An iostream inserter for modules.
|
||||||
@ -342,6 +393,11 @@ ilist_traits<GlobalVariable>::getSymTab(Module *M) {
|
|||||||
return M ? &M->getValueSymbolTable() : 0;
|
return M ? &M->getValueSymbolTable() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ValueSymbolTable *
|
||||||
|
ilist_traits<GlobalAlias>::getSymTab(Module *M) {
|
||||||
|
return M ? &M->getValueSymbolTable() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
ilist_traits<Function>::getListOffset() {
|
ilist_traits<Function>::getListOffset() {
|
||||||
return Module::getFunctionListOffset();
|
return Module::getFunctionListOffset();
|
||||||
@ -352,6 +408,11 @@ ilist_traits<GlobalVariable>::getListOffset() {
|
|||||||
return Module::getGlobalVariableListOffset();
|
return Module::getGlobalVariableListOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
ilist_traits<GlobalAlias>::getListOffset() {
|
||||||
|
return Module::getAliasListOffset();
|
||||||
|
}
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -30,6 +30,7 @@ class BasicBlock;
|
|||||||
class GlobalValue;
|
class GlobalValue;
|
||||||
class Function;
|
class Function;
|
||||||
class GlobalVariable;
|
class GlobalVariable;
|
||||||
|
class GlobalAlias;
|
||||||
class InlineAsm;
|
class InlineAsm;
|
||||||
class ValueSymbolTable;
|
class ValueSymbolTable;
|
||||||
class TypeSymbolTable;
|
class TypeSymbolTable;
|
||||||
@ -160,6 +161,7 @@ public:
|
|||||||
ArgumentVal, // This is an instance of Argument
|
ArgumentVal, // This is an instance of Argument
|
||||||
BasicBlockVal, // This is an instance of BasicBlock
|
BasicBlockVal, // This is an instance of BasicBlock
|
||||||
FunctionVal, // This is an instance of Function
|
FunctionVal, // This is an instance of Function
|
||||||
|
GlobalAliasVal, // This is an instance of GlobalAlias
|
||||||
GlobalVariableVal, // This is an instance of GlobalVariable
|
GlobalVariableVal, // This is an instance of GlobalVariable
|
||||||
UndefValueVal, // This is an instance of UndefValue
|
UndefValueVal, // This is an instance of UndefValue
|
||||||
ConstantExprVal, // This is an instance of ConstantExpr
|
ConstantExprVal, // This is an instance of ConstantExpr
|
||||||
@ -248,8 +250,11 @@ template <> inline bool isa_impl<Function, Value>(const Value &Val) {
|
|||||||
template <> inline bool isa_impl<GlobalVariable, Value>(const Value &Val) {
|
template <> inline bool isa_impl<GlobalVariable, Value>(const Value &Val) {
|
||||||
return Val.getValueID() == Value::GlobalVariableVal;
|
return Val.getValueID() == Value::GlobalVariableVal;
|
||||||
}
|
}
|
||||||
|
template <> inline bool isa_impl<GlobalAlias, Value>(const Value &Val) {
|
||||||
|
return Val.getValueID() == Value::GlobalAliasVal;
|
||||||
|
}
|
||||||
template <> inline bool isa_impl<GlobalValue, Value>(const Value &Val) {
|
template <> inline bool isa_impl<GlobalValue, Value>(const Value &Val) {
|
||||||
return isa<GlobalVariable>(Val) || isa<Function>(Val);
|
return isa<GlobalVariable>(Val) || isa<Function>(Val) || isa<GlobalAlias>(Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
@ -35,6 +35,7 @@ class ValueSymbolTable {
|
|||||||
friend class SymbolTableListTraits<Instruction, BasicBlock>;
|
friend class SymbolTableListTraits<Instruction, BasicBlock>;
|
||||||
friend class SymbolTableListTraits<Function, Module>;
|
friend class SymbolTableListTraits<Function, Module>;
|
||||||
friend class SymbolTableListTraits<GlobalVariable, Module>;
|
friend class SymbolTableListTraits<GlobalVariable, Module>;
|
||||||
|
friend class SymbolTableListTraits<GlobalAlias, Module>;
|
||||||
/// @name Types
|
/// @name Types
|
||||||
/// @{
|
/// @{
|
||||||
public:
|
public:
|
||||||
|
@ -222,6 +222,7 @@ datalayout { return DATALAYOUT; }
|
|||||||
volatile { return VOLATILE; }
|
volatile { return VOLATILE; }
|
||||||
align { return ALIGN; }
|
align { return ALIGN; }
|
||||||
section { return SECTION; }
|
section { return SECTION; }
|
||||||
|
alias { return ALIAS; }
|
||||||
module { return MODULE; }
|
module { return MODULE; }
|
||||||
asm { return ASM_TOK; }
|
asm { return ASM_TOK; }
|
||||||
sideeffect { return SIDEEFFECT; }
|
sideeffect { return SIDEEFFECT; }
|
||||||
|
@ -1004,6 +1004,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
|||||||
%type <BoolVal> OptSideEffect // 'sideeffect' or not.
|
%type <BoolVal> OptSideEffect // 'sideeffect' or not.
|
||||||
%type <Linkage> GVInternalLinkage GVExternalLinkage
|
%type <Linkage> GVInternalLinkage GVExternalLinkage
|
||||||
%type <Linkage> FunctionDefineLinkage FunctionDeclareLinkage
|
%type <Linkage> FunctionDefineLinkage FunctionDeclareLinkage
|
||||||
|
%type <Linkage> AliasLinkage
|
||||||
%type <Visibility> GVVisibilityStyle
|
%type <Visibility> GVVisibilityStyle
|
||||||
|
|
||||||
// ValueRef - Unresolved reference to a definition or BB
|
// ValueRef - Unresolved reference to a definition or BB
|
||||||
@ -1035,12 +1036,12 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
|||||||
|
|
||||||
%token<StrVal> LOCALVAR GLOBALVAR LABELSTR STRINGCONSTANT ATSTRINGCONSTANT
|
%token<StrVal> LOCALVAR GLOBALVAR LABELSTR STRINGCONSTANT ATSTRINGCONSTANT
|
||||||
%type <StrVal> LocalName OptLocalName OptLocalAssign
|
%type <StrVal> LocalName OptLocalName OptLocalAssign
|
||||||
%type <StrVal> GlobalName OptGlobalAssign
|
%type <StrVal> GlobalName OptGlobalAssign GlobalAssign
|
||||||
%type <UIntVal> OptAlign OptCAlign
|
%type <UIntVal> OptAlign OptCAlign
|
||||||
%type <StrVal> OptSection SectionString
|
%type <StrVal> OptSection SectionString
|
||||||
|
|
||||||
%token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
|
%token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
|
||||||
%token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE THREAD_LOCAL
|
%token DECLARE DEFINE GLOBAL CONSTANT SECTION ALIAS VOLATILE THREAD_LOCAL
|
||||||
%token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING
|
%token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING
|
||||||
%token DLLIMPORT DLLEXPORT EXTERN_WEAK
|
%token DLLIMPORT DLLEXPORT EXTERN_WEAK
|
||||||
%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN
|
%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN
|
||||||
@ -1136,15 +1137,17 @@ OptLocalAssign : LocalName '=' {
|
|||||||
|
|
||||||
GlobalName : GLOBALVAR | ATSTRINGCONSTANT;
|
GlobalName : GLOBALVAR | ATSTRINGCONSTANT;
|
||||||
|
|
||||||
OptGlobalAssign : GlobalName '=' {
|
OptGlobalAssign : GlobalAssign
|
||||||
$$ = $1;
|
|
||||||
CHECK_FOR_ERROR
|
|
||||||
}
|
|
||||||
| /*empty*/ {
|
| /*empty*/ {
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GlobalAssign : GlobalName '=' {
|
||||||
|
$$ = $1;
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
}
|
||||||
|
|
||||||
GVInternalLinkage
|
GVInternalLinkage
|
||||||
: INTERNAL { $$ = GlobalValue::InternalLinkage; }
|
: INTERNAL { $$ = GlobalValue::InternalLinkage; }
|
||||||
| WEAK { $$ = GlobalValue::WeakLinkage; }
|
| WEAK { $$ = GlobalValue::WeakLinkage; }
|
||||||
@ -1161,6 +1164,7 @@ GVExternalLinkage
|
|||||||
|
|
||||||
GVVisibilityStyle
|
GVVisibilityStyle
|
||||||
: /*empty*/ { $$ = GlobalValue::DefaultVisibility; }
|
: /*empty*/ { $$ = GlobalValue::DefaultVisibility; }
|
||||||
|
| DEFAULT { $$ = GlobalValue::DefaultVisibility; }
|
||||||
| HIDDEN { $$ = GlobalValue::HiddenVisibility; }
|
| HIDDEN { $$ = GlobalValue::HiddenVisibility; }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -1170,7 +1174,7 @@ FunctionDeclareLinkage
|
|||||||
| EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
|
| EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
|
||||||
;
|
;
|
||||||
|
|
||||||
FunctionDefineLinkage
|
FunctionDefineLinkage
|
||||||
: /*empty*/ { $$ = GlobalValue::ExternalLinkage; }
|
: /*empty*/ { $$ = GlobalValue::ExternalLinkage; }
|
||||||
| INTERNAL { $$ = GlobalValue::InternalLinkage; }
|
| INTERNAL { $$ = GlobalValue::InternalLinkage; }
|
||||||
| LINKONCE { $$ = GlobalValue::LinkOnceLinkage; }
|
| LINKONCE { $$ = GlobalValue::LinkOnceLinkage; }
|
||||||
@ -1178,6 +1182,12 @@ FunctionDefineLinkage
|
|||||||
| DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; }
|
| DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
AliasLinkage
|
||||||
|
: /*empty*/ { $$ = GlobalValue::ExternalLinkage; }
|
||||||
|
| WEAK { $$ = GlobalValue::WeakLinkage; }
|
||||||
|
| INTERNAL { $$ = GlobalValue::InternalLinkage; }
|
||||||
|
;
|
||||||
|
|
||||||
OptCallingConv : /*empty*/ { $$ = CallingConv::C; } |
|
OptCallingConv : /*empty*/ { $$ = CallingConv::C; } |
|
||||||
CCC_TOK { $$ = CallingConv::C; } |
|
CCC_TOK { $$ = CallingConv::C; } |
|
||||||
FASTCC_TOK { $$ = CallingConv::Fast; } |
|
FASTCC_TOK { $$ = CallingConv::Fast; } |
|
||||||
@ -2031,6 +2041,34 @@ Definition
|
|||||||
CurGV = 0;
|
CurGV = 0;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
|
| OptGlobalAssign GVVisibilityStyle ALIAS AliasLinkage ResultTypes SymbolicValueRef {
|
||||||
|
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(std::string("Invalid aliasee for alias: ") + $1);
|
||||||
|
GlobalValue* Aliasee;
|
||||||
|
if (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");
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
delete $5;
|
||||||
|
}
|
||||||
| TARGET TargetDefinition {
|
| TARGET TargetDefinition {
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
|
@ -348,7 +348,7 @@ Constant* BytecodeReader::getConstantValue(unsigned TypeSlot, unsigned Slot) {
|
|||||||
/// with this method. The ValueTable argument must be one of ModuleValues
|
/// with this method. The ValueTable argument must be one of ModuleValues
|
||||||
/// or FunctionValues data members of this class.
|
/// or FunctionValues data members of this class.
|
||||||
unsigned BytecodeReader::insertValue(Value *Val, unsigned type,
|
unsigned BytecodeReader::insertValue(Value *Val, unsigned type,
|
||||||
ValueTable &ValueTab) {
|
ValueTable &ValueTab) {
|
||||||
if (ValueTab.size() <= type)
|
if (ValueTab.size() <= type)
|
||||||
ValueTab.resize(type+1);
|
ValueTab.resize(type+1);
|
||||||
|
|
||||||
@ -1855,7 +1855,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
|||||||
case 1: Func->setLinkage(Function::DLLImportLinkage); break;
|
case 1: Func->setLinkage(Function::DLLImportLinkage); break;
|
||||||
case 2: Func->setLinkage(Function::ExternalWeakLinkage); break;
|
case 2: Func->setLinkage(Function::ExternalWeakLinkage); break;
|
||||||
default: assert(0 && "Unsupported external linkage");
|
default: assert(0 && "Unsupported external linkage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Func->setCallingConv(CC-1);
|
Func->setCallingConv(CC-1);
|
||||||
@ -1919,6 +1919,53 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
|||||||
I->first->setSection(SectionNames[I->second-1]);
|
I->first->setSection(SectionNames[I->second-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (At != BlockEnd) {
|
||||||
|
// Read aliases...
|
||||||
|
unsigned VarType = read_vbr_uint();
|
||||||
|
while (VarType != Type::VoidTyID) { // List is terminated by Void
|
||||||
|
unsigned TypeSlotNo = VarType >> 2;
|
||||||
|
unsigned EncodedLinkage = VarType & 3;
|
||||||
|
unsigned AliaseeTypeSlotNo, AliaseeSlotNo;
|
||||||
|
|
||||||
|
AliaseeTypeSlotNo = read_vbr_uint();
|
||||||
|
AliaseeSlotNo = read_vbr_uint();
|
||||||
|
|
||||||
|
const Type *Ty = getType(TypeSlotNo);
|
||||||
|
if (!Ty)
|
||||||
|
error("Alias has no type! SlotNo=" + utostr(TypeSlotNo));
|
||||||
|
|
||||||
|
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) +
|
||||||
|
" SlotNo=" + utostr(AliaseeSlotNo));
|
||||||
|
if (!isa<GlobalValue>(V))
|
||||||
|
error("Aliasee is not global value! SlotNo=" + utostr(AliaseeSlotNo));
|
||||||
|
|
||||||
|
GlobalValue::LinkageTypes Linkage;
|
||||||
|
switch (EncodedLinkage) {
|
||||||
|
case 0:
|
||||||
|
Linkage = GlobalValue::ExternalLinkage;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Linkage = GlobalValue::InternalLinkage;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Linkage = GlobalValue::WeakLinkage;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0 && "Unsupported encoded alias linkage");
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalAlias *GA = new GlobalAlias(Ty, Linkage, "",
|
||||||
|
dyn_cast<GlobalValue>(V), TheModule);
|
||||||
|
insertValue(GA, TypeSlotNo, ModuleValues);
|
||||||
|
VarType = read_vbr_uint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This is for future proofing... in the future extra fields may be added that
|
// This is for future proofing... in the future extra fields may be added that
|
||||||
// we don't understand, so we transparently ignore them.
|
// we don't understand, so we transparently ignore them.
|
||||||
//
|
//
|
||||||
|
@ -1088,9 +1088,34 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
|
|||||||
output_vbr((unsigned)SectionNames.size());
|
output_vbr((unsigned)SectionNames.size());
|
||||||
for (unsigned i = 0, e = SectionNames.size(); i != e; ++i)
|
for (unsigned i = 0, e = SectionNames.size(); i != e; ++i)
|
||||||
output(SectionNames[i]);
|
output(SectionNames[i]);
|
||||||
|
|
||||||
// Output the inline asm string.
|
// Output the inline asm string.
|
||||||
output(M->getModuleInlineAsm());
|
output(M->getModuleInlineAsm());
|
||||||
|
|
||||||
|
// 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 aliasLinkage = 0;
|
||||||
|
switch (I->getLinkage()) {
|
||||||
|
case GlobalValue::ExternalLinkage:
|
||||||
|
aliasLinkage = 0;
|
||||||
|
break;
|
||||||
|
case GlobalValue::InternalLinkage:
|
||||||
|
aliasLinkage = 1;
|
||||||
|
break;
|
||||||
|
case GlobalValue::WeakLinkage:
|
||||||
|
aliasLinkage = 2;
|
||||||
|
break;
|
||||||
|
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_typeid(Table.getTypeSlot(Type::VoidTy));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::outputInstructions(const Function *F) {
|
void BytecodeWriter::outputInstructions(const Function *F) {
|
||||||
|
@ -111,7 +111,7 @@ bool AsmPrinter::doInitialization(Module &M) {
|
|||||||
|
|
||||||
bool AsmPrinter::doFinalization(Module &M) {
|
bool AsmPrinter::doFinalization(Module &M) {
|
||||||
if (TAI->getWeakRefDirective()) {
|
if (TAI->getWeakRefDirective()) {
|
||||||
if (ExtWeakSymbols.begin() != ExtWeakSymbols.end())
|
if (!ExtWeakSymbols.empty())
|
||||||
SwitchToDataSection("");
|
SwitchToDataSection("");
|
||||||
|
|
||||||
for (std::set<const GlobalValue*>::iterator i = ExtWeakSymbols.begin(),
|
for (std::set<const GlobalValue*>::iterator i = ExtWeakSymbols.begin(),
|
||||||
@ -122,6 +122,30 @@ bool AsmPrinter::doFinalization(Module &M) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TAI->getSetDirective()) {
|
||||||
|
if (M.alias_size())
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Aliases with external weak linkage was emitted already
|
||||||
|
if (I->hasExternalLinkage())
|
||||||
|
O << "\t.globl\t" << Name << "\n";
|
||||||
|
else if (I->hasWeakLinkage())
|
||||||
|
O << TAI->getWeakRefDirective() << Name << "\n";
|
||||||
|
else if (!I->hasInternalLinkage())
|
||||||
|
assert(0 && "Invalid alias linkage");
|
||||||
|
|
||||||
|
O << TAI->getSetDirective() << Name << ", " << Target << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete Mang; Mang = 0;
|
delete Mang; Mang = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,7 @@ X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) {
|
|||||||
ReadOnlySection = "\t.section\t.rodata\n";
|
ReadOnlySection = "\t.section\t.rodata\n";
|
||||||
PrivateGlobalPrefix = ".L";
|
PrivateGlobalPrefix = ".L";
|
||||||
WeakRefDirective = "\t.weak\t";
|
WeakRefDirective = "\t.weak\t";
|
||||||
|
SetDirective = "\t.set\t";
|
||||||
DwarfRequiresFrameSection = false;
|
DwarfRequiresFrameSection = false;
|
||||||
DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",@progbits";
|
DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",@progbits";
|
||||||
DwarfInfoSection = "\t.section\t.debug_info,\"\",@progbits";
|
DwarfInfoSection = "\t.section\t.debug_info,\"\",@progbits";
|
||||||
@ -137,6 +138,7 @@ X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) {
|
|||||||
AbsoluteSectionOffsets = true;
|
AbsoluteSectionOffsets = true;
|
||||||
PrivateGlobalPrefix = "L"; // Prefix for private global symbols
|
PrivateGlobalPrefix = "L"; // Prefix for private global symbols
|
||||||
WeakRefDirective = "\t.weak\t";
|
WeakRefDirective = "\t.weak\t";
|
||||||
|
SetDirective = "\t.set\t";
|
||||||
DwarfRequiresFrameSection = false;
|
DwarfRequiresFrameSection = false;
|
||||||
DwarfSectionOffsetDirective = "\t.secrel32\t";
|
DwarfSectionOffsetDirective = "\t.secrel32\t";
|
||||||
DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"dr\"";
|
DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"dr\"";
|
||||||
|
@ -62,7 +62,8 @@ bool GlobalDCE::runOnModule(Module &M) {
|
|||||||
GlobalIsNeeded(I);
|
GlobalIsNeeded(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) {
|
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
||||||
|
I != E; ++I) {
|
||||||
Changed |= RemoveUnusedGlobalValue(*I);
|
Changed |= RemoveUnusedGlobalValue(*I);
|
||||||
// Externally visible & appending globals are needed, if they have an
|
// Externally visible & appending globals are needed, if they have an
|
||||||
// initializer.
|
// initializer.
|
||||||
@ -72,6 +73,13 @@ 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);
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
// through the program, deleting those which are not alive.
|
// through the program, deleting those which are not alive.
|
||||||
//
|
//
|
||||||
@ -135,6 +143,9 @@ 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)) {
|
||||||
|
// If this is a global alias we also need it's aliasee
|
||||||
|
GlobalIsNeeded(const_cast<GlobalValue*>(GA->getAliasee()));
|
||||||
} else {
|
} 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
|
||||||
|
@ -166,6 +166,8 @@ static SlotMachine *createSlotMachine(const Value *V) {
|
|||||||
return new SlotMachine(BB->getParent());
|
return new SlotMachine(BB->getParent());
|
||||||
} else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)){
|
} else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)){
|
||||||
return new SlotMachine(GV->getParent());
|
return new SlotMachine(GV->getParent());
|
||||||
|
} else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V)){
|
||||||
|
return new SlotMachine(GA->getParent());
|
||||||
} else if (const Function *Func = dyn_cast<Function>(V)) {
|
} else if (const Function *Func = dyn_cast<Function>(V)) {
|
||||||
return new SlotMachine(Func);
|
return new SlotMachine(Func);
|
||||||
}
|
}
|
||||||
@ -683,12 +685,13 @@ public:
|
|||||||
fillTypeNameTable(M, TypeNames);
|
fillTypeNameTable(M, TypeNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void write(const Module *M) { printModule(M); }
|
inline void write(const Module *M) { printModule(M); }
|
||||||
inline void write(const GlobalVariable *G) { printGlobal(G); }
|
inline void write(const GlobalVariable *G) { printGlobal(G); }
|
||||||
inline void write(const Function *F) { printFunction(F); }
|
inline void write(const GlobalAlias *G) { printAlias(G); }
|
||||||
inline void write(const BasicBlock *BB) { printBasicBlock(BB); }
|
inline void write(const Function *F) { printFunction(F); }
|
||||||
|
inline void write(const BasicBlock *BB) { printBasicBlock(BB); }
|
||||||
inline void write(const Instruction *I) { printInstruction(*I); }
|
inline void write(const Instruction *I) { printInstruction(*I); }
|
||||||
inline void write(const Type *Ty) { printType(Ty); }
|
inline void write(const Type *Ty) { printType(Ty); }
|
||||||
|
|
||||||
void writeOperand(const Value *Op, bool PrintType);
|
void writeOperand(const Value *Op, bool PrintType);
|
||||||
|
|
||||||
@ -698,6 +701,7 @@ private:
|
|||||||
void printModule(const Module *M);
|
void printModule(const Module *M);
|
||||||
void printTypeSymbolTable(const TypeSymbolTable &ST);
|
void printTypeSymbolTable(const TypeSymbolTable &ST);
|
||||||
void printGlobal(const GlobalVariable *GV);
|
void printGlobal(const GlobalVariable *GV);
|
||||||
|
void printAlias(const GlobalAlias *GV);
|
||||||
void printFunction(const Function *F);
|
void printFunction(const Function *F);
|
||||||
void printArgument(const Argument *FA, uint16_t ParamAttrs);
|
void printArgument(const Argument *FA, uint16_t ParamAttrs);
|
||||||
void printBasicBlock(const BasicBlock *BB);
|
void printBasicBlock(const BasicBlock *BB);
|
||||||
@ -848,6 +852,11 @@ void AssemblyWriter::printModule(const Module *M) {
|
|||||||
// Output all of the functions.
|
// Output all of the functions.
|
||||||
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
|
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||||
printFunction(I);
|
printFunction(I);
|
||||||
|
|
||||||
|
// Output all aliases
|
||||||
|
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
|
||||||
|
I != E; ++I)
|
||||||
|
printAlias(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
||||||
@ -888,16 +897,55 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
|||||||
assert(C && "GlobalVar initializer isn't constant?");
|
assert(C && "GlobalVar initializer isn't constant?");
|
||||||
writeOperand(GV->getInitializer(), false);
|
writeOperand(GV->getInitializer(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GV->hasSection())
|
if (GV->hasSection())
|
||||||
Out << ", section \"" << GV->getSection() << '"';
|
Out << ", section \"" << GV->getSection() << '"';
|
||||||
if (GV->getAlignment())
|
if (GV->getAlignment())
|
||||||
Out << ", align " << GV->getAlignment();
|
Out << ", align " << GV->getAlignment();
|
||||||
|
|
||||||
printInfoComment(*GV);
|
printInfoComment(*GV);
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssemblyWriter::printAlias(const GlobalAlias *GA) {
|
||||||
|
Out << getLLVMName(GA->getName(), GlobalPrefix) << " = ";
|
||||||
|
switch (GA->getVisibility()) {
|
||||||
|
default: assert(0 && "Invalid visibility style!");
|
||||||
|
case GlobalValue::DefaultVisibility: break;
|
||||||
|
case GlobalValue::HiddenVisibility: Out << "hidden "; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Out << "alias ";
|
||||||
|
|
||||||
|
switch (GA->getLinkage()) {
|
||||||
|
case GlobalValue::WeakLinkage: Out << "weak "; break;
|
||||||
|
case GlobalValue::InternalLinkage: Out << "internal "; break;
|
||||||
|
case GlobalValue::ExternalLinkage: break;
|
||||||
|
default:
|
||||||
|
assert(0 && "Invalid alias linkage");
|
||||||
|
}
|
||||||
|
|
||||||
|
const GlobalValue *Aliasee = GA->getAliasee();
|
||||||
|
assert(Aliasee && "Aliasee cannot be null");
|
||||||
|
|
||||||
|
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
|
||||||
|
printType(GV->getType());
|
||||||
|
Out << " " << getLLVMName(GV->getName(), GlobalPrefix);
|
||||||
|
} else if (const Function *F = dyn_cast<Function>(Aliasee)) {
|
||||||
|
printType(F->getFunctionType());
|
||||||
|
Out << "* ";
|
||||||
|
|
||||||
|
if (!F->getName().empty())
|
||||||
|
Out << getLLVMName(F->getName(), GlobalPrefix);
|
||||||
|
else
|
||||||
|
Out << "@\"\"";
|
||||||
|
} else
|
||||||
|
assert(0 && "Unsupported aliasee");
|
||||||
|
|
||||||
|
printInfoComment(*GA);
|
||||||
|
Out << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
|
void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
|
||||||
// Print the types.
|
// Print the types.
|
||||||
for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end();
|
for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end();
|
||||||
@ -1336,6 +1384,12 @@ void GlobalVariable::print(std::ostream &o) const {
|
|||||||
W.write(this);
|
W.write(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GlobalAlias::print(std::ostream &o) const {
|
||||||
|
SlotMachine SlotTable(getParent());
|
||||||
|
AssemblyWriter W(o, SlotTable, getParent(), 0);
|
||||||
|
W.write(this);
|
||||||
|
}
|
||||||
|
|
||||||
void Function::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
|
void Function::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
|
||||||
SlotMachine SlotTable(getParent());
|
SlotMachine SlotTable(getParent());
|
||||||
AssemblyWriter W(o, SlotTable, getParent(), AAW);
|
AssemblyWriter W(o, SlotTable, getParent(), AAW);
|
||||||
@ -1538,8 +1592,10 @@ void SlotMachine::CreateModuleSlot(const GlobalValue *V) {
|
|||||||
|
|
||||||
SC_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
|
SC_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
|
||||||
DestSlot << " [");
|
DestSlot << " [");
|
||||||
// G = Global, F = Function, o = other
|
// G = Global, F = Function, A = Alias, o = other
|
||||||
SC_DEBUG((isa<GlobalVariable>(V) ? 'G' : 'F') << "]\n");
|
SC_DEBUG((isa<GlobalVariable>(V) ? 'G' :
|
||||||
|
(isa<Function> ? 'F' :
|
||||||
|
(isa<GlobalAlias> ? 'A' : 'o'))) << "]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
|
#include "llvm/GlobalAlias.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Support/LeakDetector.h"
|
#include "llvm/Support/LeakDetector.h"
|
||||||
@ -76,6 +77,7 @@ void GlobalValue::destroyConstant() {
|
|||||||
assert(0 && "You can't GV->destroyConstant()!");
|
assert(0 && "You can't GV->destroyConstant()!");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// GlobalVariable Implementation
|
// GlobalVariable Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -120,7 +122,6 @@ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
|
|||||||
Before->getParent()->getGlobalList().insert(Before, this);
|
Before->getParent()->getGlobalList().insert(Before, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GlobalVariable::setParent(Module *parent) {
|
void GlobalVariable::setParent(Module *parent) {
|
||||||
if (getParent())
|
if (getParent())
|
||||||
LeakDetector::addGarbageObject(this);
|
LeakDetector::addGarbageObject(this);
|
||||||
@ -156,3 +157,45 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
|
|||||||
// Okay, preconditions out of the way, replace the constant initializer.
|
// Okay, preconditions out of the way, replace the constant initializer.
|
||||||
this->setOperand(0, cast<Constant>(To));
|
this->setOperand(0, cast<Constant>(To));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// GlobalAlias Implementation
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
|
||||||
|
const std::string &Name, const GlobalValue* aliasee,
|
||||||
|
Module *ParentModule)
|
||||||
|
: GlobalValue(Ty, Value::GlobalAliasVal, 0, 0,
|
||||||
|
Link, Name), Aliasee(aliasee) {
|
||||||
|
LeakDetector::addGarbageObject(this);
|
||||||
|
|
||||||
|
if (ParentModule)
|
||||||
|
ParentModule->getAliasList().push_back(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAlias::setParent(Module *parent) {
|
||||||
|
if (getParent())
|
||||||
|
LeakDetector::addGarbageObject(this);
|
||||||
|
Parent = parent;
|
||||||
|
if (getParent())
|
||||||
|
LeakDetector::removeGarbageObject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAlias::removeFromParent() {
|
||||||
|
getParent()->getAliasList().remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAlias::eraseFromParent() {
|
||||||
|
getParent()->getAliasList().erase(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GlobalAlias::isDeclaration() const {
|
||||||
|
return (Aliasee && Aliasee->isDeclaration());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAlias::setAliasee(const GlobalValue *GV)
|
||||||
|
{
|
||||||
|
// FIXME: Some checks?
|
||||||
|
Aliasee = GV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,12 @@ GlobalVariable *ilist_traits<GlobalVariable>::createSentinel() {
|
|||||||
LeakDetector::removeGarbageObject(Ret);
|
LeakDetector::removeGarbageObject(Ret);
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
GlobalAlias *ilist_traits<GlobalAlias>::createSentinel() {
|
||||||
|
GlobalAlias *Ret = new GlobalAlias(Type::Int32Ty, GlobalValue::ExternalLinkage);
|
||||||
|
// This should not be garbage monitored.
|
||||||
|
LeakDetector::removeGarbageObject(Ret);
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
iplist<Function> &ilist_traits<Function>::getList(Module *M) {
|
iplist<Function> &ilist_traits<Function>::getList(Module *M) {
|
||||||
return M->getFunctionList();
|
return M->getFunctionList();
|
||||||
@ -52,11 +58,15 @@ iplist<Function> &ilist_traits<Function>::getList(Module *M) {
|
|||||||
iplist<GlobalVariable> &ilist_traits<GlobalVariable>::getList(Module *M) {
|
iplist<GlobalVariable> &ilist_traits<GlobalVariable>::getList(Module *M) {
|
||||||
return M->getGlobalList();
|
return M->getGlobalList();
|
||||||
}
|
}
|
||||||
|
iplist<GlobalAlias> &ilist_traits<GlobalAlias>::getList(Module *M) {
|
||||||
|
return M->getAliasList();
|
||||||
|
}
|
||||||
|
|
||||||
// Explicit instantiations of SymbolTableListTraits since some of the methods
|
// Explicit instantiations of SymbolTableListTraits since some of the methods
|
||||||
// are not in the public header file.
|
// are not in the public header file.
|
||||||
template class SymbolTableListTraits<GlobalVariable, Module>;
|
template class SymbolTableListTraits<GlobalVariable, Module>;
|
||||||
template class SymbolTableListTraits<Function, Module>;
|
template class SymbolTableListTraits<Function, Module>;
|
||||||
|
template class SymbolTableListTraits<GlobalAlias, Module>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Primitive Module methods.
|
// Primitive Module methods.
|
||||||
@ -72,6 +82,7 @@ Module::~Module() {
|
|||||||
dropAllReferences();
|
dropAllReferences();
|
||||||
GlobalList.clear();
|
GlobalList.clear();
|
||||||
FunctionList.clear();
|
FunctionList.clear();
|
||||||
|
AliasList.clear();
|
||||||
LibraryList.clear();
|
LibraryList.clear();
|
||||||
delete ValSymTab;
|
delete ValSymTab;
|
||||||
delete TypeSymTab;
|
delete TypeSymTab;
|
||||||
@ -211,6 +222,18 @@ GlobalVariable *Module::getGlobalVariable(const std::string &Name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Methods for easy access to the global variables in the module.
|
||||||
|
//
|
||||||
|
|
||||||
|
// getNamedAlias - Look up the specified global in the module symbol table.
|
||||||
|
// If it does not exist, return null.
|
||||||
|
//
|
||||||
|
GlobalAlias *Module::getNamedAlias(const std::string &Name) const {
|
||||||
|
const ValueSymbolTable &SymTab = getValueSymbolTable();
|
||||||
|
return dyn_cast_or_null<GlobalAlias>(SymTab.lookup(Name));
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Methods for easy access to the types in the module.
|
// Methods for easy access to the types in the module.
|
||||||
//
|
//
|
||||||
|
@ -141,6 +141,10 @@ namespace { // Anonymous namespace for class
|
|||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
visitGlobalVariable(*I);
|
visitGlobalVariable(*I);
|
||||||
|
|
||||||
|
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
|
||||||
|
I != E; ++I)
|
||||||
|
visitGlobalAlias(*I);
|
||||||
|
|
||||||
// If the module is broken, abort at this time.
|
// If the module is broken, abort at this time.
|
||||||
return abortIfBroken();
|
return abortIfBroken();
|
||||||
}
|
}
|
||||||
@ -179,6 +183,7 @@ namespace { // Anonymous namespace for class
|
|||||||
void verifyTypeSymbolTable(TypeSymbolTable &ST);
|
void verifyTypeSymbolTable(TypeSymbolTable &ST);
|
||||||
void visitGlobalValue(GlobalValue &GV);
|
void visitGlobalValue(GlobalValue &GV);
|
||||||
void visitGlobalVariable(GlobalVariable &GV);
|
void visitGlobalVariable(GlobalVariable &GV);
|
||||||
|
void visitGlobalAlias(GlobalAlias &GA);
|
||||||
void visitFunction(Function &F);
|
void visitFunction(Function &F);
|
||||||
void visitBasicBlock(BasicBlock &BB);
|
void visitBasicBlock(BasicBlock &BB);
|
||||||
void visitTruncInst(TruncInst &I);
|
void visitTruncInst(TruncInst &I);
|
||||||
@ -277,7 +282,9 @@ void Verifier::visitGlobalValue(GlobalValue &GV) {
|
|||||||
Assert1(!GV.isDeclaration() ||
|
Assert1(!GV.isDeclaration() ||
|
||||||
GV.hasExternalLinkage() ||
|
GV.hasExternalLinkage() ||
|
||||||
GV.hasDLLImportLinkage() ||
|
GV.hasDLLImportLinkage() ||
|
||||||
GV.hasExternalWeakLinkage(),
|
GV.hasExternalWeakLinkage() ||
|
||||||
|
(isa<GlobalAlias>(GV) &&
|
||||||
|
(GV.hasInternalLinkage() || GV.hasWeakLinkage())),
|
||||||
"Global is external, but doesn't have external or dllimport or weak linkage!",
|
"Global is external, but doesn't have external or dllimport or weak linkage!",
|
||||||
&GV);
|
&GV);
|
||||||
|
|
||||||
@ -303,6 +310,16 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
|
|||||||
visitGlobalValue(GV);
|
visitGlobalValue(GV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Verifier::visitGlobalAlias(GlobalAlias &GA) {
|
||||||
|
Assert1(!GA.getName().empty(),
|
||||||
|
"Alias name cannot be empty!", &GA);
|
||||||
|
Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() ||
|
||||||
|
GA.hasWeakLinkage(),
|
||||||
|
"Alias should have external or external weak linkage!", &GA);
|
||||||
|
|
||||||
|
visitGlobalValue(GA);
|
||||||
|
}
|
||||||
|
|
||||||
void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) {
|
void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
test/CodeGen/X86/aliases.ll
Normal file
30
test/CodeGen/X86/aliases.ll
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
; RUN: llvm-as < %s | \
|
||||||
|
; RUN: llc -mtriple=i686-pc-linux-gnu -o %t -f
|
||||||
|
; RUN: grep -c set %t | grep 4
|
||||||
|
; RUN: grep -c globl %t | grep 3
|
||||||
|
; RUN: grep -c weak %t | grep 1
|
||||||
|
|
||||||
|
@bar = external global i32
|
||||||
|
@foo1 = alias i32* @bar
|
||||||
|
@foo2 = alias i32* @bar
|
||||||
|
|
||||||
|
%FunTy = type i32()
|
||||||
|
|
||||||
|
declare i32 @foo_f()
|
||||||
|
@bar_f = alias weak %FunTy* @foo_f
|
||||||
|
|
||||||
|
@bar_i = alias internal i32* @bar
|
||||||
|
|
||||||
|
define i32 @test() {
|
||||||
|
entry:
|
||||||
|
%tmp = load i32* @foo1
|
||||||
|
%tmp1 = load i32* @foo2
|
||||||
|
%tmp0 = load i32* @bar_i
|
||||||
|
%tmp2 = call i32 @foo_f()
|
||||||
|
%tmp3 = add i32 %tmp, %tmp2
|
||||||
|
%tmp4 = call %FunTy* @bar_f()
|
||||||
|
%tmp5 = add i32 %tmp3, %tmp4
|
||||||
|
%tmp6 = add i32 %tmp1, %tmp5
|
||||||
|
%tmp7 = add i32 %tmp6, %tmp0
|
||||||
|
ret i32 %tmp7
|
||||||
|
}
|
28
test/Feature/aliases.ll
Normal file
28
test/Feature/aliases.ll
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
; RUN: llvm-as < %s | llvm-dis > %t1.ll
|
||||||
|
; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
|
||||||
|
; RUN: diff %t1.ll %t2.ll
|
||||||
|
|
||||||
|
@bar = external global i32
|
||||||
|
@foo1 = alias i32* @bar
|
||||||
|
@foo2 = alias i32* @bar
|
||||||
|
|
||||||
|
%FunTy = type i32()
|
||||||
|
|
||||||
|
declare i32 @foo_f()
|
||||||
|
@bar_f = alias weak %FunTy* @foo_f
|
||||||
|
|
||||||
|
@bar_i = alias internal i32* @bar
|
||||||
|
|
||||||
|
define i32 @test() {
|
||||||
|
entry:
|
||||||
|
%tmp = load i32* @foo1
|
||||||
|
%tmp1 = load i32* @foo2
|
||||||
|
%tmp0 = load i32* @bar_i
|
||||||
|
%tmp2 = call i32 @foo_f()
|
||||||
|
%tmp3 = add i32 %tmp, %tmp2
|
||||||
|
%tmp4 = call %FunTy* @bar_f()
|
||||||
|
%tmp5 = add i32 %tmp3, %tmp4
|
||||||
|
%tmp6 = add i32 %tmp1, %tmp5
|
||||||
|
%tmp7 = add i32 %tmp6, %tmp0
|
||||||
|
ret i32 %tmp7
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user