#include "llvm/Instruction.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
-#include "llvm/SymbolTable.h"
+#include "llvm/ValueSymbolTable.h"
+#include "llvm/TypeSymbolTable.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CFG.h"
/// @{
public:
/// Return the slot number of the specified value in it's type
- /// plane. Its an error to ask for something not in the SlotMachine.
- /// Its an error to ask for a Type*
- int getSlot(const Value *V);
+ /// plane. If something is not in the SlotMachine, return -1.
+ int getLocalSlot(const Value *V);
+ int getGlobalSlot(const GlobalValue *V);
/// @}
/// @name Mutators
/// This function does the actual initialization.
inline void initialize();
- /// Values can be crammed into here at will. If they haven't
- /// been inserted already, they get inserted, otherwise they are ignored.
- /// Either way, the slot number for the Value* is returned.
- unsigned getOrCreateSlot(const Value *V);
-
- /// Insert a value into the value table. Return the slot number
- /// that it now occupies. BadThings(TM) will happen if you insert a
- /// Value that's already been inserted.
- unsigned insertValue(const Value *V);
+ /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
+ void CreateModuleSlot(const GlobalValue *V);
+
+ /// CreateFunctionSlot - Insert the specified Value* into the slot table.
+ void CreateFunctionSlot(const Value *V);
/// Add all of the module level global variables (and their initializers)
/// and function declarations, but not the contents of those functions.
return 0;
}
-// 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,
- bool prefixName = true) {
- assert(!Name.empty() && "Cannot get empty name!");
-
- // First character cannot start with a number...
- if (Name[0] >= '0' && Name[0] <= '9')
- return "\"" + Name + "\"";
-
+/// NameNeedsQuotes - Return true if the specified llvm name should be wrapped
+/// with ""'s.
+static bool NameNeedsQuotes(const std::string &Name) {
+ if (Name[0] >= '0' && Name[0] <= '9') return true;
// Scan to see if we have any characters that are not on the "white list"
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
char C = Name[i];
assert(C != '"' && "Illegal character in LLVM value name!");
if ((C < 'a' || C > 'z') && (C < 'A' || C > 'Z') && (C < '0' || C > '9') &&
C != '-' && C != '.' && C != '_')
- return "\"" + Name + "\"";
+ return true;
+ }
+ return false;
+}
+
+enum PrefixType {
+ GlobalPrefix,
+ LabelPrefix,
+ LocalPrefix
+};
+
+/// 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, PrefixType Prefix) {
+ assert(!Name.empty() && "Cannot get empty name!");
+
+ // First character cannot start with a number...
+ if (NameNeedsQuotes(Name)) {
+ if (Prefix == GlobalPrefix)
+ return "@\"" + Name + "\"";
+ return "\"" + Name + "\"";
}
// If we get here, then the identifier is legal to use as a "VarID".
- if (prefixName)
- return "%"+Name;
- else
- return Name;
+ switch (Prefix) {
+ default: assert(0 && "Bad prefix!");
+ case GlobalPrefix: return '@' + Name;
+ case LabelPrefix: return Name;
+ case LocalPrefix: return '%' + Name;
+ }
}
static void fillTypeNameTable(const Module *M,
std::map<const Type *, std::string> &TypeNames) {
if (!M) return;
- const SymbolTable &ST = M->getSymbolTable();
- SymbolTable::type_const_iterator TI = ST.type_begin();
- for (; TI != ST.type_end(); ++TI) {
+ const TypeSymbolTable &ST = M->getTypeSymbolTable();
+ TypeSymbolTable::const_iterator TI = ST.begin();
+ for (; TI != ST.end(); ++TI) {
// As a heuristic, don't insert pointer to primitive types, because
// they are used too often to have a single useful name.
//
const Type *Ty = cast<Type>(TI->second);
if (!isa<PointerType>(Ty) ||
!cast<PointerType>(Ty)->getElementType()->isPrimitiveType() ||
+ !cast<PointerType>(Ty)->getElementType()->isInteger() ||
isa<OpaqueType>(cast<PointerType>(Ty)->getElementType()))
- TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first)));
+ TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first, LocalPrefix)));
}
}
std::vector<const Type *> &TypeStack,
std::map<const Type *, std::string> &TypeNames,
std::string & Result){
- if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)) {
+ if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))) {
Result += Ty->getDescription(); // Base case
return;
}
TypeStack.push_back(Ty); // Recursive case: Add us to the stack..
switch (Ty->getTypeID()) {
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+ Result += "i" + utostr(BitWidth);
+ break;
+ }
case Type::FunctionTyID: {
const FunctionType *FTy = cast<FunctionType>(Ty);
calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result);
- if (FTy->getParamAttrs(0)) {
- Result += " ";
- Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(0));
- }
Result += " (";
unsigned Idx = 1;
for (FunctionType::param_iterator I = FTy->param_begin(),
Result += "...";
}
Result += ")";
+ if (FTy->getParamAttrs(0)) {
+ Result += " ";
+ Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(0));
+ }
break;
}
case Type::StructTyID: {
// Primitive types always print out their description, regardless of whether
// they have been named or not.
//
- if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))
+ if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)))
return Out << Ty->getDescription();
// Check to see if the type is named.
SlotMachine *Machine) {
const int IndentSize = 4;
static std::string Indent = "\n";
- if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
- Out << (CB->getValue() ? "true" : "false");
- } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- Out << CI->getSExtValue();
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+ if (CI->getType() == Type::Int1Ty)
+ Out << (CI->getZExtValue() ? "true" : "false");
+ else
+ Out << CI->getSExtValue();
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
// We would like to output the FP constant value in exponential notation,
// but we cannot do this if doing so will lose precision. Check here to
Out << " ]";
}
} else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
+ if (CS->getType()->isPacked())
+ Out << '<';
Out << '{';
unsigned N = CS->getNumOperands();
if (N) {
}
Out << " }";
+ if (CS->getType()->isPacked())
+ Out << '>';
} else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
const Type *ETy = CP->getType()->getElementType();
assert(CP->getNumOperands() > 0 &&
SlotMachine *Machine) {
Out << ' ';
if (V->hasName())
- Out << getLLVMName(V->getName());
+ Out << getLLVMName(V->getName(),
+ isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
else {
const Constant *CV = dyn_cast<Constant>(V);
if (CV && !isa<GlobalValue>(CV)) {
PrintEscapedString(IA->getConstraintString(), Out);
Out << '"';
} else {
+ char Prefix = '%';
int Slot;
if (Machine) {
- Slot = Machine->getSlot(V);
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ Slot = Machine->getGlobalSlot(GV);
+ Prefix = '@';
+ } else {
+ Slot = Machine->getLocalSlot(V);
+ }
} else {
Machine = createSlotMachine(V);
- if (Machine)
- Slot = Machine->getSlot(V);
- else
+ if (Machine) {
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ Slot = Machine->getGlobalSlot(GV);
+ Prefix = '@';
+ } else {
+ Slot = Machine->getLocalSlot(V);
+ }
+ } else {
Slot = -1;
+ }
delete Machine;
}
if (Slot != -1)
- Out << '%' << Slot;
+ Out << Prefix << Slot;
else
Out << "<badref>";
}
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 Constant *CPV) { printConstant(CPV); }
inline void write(const Type *Ty) { printType(Ty); }
void writeOperand(const Value *Op, bool PrintType);
private:
void printModule(const Module *M);
- void printSymbolTable(const SymbolTable &ST);
- void printConstant(const Constant *CPV);
+ void printTypeSymbolTable(const TypeSymbolTable &ST);
void printGlobal(const GlobalVariable *GV);
void printFunction(const Function *F);
void printArgument(const Argument *FA, FunctionType::ParameterAttributes A);
/// without considering any symbolic types that we may have equal to it.
///
std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
- if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
+ if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
+ Out << "i" << utostr(ITy->getBitWidth());
+ else if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
printType(FTy->getReturnType());
- if (FTy->getParamAttrs(0))
- Out << ' ' << FunctionType::getParamAttrsText(FTy->getParamAttrs(0));
Out << " (";
unsigned Idx = 1;
for (FunctionType::param_iterator I = FTy->param_begin(),
Out << "...";
}
Out << ')';
+ if (FTy->getParamAttrs(0))
+ Out << ' ' << FunctionType::getParamAttrsText(FTy->getParamAttrs(0));
} else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
if (STy->isPacked())
Out << '<';
if (!M->getDataLayout().empty())
Out << "target datalayout = \"" << M->getDataLayout() << "\"\n";
-
- switch (M->getEndianness()) {
- case Module::LittleEndian: Out << "target endian = little\n"; break;
- case Module::BigEndian: Out << "target endian = big\n"; break;
- case Module::AnyEndianness: break;
- }
- switch (M->getPointerSize()) {
- case Module::Pointer32: Out << "target pointersize = 32\n"; break;
- case Module::Pointer64: Out << "target pointersize = 64\n"; break;
- case Module::AnyPointerSize: break;
- }
if (!M->getTargetTriple().empty())
Out << "target triple = \"" << M->getTargetTriple() << "\"\n";
}
// Loop over the symbol table, emitting all named constants.
- printSymbolTable(M->getSymbolTable());
+ printTypeSymbolTable(M->getTypeSymbolTable());
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
I != E; ++I)
}
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
- if (GV->hasName()) Out << getLLVMName(GV->getName()) << " = ";
+ if (GV->hasName()) Out << getLLVMName(GV->getName(), GlobalPrefix) << " = ";
if (!GV->hasInitializer())
switch (GV->getLinkage()) {
case GlobalValue::DLLImportLinkage: Out << "dllimport "; break;
case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;
default: Out << "external "; break;
- }
- else
+ } else {
switch (GV->getLinkage()) {
case GlobalValue::InternalLinkage: Out << "internal "; break;
case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
cerr << "GhostLinkage not allowed in AsmWriter!\n";
abort();
}
-
+ switch (GV->getVisibility()) {
+ default: assert(0 && "Invalid visibility style!");
+ case GlobalValue::DefaultVisibility: break;
+ case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+ }
+ }
+
Out << (GV->isConstant() ? "constant " : "global ");
printType(GV->getType()->getElementType());
Out << "\n";
}
-
-// printSymbolTable - Run through symbol table looking for constants
-// and types. Emit their declarations.
-void AssemblyWriter::printSymbolTable(const SymbolTable &ST) {
-
+void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
// Print the types.
- for (SymbolTable::type_const_iterator TI = ST.type_begin();
- TI != ST.type_end(); ++TI) {
- Out << "\t" << getLLVMName(TI->first) << " = type ";
+ for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end();
+ TI != TE; ++TI) {
+ Out << "\t" << getLLVMName(TI->first, LocalPrefix) << " = type ";
// Make sure we print out at least one level of the type structure, so
// that we do not get %FILE = type %FILE
//
printTypeAtLeastOneLevel(TI->second) << "\n";
}
-
- // Print the constants, in type plane order.
- for (SymbolTable::plane_const_iterator PI = ST.plane_begin();
- PI != ST.plane_end(); ++PI) {
- SymbolTable::value_const_iterator VI = ST.value_begin(PI->first);
- SymbolTable::value_const_iterator VE = ST.value_end(PI->first);
-
- for (; VI != VE; ++VI) {
- const Value* V = VI->second;
- const Constant *CPV = dyn_cast<Constant>(V) ;
- if (CPV && !isa<GlobalValue>(V)) {
- printConstant(CPV);
- }
- }
- }
-}
-
-
-/// printConstant - Print out a constant pool entry...
-///
-void AssemblyWriter::printConstant(const Constant *CPV) {
- // Don't print out unnamed constants, they will be inlined
- if (!CPV->hasName()) return;
-
- // Print out name...
- Out << "\t" << getLLVMName(CPV->getName()) << " =";
-
- // Write the value out now.
- writeOperand(CPV, true);
-
- printInfoComment(*CPV);
- Out << "\n";
}
/// printFunction - Print all aspects of a function.
// Print out the return type and name...
Out << "\n";
- // Ensure that no local symbols conflict with global symbols.
- const_cast<Function*>(F)->renameLocalSymbols();
-
if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
- if (F->isExternal())
+ if (F->isDeclaration())
switch (F->getLinkage()) {
case GlobalValue::DLLImportLinkage: Out << "declare dllimport "; break;
case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break;
cerr << "GhostLinkage not allowed in AsmWriter!\n";
abort();
}
+ switch (F->getVisibility()) {
+ default: assert(0 && "Invalid visibility style!");
+ case GlobalValue::DefaultVisibility: break;
+ case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+ }
}
// Print the calling convention.
switch (F->getCallingConv()) {
case CallingConv::C: break; // default
- case CallingConv::CSRet: Out << "csretcc "; break;
case CallingConv::Fast: Out << "fastcc "; break;
case CallingConv::Cold: Out << "coldcc "; break;
case CallingConv::X86_StdCall: Out << "x86_stdcallcc "; break;
const FunctionType *FT = F->getFunctionType();
printType(F->getReturnType()) << ' ';
- if (FT->getParamAttrs(0))
- Out << FunctionType::getParamAttrsText(FT->getParamAttrs(0)) << ' ';
if (!F->getName().empty())
- Out << getLLVMName(F->getName());
+ Out << getLLVMName(F->getName(), GlobalPrefix);
else
- Out << "\"\"";
+ Out << "@\"\"";
Out << '(';
Machine.incorporateFunction(F);
Out << "..."; // Output varargs portion of signature!
}
Out << ')';
-
+ if (FT->getParamAttrs(0))
+ Out << ' ' << FunctionType::getParamAttrsText(FT->getParamAttrs(0));
if (F->hasSection())
Out << " section \"" << F->getSection() << '"';
if (F->getAlignment())
Out << " align " << F->getAlignment();
- if (F->isExternal()) {
+ if (F->isDeclaration()) {
Out << "\n";
} else {
Out << " {";
// Output name, if available...
if (Arg->hasName())
- Out << ' ' << getLLVMName(Arg->getName());
+ Out << ' ' << getLLVMName(Arg->getName(), LocalPrefix);
}
/// printBasicBlock - This member is called for each basic block in a method.
///
void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
if (BB->hasName()) { // Print out the label if it exists...
- Out << "\n" << getLLVMName(BB->getName(), false) << ':';
+ Out << "\n" << getLLVMName(BB->getName(), LabelPrefix) << ':';
} else if (!BB->use_empty()) { // Don't print block # of no uses...
Out << "\n; <label>:";
- int Slot = Machine.getSlot(BB);
+ int Slot = Machine.getLocalSlot(BB);
if (Slot != -1)
Out << Slot;
else
printType(V.getType()) << '>';
if (!V.hasName()) {
- int SlotNum = Machine.getSlot(&V);
+ int SlotNum;
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(&V))
+ SlotNum = Machine.getGlobalSlot(GV);
+ else
+ SlotNum = Machine.getLocalSlot(&V);
if (SlotNum == -1)
Out << ":<badref>";
else
// Print out name if it exists...
if (I.hasName())
- Out << getLLVMName(I.getName()) << " = ";
+ Out << getLLVMName(I.getName(), LocalPrefix) << " = ";
// If this is a volatile load or store, print out the volatile marker.
if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) ||
// Print the calling convention being used.
switch (CI->getCallingConv()) {
case CallingConv::C: break; // default
- case CallingConv::CSRet: Out << " csretcc"; break;
case CallingConv::Fast: Out << " fastcc"; break;
case CallingConv::Cold: Out << " coldcc"; break;
case CallingConv::X86_StdCall: Out << "x86_stdcallcc "; break;
(!isa<PointerType>(RetTy) ||
!isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
Out << ' '; printType(RetTy);
- if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
- Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0));
writeOperand(Operand, false);
} else {
writeOperand(Operand, true);
Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op));
}
Out << " )";
+ if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
+ Out << ' ' << FTy->getParamAttrsText(FTy->getParamAttrs(0));
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
const PointerType *PTy = cast<PointerType>(Operand->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
// Print the calling convention being used.
switch (II->getCallingConv()) {
case CallingConv::C: break; // default
- case CallingConv::CSRet: Out << " csretcc"; break;
case CallingConv::Fast: Out << " fastcc"; break;
case CallingConv::Cold: Out << " coldcc"; break;
case CallingConv::X86_StdCall: Out << "x86_stdcallcc "; break;
(!isa<PointerType>(RetTy) ||
!isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
Out << ' '; printType(RetTy);
- if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
- Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0));
writeOperand(Operand, false);
} else {
writeOperand(Operand, true);
if (op > 3)
Out << ',';
writeOperand(I.getOperand(op), true);
- if (FTy->getParamAttrs(op) != FunctionType::NoAttributeSet)
- Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op));
+ if (FTy->getParamAttrs(op-2) != FunctionType::NoAttributeSet)
+ Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op-2));
}
- Out << " )\n\t\t\tto";
+ Out << " )";
+ if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
+ Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0));
+ Out << "\n\t\t\tto";
writeOperand(II->getNormalDest(), true);
Out << " unwind";
writeOperand(II->getUnwindDest(), true);
bool PrintAllTypes = false;
const Type *TheType = Operand->getType();
- // Shift Left & Right print both types even for Ubyte LHS, and select prints
- // types even if all operands are bools.
- if (isa<ShiftInst>(I) || isa<SelectInst>(I) || isa<StoreInst>(I) ||
- isa<ShuffleVectorInst>(I)) {
+ // Select, Store and ShuffleVector always print all types.
+ if (isa<SelectInst>(I) || isa<StoreInst>(I) || isa<ShuffleVectorInst>(I)) {
PrintAllTypes = true;
} else {
for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
{
}
-inline void SlotMachine::initialize(void) {
+inline void SlotMachine::initialize() {
if (TheModule) {
processModule();
TheModule = 0; ///< Prevent re-processing next time we're called.
for (Module::const_global_iterator I = TheModule->global_begin(),
E = TheModule->global_end(); I != E; ++I)
if (!I->hasName())
- getOrCreateSlot(I);
+ 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())
- getOrCreateSlot(I);
+ CreateModuleSlot(I);
SC_DEBUG("end processModule!\n");
}
for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
AE = TheFunction->arg_end(); AI != AE; ++AI)
if (!AI->hasName())
- getOrCreateSlot(AI);
+ CreateFunctionSlot(AI);
SC_DEBUG("Inserting Instructions:\n");
for (Function::const_iterator BB = TheFunction->begin(),
E = TheFunction->end(); BB != E; ++BB) {
if (!BB->hasName())
- getOrCreateSlot(BB);
+ CreateFunctionSlot(BB);
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
if (I->getType() != Type::VoidTy && !I->hasName())
- getOrCreateSlot(I);
+ CreateFunctionSlot(I);
}
FunctionProcessed = true;
}
/// Clean up after incorporating a function. This is the only way to get out of
-/// the function incorporation state that affects the
-/// getSlot/getOrCreateSlot lock. Function incorporation state is indicated
-/// by TheFunction != 0.
+/// the function incorporation state that affects get*Slot/Create*Slot. Function
+/// incorporation state is indicated by TheFunction != 0.
void SlotMachine::purgeFunction() {
SC_DEBUG("begin purgeFunction!\n");
fMap.clear(); // Simply discard the function level map
SC_DEBUG("end purgeFunction!\n");
}
-/// Get the slot number for a value. This function will assert if you
-/// ask for a Value that hasn't previously been inserted with getOrCreateSlot.
-/// Types are forbidden because Type does not inherit from Value (any more).
-int SlotMachine::getSlot(const Value *V) {
- assert(V && "Can't get slot for null Value");
- assert(!isa<Constant>(V) || isa<GlobalValue>(V) &&
- "Can't insert a non-GlobalValue Constant into SlotMachine");
-
- // Check for uninitialized state and do lazy initialization
- this->initialize();
-
- // Get the type of the value
- const Type* VTy = V->getType();
-
+/// getGlobalSlot - Get the slot number of a global value.
+int SlotMachine::getGlobalSlot(const GlobalValue *V) {
+ // Check for uninitialized state and do lazy initialization.
+ initialize();
+
// Find the type plane in the module map
- TypedPlanes::const_iterator MI = mMap.find(VTy);
-
- if (TheFunction) {
- // Lookup the type in the function map too
- TypedPlanes::const_iterator FI = fMap.find(VTy);
- // If there is a corresponding type plane in the function map
- if (FI != fMap.end()) {
- // Lookup the Value in the function map
- ValueMap::const_iterator FVI = FI->second.map.find(V);
- // If the value doesn't exist in the function map
- if (FVI == FI->second.map.end()) {
- // Look up the value in the module map.
- if (MI == mMap.end()) return -1;
- ValueMap::const_iterator MVI = MI->second.map.find(V);
- // If we didn't find it, it wasn't inserted
- if (MVI == MI->second.map.end()) return -1;
- assert(MVI != MI->second.map.end() && "Value not found");
- // We found it only at the module level
- return MVI->second;
-
- // else the value exists in the function map
- } else {
- // Return the slot number as the module's contribution to
- // the type plane plus the index in the function's contribution
- // to the type plane.
- if (MI != mMap.end())
- return MI->second.next_slot + FVI->second;
- else
- return FVI->second;
- }
- }
- }
-
- // N.B. Can get here only if either !TheFunction or the function doesn't
- // have a corresponding type plane for the Value
-
- // Make sure the type plane exists
+ TypedPlanes::const_iterator MI = mMap.find(V->getType());
if (MI == mMap.end()) return -1;
- // Lookup the value in the module's map
+
+ // Lookup the value in the module plane's map.
ValueMap::const_iterator MVI = MI->second.map.find(V);
- // Make sure we found it.
- if (MVI == MI->second.map.end()) return -1;
- // Return it.
- return MVI->second;
+ return MVI != MI->second.map.end() ? int(MVI->second) : -1;
}
-// Create a new slot, or return the existing slot if it is already
-// inserted. Note that the logic here parallels getSlot but instead
-// of asserting when the Value* isn't found, it inserts the value.
-unsigned SlotMachine::getOrCreateSlot(const Value *V) {
- const Type* VTy = V->getType();
- assert(VTy != Type::VoidTy && !V->hasName() && "Doesn't need a slot!");
- assert(!isa<Constant>(V) || isa<GlobalValue>(V) &&
- "Can't insert a non-GlobalValue Constant into SlotMachine");
-
- // Look up the type plane for the Value's type from the module map
- TypedPlanes::const_iterator MI = mMap.find(VTy);
-
- if (TheFunction) {
- // Get the type plane for the Value's type from the function map
- TypedPlanes::const_iterator FI = fMap.find(VTy);
- // If there is a corresponding type plane in the function map
- if (FI != fMap.end()) {
- // Lookup the Value in the function map
- ValueMap::const_iterator FVI = FI->second.map.find(V);
- // If the value doesn't exist in the function map
- if (FVI == FI->second.map.end()) {
- // If there is no corresponding type plane in the module map
- if (MI == mMap.end())
- return insertValue(V);
- // Look up the value in the module map
- ValueMap::const_iterator MVI = MI->second.map.find(V);
- // If we didn't find it, it wasn't inserted
- if (MVI == MI->second.map.end())
- return insertValue(V);
- else
- // We found it only at the module level
- return MVI->second;
-
- // else the value exists in the function map
- } else {
- if (MI == mMap.end())
- return FVI->second;
- else
- // Return the slot number as the module's contribution to
- // the type plane plus the index in the function's contribution
- // to the type plane.
- return MI->second.next_slot + FVI->second;
- }
+/// getLocalSlot - Get the slot number for a value that is local to a function.
+int SlotMachine::getLocalSlot(const Value *V) {
+ assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!");
- // else there is not a corresponding type plane in the function map
- } else {
- // If the type plane doesn't exists at the module level
- if (MI == mMap.end()) {
- return insertValue(V);
- // else type plane exists at the module level, examine it
- } else {
- // Look up the value in the module's map
- ValueMap::const_iterator MVI = MI->second.map.find(V);
- // If we didn't find it there either
- if (MVI == MI->second.map.end())
- // Return the slot number as the module's contribution to
- // the type plane plus the index of the function map insertion.
- return MI->second.next_slot + insertValue(V);
- else
- return MVI->second;
- }
- }
- }
-
- // N.B. Can only get here if TheFunction == 0
+ // Check for uninitialized state and do lazy initialization.
+ initialize();
- // If the module map's type plane is not for the Value's type
- if (MI != mMap.end()) {
- // Lookup the value in the module's map
- ValueMap::const_iterator MVI = MI->second.map.find(V);
- if (MVI != MI->second.map.end())
- return MVI->second;
- }
+ // Get the type of the value
+ const Type *VTy = V->getType();
- return insertValue(V);
+ TypedPlanes::const_iterator FI = fMap.find(VTy);
+ if (FI == fMap.end()) return -1;
+
+ // Lookup the Value in the function and module maps.
+ ValueMap::const_iterator FVI = FI->second.map.find(V);
+
+ // If the value doesn't exist in the function map, it is a <badref>
+ if (FVI == FI->second.map.end()) return -1;
+
+ return FVI->second;
}
-// Low level insert function. Minimal checking is done. This
-// function is just for the convenience of getOrCreateSlot (above).
-unsigned SlotMachine::insertValue(const Value *V) {
+/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
+void SlotMachine::CreateModuleSlot(const GlobalValue *V) {
assert(V && "Can't insert a null Value into SlotMachine!");
- assert(!isa<Constant>(V) || isa<GlobalValue>(V) &&
- "Can't insert a non-GlobalValue Constant into SlotMachine");
- assert(V->getType() != Type::VoidTy && !V->hasName());
-
- const Type *VTy = V->getType();
+
unsigned DestSlot = 0;
-
- if (TheFunction) {
- TypedPlanes::iterator I = fMap.find(VTy);
- if (I == fMap.end())
- I = fMap.insert(std::make_pair(VTy,ValuePlane())).first;
- DestSlot = I->second.map[V] = I->second.next_slot++;
- } else {
- TypedPlanes::iterator I = mMap.find(VTy);
- if (I == mMap.end())
- I = mMap.insert(std::make_pair(VTy,ValuePlane())).first;
- DestSlot = I->second.map[V] = I->second.next_slot++;
- }
-
+ const Type *VTy = V->getType();
+
+ ValuePlane &PlaneMap = mMap[VTy];
+ DestSlot = PlaneMap.map[V] = PlaneMap.next_slot++;
+
SC_DEBUG(" Inserting value [" << VTy << "] = " << V << " slot=" <<
DestSlot << " [");
// G = Global, F = Function, o = other
- SC_DEBUG((isa<GlobalVariable>(V) ? 'G' : (isa<Function>(V) ? 'F' : 'o')));
- SC_DEBUG("]\n");
- return DestSlot;
+ SC_DEBUG((isa<GlobalVariable>(V) ? 'G' : 'F') << "]\n");
}
+
+
+/// CreateSlot - Create a new slot for the specified value if it has no name.
+void SlotMachine::CreateFunctionSlot(const Value *V) {
+ const Type *VTy = V->getType();
+ assert(VTy != Type::VoidTy && !V->hasName() && "Doesn't need a slot!");
+
+ unsigned DestSlot = 0;
+
+ ValuePlane &PlaneMap = fMap[VTy];
+ DestSlot = PlaneMap.map[V] = PlaneMap.next_slot++;
+
+ // G = Global, F = Function, o = other
+ SC_DEBUG(" Inserting value [" << VTy << "] = " << V << " slot=" <<
+ DestSlot << " [o]\n");
+}