rearrange code and make more legible.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54976 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2008-08-19 04:36:02 +00:00
parent b64871a6ad
commit 6ab910b946

View File

@ -40,6 +40,165 @@ using namespace llvm;
// Make virtual table appear in this compilation unit.
AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {}
char PrintModulePass::ID = 0;
static RegisterPass<PrintModulePass>
X("printm", "Print module to stderr");
char PrintFunctionPass::ID = 0;
static RegisterPass<PrintFunctionPass>
Y("print","Print function to stderr");
//===----------------------------------------------------------------------===//
// Helper Functions
//===----------------------------------------------------------------------===//
static const Module *getModuleFromVal(const Value *V) {
if (const Argument *MA = dyn_cast<Argument>(V))
return MA->getParent() ? MA->getParent()->getParent() : 0;
if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
return BB->getParent() ? BB->getParent()->getParent() : 0;
if (const Instruction *I = dyn_cast<Instruction>(V)) {
const Function *M = I->getParent() ? I->getParent()->getParent() : 0;
return M ? M->getParent() : 0;
}
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
return GV->getParent();
return 0;
}
/// NameNeedsQuotes - Return true if the specified llvm name should be wrapped
/// with ""'s.
static std::string QuoteNameIfNeeded(const std::string &Name) {
std::string result;
bool needsQuotes = Name[0] >= '0' && Name[0] <= '9';
// Scan the name to see if it needs quotes and to replace funky chars with
// their octal equivalent.
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
char C = Name[i];
assert(C != '"' && "Illegal character in LLVM value name!");
if (isalnum(C) || C == '-' || C == '.' || C == '_')
result += C;
else if (C == '\\') {
needsQuotes = true;
result += "\\\\";
} else if (isprint(C)) {
needsQuotes = true;
result += C;
} else {
needsQuotes = true;
result += "\\";
char hex1 = (C >> 4) & 0x0F;
if (hex1 < 10)
result += hex1 + '0';
else
result += hex1 - 10 + 'A';
char hex2 = C & 0x0F;
if (hex2 < 10)
result += hex2 + '0';
else
result += hex2 - 10 + 'A';
}
}
if (needsQuotes) {
result.insert(0,"\"");
result += '"';
}
return result;
}
/// getLLVMName - Turn the specified string into an 'LLVM name', which is either
/// prefixed with % (if the string only contains simple characters) or is
/// surrounded with ""'s (if it has special chars in it).
static std::string getLLVMName(const std::string &Name) {
assert(!Name.empty() && "Cannot get empty name!");
return '%' + QuoteNameIfNeeded(Name);
}
enum PrefixType {
GlobalPrefix,
LabelPrefix,
LocalPrefix
};
/// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either
/// prefixed with % (if the string only contains simple characters) or is
/// surrounded with ""'s (if it has special chars in it). Print it out.
static void PrintLLVMName(std::ostream &OS, const ValueName *Name,
PrefixType Prefix) {
assert(Name && "Cannot get empty name!");
switch (Prefix) {
default: assert(0 && "Bad prefix!");
case GlobalPrefix: OS << '@'; break;
case LabelPrefix: break;
case LocalPrefix: OS << '%'; break;
}
// Scan the name to see if it needs quotes first.
const char *NameStr = Name->getKeyData();
unsigned NameLen = Name->getKeyLength();
bool NeedsQuotes = NameStr[0] >= '0' && NameStr[0] <= '9';
if (!NeedsQuotes) {
for (unsigned i = 0; i != NameLen; ++i) {
char C = NameStr[i];
if (!isalnum(C) && C != '-' && C != '.' && C != '_') {
NeedsQuotes = true;
break;
}
}
}
// If we didn't need any quotes, just write out the name in one blast.
if (!NeedsQuotes) {
OS.write(NameStr, NameLen);
return;
}
// Okay, we need quotes. Output the quotes and escape any scary characters as
// needed.
OS << '"';
for (unsigned i = 0; i != NameLen; ++i) {
char C = NameStr[i];
assert(C != '"' && "Illegal character in LLVM value name!");
if (C == '\\') {
OS << "\\\\";
} else if (isprint(C)) {
OS << C;
} else {
OS << '\\';
char hex1 = (C >> 4) & 0x0F;
if (hex1 < 10)
OS << (char)(hex1 + '0');
else
OS << (char)(hex1 - 10 + 'A');
char hex2 = C & 0x0F;
if (hex2 < 10)
OS << (char)(hex2 + '0');
else
OS << (char)(hex2 - 10 + 'A');
}
}
OS << '"';
}
/// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either
/// prefixed with % (if the string only contains simple characters) or is
/// surrounded with ""'s (if it has special chars in it). Print it out.
static void PrintLLVMName(std::ostream &OS, const Value *V) {
PrintLLVMName(OS, V->getValueName(),
isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
}
//===----------------------------------------------------------------------===//
// SlotTracker Class: Enumerate slot numbers for unnamed values
//===----------------------------------------------------------------------===//
namespace {
/// This class provides computation of slot numbers for LLVM Assembly writing.
@ -112,166 +271,188 @@ private:
} // end anonymous namespace
char PrintModulePass::ID = 0;
static RegisterPass<PrintModulePass>
X("printm", "Print module to stderr");
char PrintFunctionPass::ID = 0;
static RegisterPass<PrintFunctionPass>
Y("print","Print function to stderr");
static SlotTracker *createSlotTracker(const Value *V) {
if (const Argument *FA = dyn_cast<Argument>(V))
return new SlotTracker(FA->getParent());
if (const Instruction *I = dyn_cast<Instruction>(V))
return new SlotTracker(I->getParent()->getParent());
if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
return new SlotTracker(BB->getParent());
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
return new SlotTracker(GV->getParent());
if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
return new SlotTracker(GA->getParent());
if (const Function *Func = dyn_cast<Function>(V))
return new SlotTracker(Func);
return 0;
}
#if 0
#define SC_DEBUG(X) cerr << X
#else
#define SC_DEBUG(X)
#endif
// Module level constructor. Causes the contents of the Module (sans functions)
// to be added to the slot table.
SlotTracker::SlotTracker(const Module *M)
: TheModule(M) ///< Saved for lazy initialization.
, TheFunction(0)
, FunctionProcessed(false)
, mNext(0), fNext(0)
{
}
// Function level constructor. Causes the contents of the Module and the one
// function provided to be added to the slot table.
SlotTracker::SlotTracker(const Function *F)
: TheModule(F ? F->getParent() : 0) ///< Saved for lazy initialization
, TheFunction(F) ///< Saved for lazy initialization
, FunctionProcessed(false)
, mNext(0), fNext(0)
{
}
inline void SlotTracker::initialize() {
if (TheModule) {
processModule();
TheModule = 0; ///< Prevent re-processing next time we're called.
}
if (TheFunction && !FunctionProcessed)
processFunction();
}
// Iterate through all the global variables, functions, and global
// variable initializers and create slots for them.
void SlotTracker::processModule() {
SC_DEBUG("begin processModule!\n");
// Add all of the unnamed global variables to the value table.
for (Module::const_global_iterator I = TheModule->global_begin(),
E = TheModule->global_end(); I != E; ++I)
if (!I->hasName())
CreateModuleSlot(I);
// Add all the unnamed functions to the table.
for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
I != E; ++I)
if (!I->hasName())
CreateModuleSlot(I);
SC_DEBUG("end processModule!\n");
}
// Process the arguments, basic blocks, and instructions of a function.
void SlotTracker::processFunction() {
SC_DEBUG("begin processFunction!\n");
fNext = 0;
// Add all the function arguments with no names.
for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
AE = TheFunction->arg_end(); AI != AE; ++AI)
if (!AI->hasName())
CreateFunctionSlot(AI);
SC_DEBUG("Inserting Instructions:\n");
// Add all of the basic blocks and instructions with no names.
for (Function::const_iterator BB = TheFunction->begin(),
E = TheFunction->end(); BB != E; ++BB) {
if (!BB->hasName())
CreateFunctionSlot(BB);
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
if (I->getType() != Type::VoidTy && !I->hasName())
CreateFunctionSlot(I);
}
FunctionProcessed = true;
SC_DEBUG("end processFunction!\n");
}
/// Clean up after incorporating a function. This is the only way to get out of
/// the function incorporation state that affects get*Slot/Create*Slot. Function
/// incorporation state is indicated by TheFunction != 0.
void SlotTracker::purgeFunction() {
SC_DEBUG("begin purgeFunction!\n");
fMap.clear(); // Simply discard the function level map
TheFunction = 0;
FunctionProcessed = false;
SC_DEBUG("end purgeFunction!\n");
}
/// getGlobalSlot - Get the slot number of a global value.
int SlotTracker::getGlobalSlot(const GlobalValue *V) {
// Check for uninitialized state and do lazy initialization.
initialize();
// Find the type plane in the module map
ValueMap::iterator MI = mMap.find(V);
return MI == mMap.end() ? -1 : MI->second;
}
/// getLocalSlot - Get the slot number for a value that is local to a function.
int SlotTracker::getLocalSlot(const Value *V) {
assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!");
// Check for uninitialized state and do lazy initialization.
initialize();
ValueMap::iterator FI = fMap.find(V);
return FI == fMap.end() ? -1 : FI->second;
}
/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
assert(V && "Can't insert a null Value into SlotTracker!");
assert(V->getType() != Type::VoidTy && "Doesn't need a slot!");
assert(!V->hasName() && "Doesn't need a slot!");
unsigned DestSlot = mNext++;
mMap[V] = DestSlot;
SC_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
DestSlot << " [");
// G = Global, F = Function, A = Alias, o = other
SC_DEBUG((isa<GlobalVariable>(V) ? 'G' :
(isa<Function>(V) ? 'F' :
(isa<GlobalAlias>(V) ? 'A' : 'o'))) << "]\n");
}
/// CreateSlot - Create a new slot for the specified value if it has no name.
void SlotTracker::CreateFunctionSlot(const Value *V) {
assert(V->getType() != Type::VoidTy && !V->hasName() &&
"Doesn't need a slot!");
unsigned DestSlot = fNext++;
fMap[V] = DestSlot;
// G = Global, F = Function, o = other
SC_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
DestSlot << " [o]\n");
}
//===----------------------------------------------------------------------===//
// AsmWriter Implementation
//===----------------------------------------------------------------------===//
static void WriteAsOperandInternal(std::ostream &Out, const Value *V,
std::map<const Type *, std::string> &TypeTable,
SlotTracker *Machine);
static const Module *getModuleFromVal(const Value *V) {
if (const Argument *MA = dyn_cast<Argument>(V))
return MA->getParent() ? MA->getParent()->getParent() : 0;
else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
return BB->getParent() ? BB->getParent()->getParent() : 0;
else if (const Instruction *I = dyn_cast<Instruction>(V)) {
const Function *M = I->getParent() ? I->getParent()->getParent() : 0;
return M ? M->getParent() : 0;
} else if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
return GV->getParent();
return 0;
}
static SlotTracker *createSlotTracker(const Value *V) {
if (const Argument *FA = dyn_cast<Argument>(V)) {
return new SlotTracker(FA->getParent());
} else if (const Instruction *I = dyn_cast<Instruction>(V)) {
return new SlotTracker(I->getParent()->getParent());
} else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V)) {
return new SlotTracker(BB->getParent());
} else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)){
return new SlotTracker(GV->getParent());
} else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V)){
return new SlotTracker(GA->getParent());
} else if (const Function *Func = dyn_cast<Function>(V)) {
return new SlotTracker(Func);
}
return 0;
}
/// NameNeedsQuotes - Return true if the specified llvm name should be wrapped
/// with ""'s.
static std::string QuoteNameIfNeeded(const std::string &Name) {
std::string result;
bool needsQuotes = Name[0] >= '0' && Name[0] <= '9';
// Scan the name to see if it needs quotes and to replace funky chars with
// their octal equivalent.
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
char C = Name[i];
assert(C != '"' && "Illegal character in LLVM value name!");
if (isalnum(C) || C == '-' || C == '.' || C == '_')
result += C;
else if (C == '\\') {
needsQuotes = true;
result += "\\\\";
} else if (isprint(C)) {
needsQuotes = true;
result += C;
} else {
needsQuotes = true;
result += "\\";
char hex1 = (C >> 4) & 0x0F;
if (hex1 < 10)
result += hex1 + '0';
else
result += hex1 - 10 + 'A';
char hex2 = C & 0x0F;
if (hex2 < 10)
result += hex2 + '0';
else
result += hex2 - 10 + 'A';
}
}
if (needsQuotes) {
result.insert(0,"\"");
result += '"';
}
return result;
}
/// getLLVMName - Turn the specified string into an 'LLVM name', which is either
/// prefixed with % (if the string only contains simple characters) or is
/// surrounded with ""'s (if it has special chars in it).
static std::string getLLVMName(const std::string &Name) {
assert(!Name.empty() && "Cannot get empty name!");
return '%' + QuoteNameIfNeeded(Name);
}
enum PrefixType {
GlobalPrefix,
LabelPrefix,
LocalPrefix
};
/// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either
/// prefixed with % (if the string only contains simple characters) or is
/// surrounded with ""'s (if it has special chars in it). Print it out.
static void PrintLLVMName(std::ostream &OS, const ValueName *Name,
PrefixType Prefix) {
assert(Name && "Cannot get empty name!");
switch (Prefix) {
default: assert(0 && "Bad prefix!");
case GlobalPrefix: OS << '@'; break;
case LabelPrefix: break;
case LocalPrefix: OS << '%'; break;
}
// Scan the name to see if it needs quotes first.
const char *NameStr = Name->getKeyData();
unsigned NameLen = Name->getKeyLength();
bool NeedsQuotes = NameStr[0] >= '0' && NameStr[0] <= '9';
if (!NeedsQuotes) {
for (unsigned i = 0; i != NameLen; ++i) {
char C = NameStr[i];
if (!isalnum(C) && C != '-' && C != '.' && C != '_') {
NeedsQuotes = true;
break;
}
}
}
// If we didn't need any quotes, just write out the name in one blast.
if (!NeedsQuotes) {
OS.write(NameStr, NameLen);
return;
}
// Okay, we need quotes. Output the quotes and escape any scary characters as
// needed.
OS << '"';
for (unsigned i = 0; i != NameLen; ++i) {
char C = NameStr[i];
assert(C != '"' && "Illegal character in LLVM value name!");
if (C == '\\') {
OS << "\\\\";
} else if (isprint(C)) {
OS << C;
} else {
OS << '\\';
char hex1 = (C >> 4) & 0x0F;
if (hex1 < 10)
OS << (char)(hex1 + '0');
else
OS << (char)(hex1 - 10 + 'A');
char hex2 = C & 0x0F;
if (hex2 < 10)
OS << (char)(hex2 + '0');
else
OS << (char)(hex2 - 10 + 'A');
}
}
OS << '"';
}
static void PrintLLVMName(std::ostream &OS, const Value *V) {
PrintLLVMName(OS, V->getValueName(),
isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
}
/// fillTypeNameTable - If the module has a symbol table, take all global types
@ -1585,155 +1766,3 @@ void Value::dump() const { print(*cerr.stream()); cerr << '\n'; }
// Located here because so much of the needed functionality is here.
void Type::dump() const { print(*cerr.stream()); cerr << '\n'; }
//===----------------------------------------------------------------------===//
// SlotTracker Implementation
//===----------------------------------------------------------------------===//
#if 0
#define SC_DEBUG(X) cerr << X
#else
#define SC_DEBUG(X)
#endif
// Module level constructor. Causes the contents of the Module (sans functions)
// to be added to the slot table.
SlotTracker::SlotTracker(const Module *M)
: TheModule(M) ///< Saved for lazy initialization.
, TheFunction(0)
, FunctionProcessed(false)
, mNext(0), fNext(0)
{
}
// Function level constructor. Causes the contents of the Module and the one
// function provided to be added to the slot table.
SlotTracker::SlotTracker(const Function *F)
: TheModule(F ? F->getParent() : 0) ///< Saved for lazy initialization
, TheFunction(F) ///< Saved for lazy initialization
, FunctionProcessed(false)
, mNext(0), fNext(0)
{
}
inline void SlotTracker::initialize() {
if (TheModule) {
processModule();
TheModule = 0; ///< Prevent re-processing next time we're called.
}
if (TheFunction && !FunctionProcessed)
processFunction();
}
// Iterate through all the global variables, functions, and global
// variable initializers and create slots for them.
void SlotTracker::processModule() {
SC_DEBUG("begin processModule!\n");
// Add all of the unnamed global variables to the value table.
for (Module::const_global_iterator I = TheModule->global_begin(),
E = TheModule->global_end(); I != E; ++I)
if (!I->hasName())
CreateModuleSlot(I);
// Add all the unnamed functions to the table.
for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
I != E; ++I)
if (!I->hasName())
CreateModuleSlot(I);
SC_DEBUG("end processModule!\n");
}
// Process the arguments, basic blocks, and instructions of a function.
void SlotTracker::processFunction() {
SC_DEBUG("begin processFunction!\n");
fNext = 0;
// Add all the function arguments with no names.
for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
AE = TheFunction->arg_end(); AI != AE; ++AI)
if (!AI->hasName())
CreateFunctionSlot(AI);
SC_DEBUG("Inserting Instructions:\n");
// Add all of the basic blocks and instructions with no names.
for (Function::const_iterator BB = TheFunction->begin(),
E = TheFunction->end(); BB != E; ++BB) {
if (!BB->hasName())
CreateFunctionSlot(BB);
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
if (I->getType() != Type::VoidTy && !I->hasName())
CreateFunctionSlot(I);
}
FunctionProcessed = true;
SC_DEBUG("end processFunction!\n");
}
/// Clean up after incorporating a function. This is the only way to get out of
/// the function incorporation state that affects get*Slot/Create*Slot. Function
/// incorporation state is indicated by TheFunction != 0.
void SlotTracker::purgeFunction() {
SC_DEBUG("begin purgeFunction!\n");
fMap.clear(); // Simply discard the function level map
TheFunction = 0;
FunctionProcessed = false;
SC_DEBUG("end purgeFunction!\n");
}
/// getGlobalSlot - Get the slot number of a global value.
int SlotTracker::getGlobalSlot(const GlobalValue *V) {
// Check for uninitialized state and do lazy initialization.
initialize();
// Find the type plane in the module map
ValueMap::iterator MI = mMap.find(V);
return MI == mMap.end() ? -1 : MI->second;
}
/// getLocalSlot - Get the slot number for a value that is local to a function.
int SlotTracker::getLocalSlot(const Value *V) {
assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!");
// Check for uninitialized state and do lazy initialization.
initialize();
ValueMap::iterator FI = fMap.find(V);
return FI == fMap.end() ? -1 : FI->second;
}
/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
assert(V && "Can't insert a null Value into SlotTracker!");
assert(V->getType() != Type::VoidTy && "Doesn't need a slot!");
assert(!V->hasName() && "Doesn't need a slot!");
unsigned DestSlot = mNext++;
mMap[V] = DestSlot;
SC_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
DestSlot << " [");
// G = Global, F = Function, A = Alias, o = other
SC_DEBUG((isa<GlobalVariable>(V) ? 'G' :
(isa<Function>(V) ? 'F' :
(isa<GlobalAlias>(V) ? 'A' : 'o'))) << "]\n");
}
/// CreateSlot - Create a new slot for the specified value if it has no name.
void SlotTracker::CreateFunctionSlot(const Value *V) {
assert(V->getType() != Type::VoidTy && !V->hasName() &&
"Doesn't need a slot!");
unsigned DestSlot = fNext++;
fMap[V] = DestSlot;
// G = Global, F = Function, o = other
SC_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
DestSlot << " [o]\n");
}