mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
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:
parent
b64871a6ad
commit
6ab910b946
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user