forked from OSchip/llvm-project
Switch ValueSymbolTable to use StringMap<Value*> instead of std::map<std::string, Value*>
as its main datastructure. There are many improvements yet to be made, but this speeds up opt --std-compile-opts on 447.dealII by 7.3%. llvm-svn: 34193
This commit is contained in:
parent
e976307ba9
commit
32ab643df7
|
@ -39,9 +39,8 @@ class Constant : public User {
|
||||||
void operator=(const Constant &); // Do not implement
|
void operator=(const Constant &); // Do not implement
|
||||||
Constant(const Constant &); // Do not implement
|
Constant(const Constant &); // Do not implement
|
||||||
protected:
|
protected:
|
||||||
Constant(const Type *Ty, ValueTy vty, Use *Ops, unsigned NumOps,
|
Constant(const Type *Ty, ValueTy vty, Use *Ops, unsigned NumOps)
|
||||||
const std::string& Name = "")
|
: User(Ty, vty, Ops, NumOps) {}
|
||||||
: User(Ty, vty, Ops, NumOps, Name) {}
|
|
||||||
|
|
||||||
void destroyConstantImpl();
|
void destroyConstantImpl();
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -49,8 +49,10 @@ public:
|
||||||
protected:
|
protected:
|
||||||
GlobalValue(const Type *Ty, ValueTy vty, Use *Ops, unsigned NumOps,
|
GlobalValue(const Type *Ty, ValueTy vty, Use *Ops, unsigned NumOps,
|
||||||
LinkageTypes linkage, const std::string &name = "")
|
LinkageTypes linkage, const std::string &name = "")
|
||||||
: Constant(Ty, vty, Ops, NumOps, name), Parent(0),
|
: Constant(Ty, vty, Ops, NumOps), Parent(0),
|
||||||
Linkage(linkage), Visibility(DefaultVisibility), Alignment(0) { }
|
Linkage(linkage), Visibility(DefaultVisibility), Alignment(0) {
|
||||||
|
if (!name.empty()) setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
Module *Parent;
|
Module *Parent;
|
||||||
LinkageTypes Linkage; // The linkage of this global
|
LinkageTypes Linkage; // The linkage of this global
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#define LLVM_USER_H
|
#define LLVM_USER_H
|
||||||
|
|
||||||
#include "llvm/Value.h"
|
#include "llvm/Value.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
@ -39,9 +38,8 @@ protected:
|
||||||
unsigned NumOperands;
|
unsigned NumOperands;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
User(const Type *Ty, unsigned vty, Use *OpList, unsigned NumOps,
|
User(const Type *Ty, unsigned vty, Use *OpList, unsigned NumOps)
|
||||||
const std::string &name = "")
|
: Value(Ty, vty), OperandList(OpList), NumOperands(NumOps) {}
|
||||||
: Value(Ty, vty, name), OperandList(OpList), NumOperands(NumOps) {}
|
|
||||||
|
|
||||||
Value *getOperand(unsigned i) const {
|
Value *getOperand(unsigned i) const {
|
||||||
assert(i < NumOperands && "getOperand() out of range!");
|
assert(i < NumOperands && "getOperand() out of range!");
|
||||||
|
|
|
@ -33,6 +33,8 @@ class GlobalVariable;
|
||||||
class InlineAsm;
|
class InlineAsm;
|
||||||
class ValueSymbolTable;
|
class ValueSymbolTable;
|
||||||
class TypeSymbolTable;
|
class TypeSymbolTable;
|
||||||
|
template<typename ValueTy> class StringMapEntry;
|
||||||
|
typedef StringMapEntry<Value*> ValueName;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Value Class
|
// Value Class
|
||||||
|
@ -61,13 +63,13 @@ private:
|
||||||
|
|
||||||
friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name.
|
friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name.
|
||||||
friend class SymbolTable; // Allow SymbolTable to directly poke Name.
|
friend class SymbolTable; // Allow SymbolTable to directly poke Name.
|
||||||
std::string Name;
|
ValueName *Name;
|
||||||
|
|
||||||
void operator=(const Value &); // Do not implement
|
void operator=(const Value &); // Do not implement
|
||||||
Value(const Value &); // Do not implement
|
Value(const Value &); // Do not implement
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Value(const Type *Ty, unsigned scid, const std::string &name = "");
|
Value(const Type *Ty, unsigned scid);
|
||||||
virtual ~Value();
|
virtual ~Value();
|
||||||
|
|
||||||
/// dump - Support for debugging, callable in GDB: V->dump()
|
/// dump - Support for debugging, callable in GDB: V->dump()
|
||||||
|
@ -84,8 +86,9 @@ public:
|
||||||
inline const Type *getType() const { return Ty; }
|
inline const Type *getType() const { return Ty; }
|
||||||
|
|
||||||
// All values can potentially be named...
|
// All values can potentially be named...
|
||||||
inline bool hasName() const { return !Name.empty(); }
|
inline bool hasName() const { return Name != 0; }
|
||||||
inline const std::string &getName() const { return Name; }
|
std::string getName() const;
|
||||||
|
ValueName *getValueName() const { return Name; }
|
||||||
|
|
||||||
void setName(const std::string &name);
|
void setName(const std::string &name);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#define LLVM_VALUE_SYMBOL_TABLE_H
|
#define LLVM_VALUE_SYMBOL_TABLE_H
|
||||||
|
|
||||||
#include "llvm/Value.h"
|
#include "llvm/Value.h"
|
||||||
#include <map>
|
#include "llvm/ADT/StringMap.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
template<typename ValueSubClass, typename ItemParentClass,
|
template<typename ValueSubClass, typename ItemParentClass,
|
||||||
|
@ -47,9 +47,8 @@ class ValueSymbolTable {
|
||||||
/// @name Types
|
/// @name Types
|
||||||
/// @{
|
/// @{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @brief A mapping of names to values.
|
/// @brief A mapping of names to values.
|
||||||
typedef std::map<const std::string, Value *> ValueMap;
|
typedef StringMap<Value*> ValueMap;
|
||||||
|
|
||||||
/// @brief An iterator over a ValueMap.
|
/// @brief An iterator over a ValueMap.
|
||||||
typedef ValueMap::iterator iterator;
|
typedef ValueMap::iterator iterator;
|
||||||
|
@ -89,12 +88,6 @@ public:
|
||||||
/// @brief Get a name unique to this symbol table
|
/// @brief Get a name unique to this symbol table
|
||||||
std::string getUniqueName(const std::string &BaseName) const;
|
std::string getUniqueName(const std::string &BaseName) const;
|
||||||
|
|
||||||
/// @return 1 if the name is in the symbol table, 0 otherwise
|
|
||||||
/// @brief Determine if a name is in the symbol table
|
|
||||||
bool count(const std::string &name) const {
|
|
||||||
return vmap.count(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This function can be used from the debugger to display the
|
/// This function can be used from the debugger to display the
|
||||||
/// content of the symbol table while debugging.
|
/// content of the symbol table while debugging.
|
||||||
/// @brief Print out symbol table on stderr
|
/// @brief Print out symbol table on stderr
|
||||||
|
@ -104,7 +97,6 @@ public:
|
||||||
/// @name Iteration
|
/// @name Iteration
|
||||||
/// @{
|
/// @{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @brief Get an iterator that from the beginning of the symbol table.
|
/// @brief Get an iterator that from the beginning of the symbol table.
|
||||||
inline iterator begin() { return vmap.begin(); }
|
inline iterator begin() { return vmap.begin(); }
|
||||||
|
|
||||||
|
@ -116,21 +108,26 @@ public:
|
||||||
|
|
||||||
/// @brief Get a const_iterator to the end of the symbol table.
|
/// @brief Get a const_iterator to the end of the symbol table.
|
||||||
inline const_iterator end() const { return vmap.end(); }
|
inline const_iterator end() const { return vmap.end(); }
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Mutators
|
/// @name Mutators
|
||||||
/// @{
|
/// @{
|
||||||
private:
|
private:
|
||||||
/// This method adds the provided value \p N to the symbol table. The Value
|
/// This method adds the provided value \p N to the symbol table. The Value
|
||||||
/// must have a name which is used to place the value in the symbol table.
|
/// must have a name which is used to place the value in the symbol table.
|
||||||
|
/// If the inserted name conflicts, this renames the value.
|
||||||
/// @brief Add a named value to the symbol table
|
/// @brief Add a named value to the symbol table
|
||||||
void insert(Value *Val);
|
void reinsertValue(Value *V);
|
||||||
|
|
||||||
/// This method removes a value from the symbol table. The name of the
|
/// createValueName - This method attempts to create a value name and insert
|
||||||
/// Value is extracted from \p Val and used to lookup the Value in the
|
/// it into the symbol table with the specified name. If it conflicts, it
|
||||||
/// symbol table. \p Val is not deleted, just removed from the symbol table.
|
/// auto-renames the name and returns that instead.
|
||||||
/// @brief Remove a value from the symbol table.
|
ValueName *createValueName(const char *NameStart, unsigned NameLen, Value *V);
|
||||||
void remove(Value* Val);
|
|
||||||
|
/// This method removes a value from the symbol table. It leaves the
|
||||||
|
/// ValueName attached to the value, but it is no longer inserted in the
|
||||||
|
/// symtab.
|
||||||
|
void removeValueName(ValueName *V);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Internal Data
|
/// @name Internal Data
|
||||||
|
|
|
@ -199,7 +199,7 @@ void SlotCalculator::processTypeSymbolTable(const TypeSymbolTable *TST) {
|
||||||
void SlotCalculator::processValueSymbolTable(const ValueSymbolTable *VST) {
|
void SlotCalculator::processValueSymbolTable(const ValueSymbolTable *VST) {
|
||||||
for (ValueSymbolTable::const_iterator VI = VST->begin(), VE = VST->end();
|
for (ValueSymbolTable::const_iterator VI = VST->begin(), VE = VST->end();
|
||||||
VI != VE; ++VI)
|
VI != VE; ++VI)
|
||||||
CreateSlotIfNeeded(VI->second);
|
CreateSlotIfNeeded(VI->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlotCalculator::CreateSlotIfNeeded(const Value *V) {
|
void SlotCalculator::CreateSlotIfNeeded(const Value *V) {
|
||||||
|
|
|
@ -132,10 +132,9 @@ inline void BytecodeWriter::output_vbr(int i) {
|
||||||
output_vbr((unsigned)i << 1); // Low order bit is clear.
|
output_vbr((unsigned)i << 1); // Low order bit is clear.
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BytecodeWriter::output(const std::string &s) {
|
inline void BytecodeWriter::output_str(const char *Str, unsigned Len) {
|
||||||
unsigned Len = s.length();
|
|
||||||
output_vbr(Len); // Strings may have an arbitrary length.
|
output_vbr(Len); // Strings may have an arbitrary length.
|
||||||
Out.insert(Out.end(), s.begin(), s.end());
|
Out.insert(Out.end(), Str, Str+Len);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BytecodeWriter::output_data(const void *Ptr, const void *End) {
|
inline void BytecodeWriter::output_data(const void *Ptr, const void *End) {
|
||||||
|
@ -1088,14 +1087,12 @@ void BytecodeWriter::outputValueSymbolTable(const ValueSymbolTable &VST) {
|
||||||
true/*ElideIfEmpty*/);
|
true/*ElideIfEmpty*/);
|
||||||
|
|
||||||
// Organize the symbol table by type
|
// Organize the symbol table by type
|
||||||
typedef std::pair<const std::string*, const Value*> PlaneMapEntry;
|
typedef SmallVector<const ValueName*, 8> PlaneMapVector;
|
||||||
typedef SmallVector<PlaneMapEntry, 8> PlaneMapVector;
|
|
||||||
typedef DenseMap<const Type*, PlaneMapVector > PlaneMap;
|
typedef DenseMap<const Type*, PlaneMapVector > PlaneMap;
|
||||||
PlaneMap Planes;
|
PlaneMap Planes;
|
||||||
for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
|
for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
|
||||||
SI != SE; ++SI)
|
SI != SE; ++SI)
|
||||||
Planes[SI->second->getType()]
|
Planes[SI->getValue()->getType()].push_back(&*SI);
|
||||||
.push_back(std::make_pair(&SI->first, SI->second));
|
|
||||||
|
|
||||||
for (PlaneMap::iterator PI = Planes.begin(), PE = Planes.end();
|
for (PlaneMap::iterator PI = Planes.begin(), PE = Planes.end();
|
||||||
PI != PE; ++PI) {
|
PI != PE; ++PI) {
|
||||||
|
@ -1113,8 +1110,8 @@ void BytecodeWriter::outputValueSymbolTable(const ValueSymbolTable &VST) {
|
||||||
// Write each of the values in this plane
|
// Write each of the values in this plane
|
||||||
for (; I != End; ++I) {
|
for (; I != End; ++I) {
|
||||||
// Symtab entry: [def slot #][name]
|
// Symtab entry: [def slot #][name]
|
||||||
output_vbr(Table.getSlot(I->second));
|
output_vbr(Table.getSlot((*I)->getValue()));
|
||||||
output(*I->first);
|
output_str((*I)->getKeyData(), (*I)->getKeyLength());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,10 @@ private:
|
||||||
/// @brief Signed 32-bit variable bit rate output primitive.
|
/// @brief Signed 32-bit variable bit rate output primitive.
|
||||||
inline void output_vbr(int i);
|
inline void output_vbr(int i);
|
||||||
|
|
||||||
inline void output(const std::string &s);
|
inline void output_str(const char *Str, unsigned Len);
|
||||||
|
inline void output(const std::string &s) {
|
||||||
|
output_str(&s[0], s.size());
|
||||||
|
}
|
||||||
|
|
||||||
inline void output_data(const void *Ptr, const void *End);
|
inline void output_data(const void *Ptr, const void *End);
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ static void RemoveDeadConstant(Constant *C) {
|
||||||
//
|
//
|
||||||
static void StripSymtab(ValueSymbolTable &ST) {
|
static void StripSymtab(ValueSymbolTable &ST) {
|
||||||
for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
|
for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
|
||||||
Value *V = VI->second;
|
Value *V = VI->getValue();
|
||||||
++VI;
|
++VI;
|
||||||
if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
|
if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
|
||||||
// Set name to "", removing from symbol table!
|
// Set name to "", removing from symbol table!
|
||||||
|
|
|
@ -62,7 +62,7 @@ template class SymbolTableListTraits<Instruction, BasicBlock, Function>;
|
||||||
|
|
||||||
BasicBlock::BasicBlock(const std::string &Name, Function *Parent,
|
BasicBlock::BasicBlock(const std::string &Name, Function *Parent,
|
||||||
BasicBlock *InsertBefore)
|
BasicBlock *InsertBefore)
|
||||||
: Value(Type::LabelTy, Value::BasicBlockVal, Name) {
|
: Value(Type::LabelTy, Value::BasicBlockVal) {
|
||||||
// Initialize the instlist...
|
// Initialize the instlist...
|
||||||
InstList.setItemParent(this);
|
InstList.setItemParent(this);
|
||||||
|
|
||||||
|
@ -76,6 +76,8 @@ BasicBlock::BasicBlock(const std::string &Name, Function *Parent,
|
||||||
} else if (Parent) {
|
} else if (Parent) {
|
||||||
Parent->getBasicBlockList().push_back(this);
|
Parent->getBasicBlockList().push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setName(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ template class SymbolTableListTraits<BasicBlock, Function, Function>;
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
Argument::Argument(const Type *Ty, const std::string &Name, Function *Par)
|
Argument::Argument(const Type *Ty, const std::string &Name, Function *Par)
|
||||||
: Value(Ty, Value::ArgumentVal, Name) {
|
: Value(Ty, Value::ArgumentVal) {
|
||||||
Parent = 0;
|
Parent = 0;
|
||||||
|
|
||||||
// Make sure that we get added to a function
|
// Make sure that we get added to a function
|
||||||
|
@ -59,6 +59,7 @@ Argument::Argument(const Type *Ty, const std::string &Name, Function *Par)
|
||||||
|
|
||||||
if (Par)
|
if (Par)
|
||||||
Par->getArgumentList().push_back(this);
|
Par->getArgumentList().push_back(this);
|
||||||
|
setName(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Argument::setParent(Function *parent) {
|
void Argument::setParent(Function *parent) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ using namespace llvm;
|
||||||
|
|
||||||
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
|
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
|
||||||
const std::string &Name, Instruction *InsertBefore)
|
const std::string &Name, Instruction *InsertBefore)
|
||||||
: User(ty, Value::InstructionVal + it, Ops, NumOps, Name), Parent(0) {
|
: User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) {
|
||||||
// Make sure that we get added to a basicblock
|
// Make sure that we get added to a basicblock
|
||||||
LeakDetector::addGarbageObject(this);
|
LeakDetector::addGarbageObject(this);
|
||||||
|
|
||||||
|
@ -29,17 +29,19 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
|
||||||
"Instruction to insert before is not in a basic block!");
|
"Instruction to insert before is not in a basic block!");
|
||||||
InsertBefore->getParent()->getInstList().insert(InsertBefore, this);
|
InsertBefore->getParent()->getInstList().insert(InsertBefore, this);
|
||||||
}
|
}
|
||||||
|
setName(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
|
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
|
||||||
const std::string &Name, BasicBlock *InsertAtEnd)
|
const std::string &Name, BasicBlock *InsertAtEnd)
|
||||||
: User(ty, Value::InstructionVal + it, Ops, NumOps, Name), Parent(0) {
|
: User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) {
|
||||||
// Make sure that we get added to a basicblock
|
// Make sure that we get added to a basicblock
|
||||||
LeakDetector::addGarbageObject(this);
|
LeakDetector::addGarbageObject(this);
|
||||||
|
|
||||||
// append this instruction into the basic block
|
// append this instruction into the basic block
|
||||||
assert(InsertAtEnd && "Basic block to append to may not be NULL!");
|
assert(InsertAtEnd && "Basic block to append to may not be NULL!");
|
||||||
InsertAtEnd->getInstList().push_back(this);
|
InsertAtEnd->getInstList().push_back(this);
|
||||||
|
setName(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Out of line virtual method, so the vtable, etc has a home.
|
// Out of line virtual method, so the vtable, etc has a home.
|
||||||
|
|
|
@ -32,7 +32,7 @@ void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
|
||||||
ValueSymbolTable &SymTab = SymTabObject->getValueSymbolTable();
|
ValueSymbolTable &SymTab = SymTabObject->getValueSymbolTable();
|
||||||
for (typename iplist<ValueSubClass>::iterator I = List.begin();
|
for (typename iplist<ValueSubClass>::iterator I = List.begin();
|
||||||
I != List.end(); ++I)
|
I != List.end(); ++I)
|
||||||
if (I->hasName()) SymTab.remove(I);
|
if (I->hasName()) SymTab.removeValueName(I->getValueName());
|
||||||
}
|
}
|
||||||
|
|
||||||
SymTabObject = STO;
|
SymTabObject = STO;
|
||||||
|
@ -42,7 +42,7 @@ void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
|
||||||
ValueSymbolTable &SymTab = SymTabObject->getValueSymbolTable();
|
ValueSymbolTable &SymTab = SymTabObject->getValueSymbolTable();
|
||||||
for (typename iplist<ValueSubClass>::iterator I = List.begin();
|
for (typename iplist<ValueSubClass>::iterator I = List.begin();
|
||||||
I != List.end(); ++I)
|
I != List.end(); ++I)
|
||||||
if (I->hasName()) SymTab.insert(I);
|
if (I->hasName()) SymTab.reinsertValue(I);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
|
||||||
assert(V->getParent() == 0 && "Value already in a container!!");
|
assert(V->getParent() == 0 && "Value already in a container!!");
|
||||||
V->setParent(ItemParent);
|
V->setParent(ItemParent);
|
||||||
if (V->hasName() && SymTabObject)
|
if (V->hasName() && SymTabObject)
|
||||||
SymTabObject->getValueSymbolTable().insert(V);
|
SymTabObject->getValueSymbolTable().reinsertValue(V);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass,
|
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass,
|
||||||
|
@ -62,7 +62,7 @@ void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
|
||||||
::removeNodeFromList(ValueSubClass *V) {
|
::removeNodeFromList(ValueSubClass *V) {
|
||||||
V->setParent(0);
|
V->setParent(0);
|
||||||
if (V->hasName() && SymTabObject)
|
if (V->hasName() && SymTabObject)
|
||||||
SymTabObject->getValueSymbolTable().remove(V);
|
SymTabObject->getValueSymbolTable().removeValueName(V->getValueName());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass,
|
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass,
|
||||||
|
@ -83,10 +83,10 @@ void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
|
||||||
ValueSubClass &V = *first;
|
ValueSubClass &V = *first;
|
||||||
bool HasName = V.hasName();
|
bool HasName = V.hasName();
|
||||||
if (OldSTO && HasName)
|
if (OldSTO && HasName)
|
||||||
OldSTO->getValueSymbolTable().remove(&V);
|
OldSTO->getValueSymbolTable().removeValueName(V.getValueName());
|
||||||
V.setParent(NewIP);
|
V.setParent(NewIP);
|
||||||
if (NewSTO && HasName)
|
if (NewSTO && HasName)
|
||||||
NewSTO->getValueSymbolTable().insert(&V);
|
NewSTO->getValueSymbolTable().reinsertValue(&V);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Just transferring between blocks in the same function, simply update the
|
// Just transferring between blocks in the same function, simply update the
|
||||||
|
|
|
@ -30,15 +30,13 @@ static inline const Type *checkType(const Type *Ty) {
|
||||||
return Ty;
|
return Ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::Value(const Type *ty, unsigned scid, const std::string &name)
|
Value::Value(const Type *ty, unsigned scid)
|
||||||
: SubclassID(scid), SubclassData(0), Ty(checkType(ty)),
|
: SubclassID(scid), SubclassData(0), Ty(checkType(ty)),
|
||||||
UseList(0), Name(name) {
|
UseList(0), Name(0) {
|
||||||
if (!isa<Constant>(this) && !isa<BasicBlock>(this))
|
if (!isa<Constant>(this) && !isa<BasicBlock>(this))
|
||||||
assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
|
assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
|
||||||
isa<OpaqueType>(ty)) &&
|
isa<OpaqueType>(ty)) &&
|
||||||
"Cannot create non-first-class values except for constants!");
|
"Cannot create non-first-class values except for constants!");
|
||||||
if (ty == Type::VoidTy)
|
|
||||||
assert(name.empty() && "Cannot have named void values!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::~Value() {
|
Value::~Value() {
|
||||||
|
@ -114,29 +112,62 @@ static bool getSymTab(Value *V, ValueSymbolTable *&ST) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::setName(const std::string &name) {
|
std::string Value::getName() const {
|
||||||
if (Name == name) return; // Name is already set.
|
if (Name == 0) return "";
|
||||||
|
return std::string(Name->getKeyData(),
|
||||||
|
Name->getKeyData()+Name->getKeyLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setName(const std::string &name) {
|
||||||
|
if (name.empty() && !hasName()) return;
|
||||||
|
if (getType() != Type::VoidTy && "Cannot assign a name to void values!");
|
||||||
|
|
||||||
|
|
||||||
// Get the symbol table to update for this object.
|
// Get the symbol table to update for this object.
|
||||||
ValueSymbolTable *ST;
|
ValueSymbolTable *ST;
|
||||||
if (getSymTab(this, ST))
|
if (getSymTab(this, ST))
|
||||||
return; // Cannot set a name on this value (e.g. constant).
|
return; // Cannot set a name on this value (e.g. constant).
|
||||||
|
|
||||||
if (!ST) // No symbol table to update? Just do the change.
|
if (!ST) { // No symbol table to update? Just do the change.
|
||||||
Name = name;
|
if (name.empty()) {
|
||||||
else if (hasName()) {
|
// Free the name for this value.
|
||||||
if (!name.empty()) { // Replacing name.
|
Name->Destroy();
|
||||||
ST->remove(this);
|
Name = 0;
|
||||||
Name = name;
|
} else {
|
||||||
ST->insert(this);
|
if (Name) {
|
||||||
} else { // Transitioning from hasName -> noname.
|
// Name isn't changing.
|
||||||
ST->remove(this);
|
if (name.size() == Name->getKeyLength() &&
|
||||||
Name.clear();
|
!memcmp(Name->getKeyData(), &name[0], name.size()))
|
||||||
|
return;
|
||||||
|
Name->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new name.
|
||||||
|
Name = ValueName::Create(&name[0], &name[name.size()]);
|
||||||
|
Name->setValue(this);
|
||||||
}
|
}
|
||||||
} else { // Transitioning from noname -> hasName.
|
return;
|
||||||
Name = name;
|
|
||||||
ST->insert(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Could optimize for the case the name is shrinking to not deallocate
|
||||||
|
// then reallocated.
|
||||||
|
if (hasName()) {
|
||||||
|
// Name isn't changing?
|
||||||
|
if (name.size() == Name->getKeyLength() &&
|
||||||
|
!memcmp(Name->getKeyData(), &name[0], name.size()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove old name.
|
||||||
|
ST->removeValueName(Name);
|
||||||
|
Name->Destroy();
|
||||||
|
Name = 0;
|
||||||
|
|
||||||
|
if (name.empty())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name is changing to something new.
|
||||||
|
Name = ST->createValueName(&name[0], name.size(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// takeName - transfer the name from V to this value, setting V's name to
|
/// takeName - transfer the name from V to this value, setting V's name to
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "llvm/ValueSymbolTable.h"
|
#include "llvm/ValueSymbolTable.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include <algorithm>
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
// Class destructor
|
// Class destructor
|
||||||
|
@ -25,8 +24,8 @@ ValueSymbolTable::~ValueSymbolTable() {
|
||||||
#ifndef NDEBUG // Only do this in -g mode...
|
#ifndef NDEBUG // Only do this in -g mode...
|
||||||
for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI)
|
for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI)
|
||||||
DEBUG(DOUT << "Value still in symbol table! Type = '"
|
DEBUG(DOUT << "Value still in symbol table! Type = '"
|
||||||
<< VI->second->getType()->getDescription() << "' Name = '"
|
<< VI->getValue()->getType()->getDescription() << "' Name = '"
|
||||||
<< VI->first << "'\n");
|
<< VI->getKeyData() << "'\n");
|
||||||
assert(vmap.empty() && "Values remain in symbol table!");
|
assert(vmap.empty() && "Values remain in symbol table!");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -37,11 +36,11 @@ ValueSymbolTable::~ValueSymbolTable() {
|
||||||
//
|
//
|
||||||
std::string ValueSymbolTable::getUniqueName(const std::string &BaseName) const {
|
std::string ValueSymbolTable::getUniqueName(const std::string &BaseName) const {
|
||||||
std::string TryName = BaseName;
|
std::string TryName = BaseName;
|
||||||
const_iterator End = vmap.end();
|
|
||||||
|
|
||||||
// See if the name exists
|
// See if the name exists
|
||||||
while (vmap.find(TryName) != End) // Loop until we find a free
|
while (vmap.find(&TryName[0], &TryName[TryName.size()]) != vmap.end())
|
||||||
TryName = BaseName + utostr(++LastUnique); // name in the symbol table
|
// Loop until we find a free name in the symbol table.
|
||||||
|
TryName = BaseName + utostr(++LastUnique);
|
||||||
return TryName;
|
return TryName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,62 +48,95 @@ std::string ValueSymbolTable::getUniqueName(const std::string &BaseName) const {
|
||||||
// lookup a value - Returns null on failure...
|
// lookup a value - Returns null on failure...
|
||||||
//
|
//
|
||||||
Value *ValueSymbolTable::lookup(const std::string &Name) const {
|
Value *ValueSymbolTable::lookup(const std::string &Name) const {
|
||||||
const_iterator VI = vmap.find(Name);
|
const_iterator VI = vmap.find(&Name[0], &Name[Name.size()]);
|
||||||
if (VI != vmap.end()) // We found the symbol
|
if (VI != vmap.end()) // We found the symbol
|
||||||
return const_cast<Value*>(VI->second);
|
return VI->getValue();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert a value into the symbol table with the specified name...
|
// Insert a value into the symbol table with the specified name...
|
||||||
//
|
//
|
||||||
void ValueSymbolTable::insert(Value* V) {
|
void ValueSymbolTable::reinsertValue(Value* V) {
|
||||||
assert(V && "Can't insert null Value into symbol table!");
|
|
||||||
assert(V->hasName() && "Can't insert nameless Value into symbol table");
|
assert(V->hasName() && "Can't insert nameless Value into symbol table");
|
||||||
|
|
||||||
// Try inserting the name, assuming it won't conflict.
|
// Try inserting the name, assuming it won't conflict.
|
||||||
if (vmap.insert(make_pair(V->Name, V)).second) {
|
if (vmap.insert(V->Name)) {
|
||||||
DOUT << " Inserted value: " << V->Name << ": " << *V << "\n";
|
DOUT << " Inserted value: " << V->Name << ": " << *V << "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: this could be much more efficient.
|
||||||
|
|
||||||
// Otherwise, there is a naming conflict. Rename this value.
|
// Otherwise, there is a naming conflict. Rename this value.
|
||||||
std::string UniqueName = V->getName();
|
std::string UniqueName = V->getName();
|
||||||
|
|
||||||
|
V->Name->Destroy();
|
||||||
|
|
||||||
unsigned BaseSize = UniqueName.size();
|
unsigned BaseSize = UniqueName.size();
|
||||||
do {
|
while (1) {
|
||||||
// Trim any suffix off.
|
// Trim any suffix off.
|
||||||
UniqueName.resize(BaseSize);
|
UniqueName.resize(BaseSize);
|
||||||
UniqueName += utostr(++LastUnique);
|
UniqueName += utostr(++LastUnique);
|
||||||
// Try insert the vmap entry with this suffix.
|
// Try insert the vmap entry with this suffix.
|
||||||
} while (!vmap.insert(make_pair(UniqueName, V)).second);
|
ValueName &NewName = vmap.GetOrCreateValue(&UniqueName[0],
|
||||||
|
&UniqueName[UniqueName.size()]);
|
||||||
|
if (NewName.getValue() == 0) {
|
||||||
|
// Newly inserted name. Success!
|
||||||
|
NewName.setValue(V);
|
||||||
|
V->Name = &NewName;
|
||||||
|
DEBUG(DOUT << " Inserted value: " << UniqueName << ": " << *V << "\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
V->Name = UniqueName;
|
void ValueSymbolTable::removeValueName(ValueName *V) {
|
||||||
|
DEBUG(DOUT << " Removing Value: " << V->getKeyData() << "\n");
|
||||||
|
// Remove the value from the plane.
|
||||||
|
vmap.remove(V);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// createValueName - This method attempts to create a value name and insert
|
||||||
|
/// it into the symbol table with the specified name. If it conflicts, it
|
||||||
|
/// auto-renames the name and returns that instead.
|
||||||
|
ValueName *ValueSymbolTable::createValueName(const char *NameStart,
|
||||||
|
unsigned NameLen, Value *V) {
|
||||||
|
ValueName &Entry = vmap.GetOrCreateValue(NameStart, NameStart+NameLen);
|
||||||
|
if (Entry.getValue() == 0) {
|
||||||
|
Entry.setValue(V);
|
||||||
|
DEBUG(DOUT << " Inserted value: " << Entry.getKeyData() << ": "
|
||||||
|
<< *V << "\n");
|
||||||
|
return &Entry;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG(DOUT << " Inserted value: " << UniqueName << ": " << *V << "\n");
|
// FIXME: this could be much more efficient.
|
||||||
|
|
||||||
|
// Otherwise, there is a naming conflict. Rename this value.
|
||||||
|
std::string UniqueName(NameStart, NameStart+NameLen);
|
||||||
|
while (1) {
|
||||||
|
// Trim any suffix off.
|
||||||
|
UniqueName.resize(NameLen);
|
||||||
|
UniqueName += utostr(++LastUnique);
|
||||||
|
// Try insert the vmap entry with this suffix.
|
||||||
|
ValueName &NewName = vmap.GetOrCreateValue(&UniqueName[0],
|
||||||
|
&UniqueName[UniqueName.size()]);
|
||||||
|
if (NewName.getValue() == 0) {
|
||||||
|
// Newly inserted name. Success!
|
||||||
|
NewName.setValue(V);
|
||||||
|
DEBUG(DOUT << " Inserted value: " << UniqueName << ": " << *V << "\n");
|
||||||
|
return &NewName;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a value
|
|
||||||
void ValueSymbolTable::remove(Value *V) {
|
|
||||||
assert(V->hasName() && "Value doesn't have name!");
|
|
||||||
iterator Entry = vmap.find(V->getName());
|
|
||||||
assert(Entry != vmap.end() && "Entry was not in the symtab!");
|
|
||||||
|
|
||||||
DEBUG(DOUT << " Removing Value: " << Entry->second->getName() << "\n");
|
|
||||||
|
|
||||||
// Remove the value from the plane...
|
|
||||||
vmap.erase(Entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// DumpVal - a std::for_each function for dumping a value
|
|
||||||
//
|
|
||||||
static void DumpVal(const std::pair<const std::string, Value *> &V) {
|
|
||||||
DOUT << " '" << V.first << "' = ";
|
|
||||||
V.second->dump();
|
|
||||||
DOUT << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// dump - print out the symbol table
|
// dump - print out the symbol table
|
||||||
//
|
//
|
||||||
void ValueSymbolTable::dump() const {
|
void ValueSymbolTable::dump() const {
|
||||||
DOUT << "ValueSymbolTable:\n";
|
DOUT << "ValueSymbolTable:\n";
|
||||||
for_each(vmap.begin(), vmap.end(), DumpVal);
|
for (const_iterator I = begin(), E = end(); I != E; ++I) {
|
||||||
|
DOUT << " '" << I->getKeyData() << "' = ";
|
||||||
|
I->getValue()->dump();
|
||||||
|
DOUT << "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/Intrinsics.h"
|
#include "llvm/Intrinsics.h"
|
||||||
#include "llvm/PassManager.h"
|
#include "llvm/PassManager.h"
|
||||||
#include "llvm/ValueSymbolTable.h"
|
|
||||||
#include "llvm/Analysis/Dominators.h"
|
#include "llvm/Analysis/Dominators.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
#include "llvm/Support/InstVisitor.h"
|
#include "llvm/Support/InstVisitor.h"
|
||||||
|
@ -102,7 +101,6 @@ namespace { // Anonymous namespace for class
|
||||||
bool doInitialization(Module &M) {
|
bool doInitialization(Module &M) {
|
||||||
Mod = &M;
|
Mod = &M;
|
||||||
verifyTypeSymbolTable(M.getTypeSymbolTable());
|
verifyTypeSymbolTable(M.getTypeSymbolTable());
|
||||||
verifyValueSymbolTable(M.getValueSymbolTable());
|
|
||||||
|
|
||||||
// If this is a real pass, in a pass manager, we must abort before
|
// If this is a real pass, in a pass manager, we must abort before
|
||||||
// returning back to the pass manager, or else the pass manager may try to
|
// returning back to the pass manager, or else the pass manager may try to
|
||||||
|
@ -177,7 +175,6 @@ namespace { // Anonymous namespace for class
|
||||||
|
|
||||||
// Verification methods...
|
// Verification methods...
|
||||||
void verifyTypeSymbolTable(TypeSymbolTable &ST);
|
void verifyTypeSymbolTable(TypeSymbolTable &ST);
|
||||||
void verifyValueSymbolTable(ValueSymbolTable &ST);
|
|
||||||
void visitGlobalValue(GlobalValue &GV);
|
void visitGlobalValue(GlobalValue &GV);
|
||||||
void visitGlobalVariable(GlobalVariable &GV);
|
void visitGlobalVariable(GlobalVariable &GV);
|
||||||
void visitFunction(Function &F);
|
void visitFunction(Function &F);
|
||||||
|
@ -307,22 +304,6 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
|
||||||
void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) {
|
void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifySymbolTable - Verify that a function or module symbol table is ok
|
|
||||||
//
|
|
||||||
void Verifier::verifyValueSymbolTable(ValueSymbolTable &ST) {
|
|
||||||
|
|
||||||
// Loop over all of the values in the symbol table.
|
|
||||||
for (ValueSymbolTable::const_iterator VI = ST.begin(), VE = ST.end();
|
|
||||||
VI != VE; ++VI) {
|
|
||||||
Value *V = VI->second;
|
|
||||||
// Check that there are no void typed values in the symbol table. Values
|
|
||||||
// with a void type cannot be put into symbol tables because they cannot
|
|
||||||
// have names!
|
|
||||||
Assert1(V->getType() != Type::VoidTy,
|
|
||||||
"Values with void type are not allowed to have names!", V);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// visitFunction - Verify that a function is ok.
|
// visitFunction - Verify that a function is ok.
|
||||||
//
|
//
|
||||||
void Verifier::visitFunction(Function &F) {
|
void Verifier::visitFunction(Function &F) {
|
||||||
|
@ -375,8 +356,6 @@ void Verifier::visitFunction(Function &F) {
|
||||||
Assert1(F.getName().substr(0, 5) != "llvm.",
|
Assert1(F.getName().substr(0, 5) != "llvm.",
|
||||||
"llvm intrinsics cannot be defined!", &F);
|
"llvm intrinsics cannot be defined!", &F);
|
||||||
|
|
||||||
verifyValueSymbolTable(F.getValueSymbolTable());
|
|
||||||
|
|
||||||
// Check the entry node
|
// Check the entry node
|
||||||
BasicBlock *Entry = &F.getEntryBlock();
|
BasicBlock *Entry = &F.getEntryBlock();
|
||||||
Assert1(pred_begin(Entry) == pred_end(Entry),
|
Assert1(pred_begin(Entry) == pred_end(Entry),
|
||||||
|
|
Loading…
Reference in New Issue