#include <algorithm>
#include <set>
#include <sstream>
+#include "llvm/Support/Mangler.h"
namespace {
class CWriter : public Pass, public InstVisitor<CWriter> {
std::ostream &Out;
- SlotCalculator *Table;
+ Mangler *Mang;
const Module *TheModule;
std::map<const Type *, std::string> TypeNames;
std::set<const Value*> MangledGlobals;
virtual bool run(Module &M) {
// Initialize
- Table = new SlotCalculator(&M, false);
TheModule = &M;
// Ensure that all structure types have names...
bool Changed = nameAllUsedStructureTypes(M);
+ Mang = new Mangler(M);
// Run...
printModule(&M);
// Free memory...
- delete Table;
+ delete Mang;
TypeNames.clear();
MangledGlobals.clear();
return false;
void writeOperand(Value *Operand);
void writeOperandInternal(Value *Operand);
- std::string getValueName(const Value *V);
-
private :
bool nameAllUsedStructureTypes(Module &M);
void printModule(Module *M);
}
void outputLValue(Instruction *I) {
- Out << " " << getValueName(I) << " = ";
+ Out << " " << Mang->getValueName(I) << " = ";
}
void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
unsigned Indent);
};
}
-// We dont want identifier names with ., space, - in them.
-// So we replace them with _
-static std::string makeNameProper(std::string x) {
- std::string tmp;
- for (std::string::iterator sI = x.begin(), sEnd = x.end(); sI != sEnd; sI++)
- switch (*sI) {
- case '.': tmp += "d_"; break;
- case ' ': tmp += "s_"; break;
- case '-': tmp += "D_"; break;
- default: tmp += *sI;
- }
-
- return tmp;
-}
-
-std::string CWriter::getValueName(const Value *V) {
- if (V->hasName()) { // Print out the label if it exists...
-
- // Name mangling occurs as follows:
- // - If V is not a global, mangling always occurs.
- // - Otherwise, mangling occurs when any of the following are true:
- // 1) V has internal linkage
- // 2) V's name would collide if it is not mangled.
- //
-
- if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
- if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
- // No internal linkage, name will not collide -> no mangling.
- return makeNameProper(gv->getName());
- }
- }
-
- // Non-global, or global with internal linkage / colliding name -> mangle.
- return "l" + utostr(V->getType()->getUniqueID()) + "_" +
- makeNameProper(V->getName());
- }
-
- int Slot = Table->getValSlot(V);
- assert(Slot >= 0 && "Invalid value!");
- return "ltmp_" + itostr(Slot) + "_" + utostr(V->getType()->getUniqueID());
-}
-
// A pointer type should not use parens around *'s alone, e.g., (**)
inline bool ptrTypeNameNeedsParens(const std::string &NameSoFar) {
return (NameSoFar.find_last_not_of('*') != std::string::npos);
return;
}
- if (Operand->hasName()) {
- Out << getValueName(Operand);
- } else if (Constant *CPV = dyn_cast<Constant>(Operand)) {
+ if (Constant *CPV = dyn_cast<Constant>(Operand)) {
printConstant(CPV);
} else {
- int Slot = Table->getValSlot(Operand);
- assert(Slot >= 0 && "Malformed LLVM!");
- Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID();
+ Out << Mang->getValueName(Operand);
}
}
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) {
if (I->hasExternalLinkage()) {
Out << "extern ";
- printType(Out, I->getType()->getElementType(), getValueName(I));
+ printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
Out << ";\n";
}
}
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
if (!I->isExternal()) {
Out << "extern ";
- printType(Out, I->getType()->getElementType(), getValueName(I));
+ printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
Out << ";\n";
}
if (!I->isExternal()) {
if (I->hasInternalLinkage())
Out << "static ";
- printType(Out, I->getType()->getElementType(), getValueName(I));
+ printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
if (I->hasLinkOnceLinkage())
Out << " __attribute__((common))";
if (!I->getInitializer()->isNullValue()) {
Out << "/* Structure forward decls */\n";
for (; I != End; ++I)
if (const Type *STy = dyn_cast<StructType>(I->second)) {
- std::string Name = "struct l_" + makeNameProper(I->first);
+ std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
Out << Name << ";\n";
TypeNames.insert(std::make_pair(STy, Name));
}
Out << "/* Typedefs */\n";
for (I = ST.type_begin(Type::TypeTy); I != End; ++I) {
const Type *Ty = cast<Type>(I->second);
- std::string Name = "l_" + makeNameProper(I->first);
+ std::string Name = "l_" + Mangler::makeNameProper(I->first);
Out << "typedef ";
printType(Out, Ty, Name);
Out << ";\n";
void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
// If the program provides its own malloc prototype we don't need
// to include the general one.
- if (getValueName(F) == "malloc")
+ if (Mang->getValueName(F) == "malloc")
needsMalloc = false;
if (F->hasInternalLinkage()) Out << "static ";
std::stringstream FunctionInnards;
// Print out the name...
- FunctionInnards << getValueName(F) << "(";
+ FunctionInnards << Mang->getValueName(F) << "(";
if (!F->isExternal()) {
if (!F->aempty()) {
std::string ArgName;
if (F->abegin()->hasName() || !Prototype)
- ArgName = getValueName(F->abegin());
+ ArgName = Mang->getValueName(F->abegin());
printType(FunctionInnards, F->afront().getType(), ArgName);
for (Function::const_aiterator I = ++F->abegin(), E = F->aend();
I != E; ++I) {
FunctionInnards << ", ";
if (I->hasName() || !Prototype)
- ArgName = getValueName(I);
+ ArgName = Mang->getValueName(I);
else
ArgName = "";
printType(FunctionInnards, I->getType(), ArgName);
void CWriter::printFunction(Function *F) {
if (F->isExternal()) return;
- Table->incorporateFunction(F);
-
printFunctionSignature(F, false);
Out << " {\n";
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
if (const AllocaInst *AI = isDirectAlloca(*I)) {
Out << " ";
- printType(Out, AI->getAllocatedType(), getValueName(AI));
+ printType(Out, AI->getAllocatedType(), Mang->getValueName(AI));
Out << "; /* Address exposed local */\n";
} else if ((*I)->getType() != Type::VoidTy && !isInlinableInst(**I)) {
Out << " ";
- printType(Out, (*I)->getType(), getValueName(*I));
+ printType(Out, (*I)->getType(), Mang->getValueName(*I));
Out << ";\n";
if (isa<PHINode>(*I)) { // Print out PHI node temporaries as well...
Out << " ";
- printType(Out, (*I)->getType(), getValueName(*I)+"__PHI_TEMPORARY");
+ printType(Out, (*I)->getType(), Mang->getValueName(*I)+"__PHI_TEMPORARY");
Out << ";\n";
}
}
break;
}
- if (NeedsLabel) Out << getValueName(BB) << ":\n";
+ if (NeedsLabel) Out << Mang->getValueName(BB) << ":\n";
// Output all of the instructions in the basic block...
for (BasicBlock::iterator II = BB->begin(), E = --BB->end(); II != E; ++II){
}
Out << "}\n\n";
- Table->purgeFunction();
FPConstantMap.clear();
}
PHINode *PN = dyn_cast<PHINode>(I); ++I) {
// now we have to do the printing
Out << std::string(Indent, ' ');
- Out << " " << getValueName(I) << "__PHI_TEMPORARY = ";
+ Out << " " << Mang->getValueName(I) << "__PHI_TEMPORARY = ";
writeOperand(PN->getIncomingValue(PN->getBasicBlockIndex(CurBB)));
Out << "; /* for PHI node */\n";
}
#include <algorithm>
#include <set>
#include <sstream>
+#include "llvm/Support/Mangler.h"
namespace {
class CWriter : public Pass, public InstVisitor<CWriter> {
std::ostream &Out;
- SlotCalculator *Table;
+ Mangler *Mang;
const Module *TheModule;
std::map<const Type *, std::string> TypeNames;
std::set<const Value*> MangledGlobals;
virtual bool run(Module &M) {
// Initialize
- Table = new SlotCalculator(&M, false);
TheModule = &M;
// Ensure that all structure types have names...
bool Changed = nameAllUsedStructureTypes(M);
+ Mang = new Mangler(M);
// Run...
printModule(&M);
// Free memory...
- delete Table;
+ delete Mang;
TypeNames.clear();
MangledGlobals.clear();
return false;
void writeOperand(Value *Operand);
void writeOperandInternal(Value *Operand);
- std::string getValueName(const Value *V);
-
private :
bool nameAllUsedStructureTypes(Module &M);
void printModule(Module *M);
}
void outputLValue(Instruction *I) {
- Out << " " << getValueName(I) << " = ";
+ Out << " " << Mang->getValueName(I) << " = ";
}
void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
unsigned Indent);
};
}
-// We dont want identifier names with ., space, - in them.
-// So we replace them with _
-static std::string makeNameProper(std::string x) {
- std::string tmp;
- for (std::string::iterator sI = x.begin(), sEnd = x.end(); sI != sEnd; sI++)
- switch (*sI) {
- case '.': tmp += "d_"; break;
- case ' ': tmp += "s_"; break;
- case '-': tmp += "D_"; break;
- default: tmp += *sI;
- }
-
- return tmp;
-}
-
-std::string CWriter::getValueName(const Value *V) {
- if (V->hasName()) { // Print out the label if it exists...
-
- // Name mangling occurs as follows:
- // - If V is not a global, mangling always occurs.
- // - Otherwise, mangling occurs when any of the following are true:
- // 1) V has internal linkage
- // 2) V's name would collide if it is not mangled.
- //
-
- if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
- if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
- // No internal linkage, name will not collide -> no mangling.
- return makeNameProper(gv->getName());
- }
- }
-
- // Non-global, or global with internal linkage / colliding name -> mangle.
- return "l" + utostr(V->getType()->getUniqueID()) + "_" +
- makeNameProper(V->getName());
- }
-
- int Slot = Table->getValSlot(V);
- assert(Slot >= 0 && "Invalid value!");
- return "ltmp_" + itostr(Slot) + "_" + utostr(V->getType()->getUniqueID());
-}
-
// A pointer type should not use parens around *'s alone, e.g., (**)
inline bool ptrTypeNameNeedsParens(const std::string &NameSoFar) {
return (NameSoFar.find_last_not_of('*') != std::string::npos);
return;
}
- if (Operand->hasName()) {
- Out << getValueName(Operand);
- } else if (Constant *CPV = dyn_cast<Constant>(Operand)) {
+ if (Constant *CPV = dyn_cast<Constant>(Operand)) {
printConstant(CPV);
} else {
- int Slot = Table->getValSlot(Operand);
- assert(Slot >= 0 && "Malformed LLVM!");
- Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID();
+ Out << Mang->getValueName(Operand);
}
}
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) {
if (I->hasExternalLinkage()) {
Out << "extern ";
- printType(Out, I->getType()->getElementType(), getValueName(I));
+ printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
Out << ";\n";
}
}
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
if (!I->isExternal()) {
Out << "extern ";
- printType(Out, I->getType()->getElementType(), getValueName(I));
+ printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
Out << ";\n";
}
if (!I->isExternal()) {
if (I->hasInternalLinkage())
Out << "static ";
- printType(Out, I->getType()->getElementType(), getValueName(I));
+ printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
if (I->hasLinkOnceLinkage())
Out << " __attribute__((common))";
if (!I->getInitializer()->isNullValue()) {
Out << "/* Structure forward decls */\n";
for (; I != End; ++I)
if (const Type *STy = dyn_cast<StructType>(I->second)) {
- std::string Name = "struct l_" + makeNameProper(I->first);
+ std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
Out << Name << ";\n";
TypeNames.insert(std::make_pair(STy, Name));
}
Out << "/* Typedefs */\n";
for (I = ST.type_begin(Type::TypeTy); I != End; ++I) {
const Type *Ty = cast<Type>(I->second);
- std::string Name = "l_" + makeNameProper(I->first);
+ std::string Name = "l_" + Mangler::makeNameProper(I->first);
Out << "typedef ";
printType(Out, Ty, Name);
Out << ";\n";
void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
// If the program provides its own malloc prototype we don't need
// to include the general one.
- if (getValueName(F) == "malloc")
+ if (Mang->getValueName(F) == "malloc")
needsMalloc = false;
if (F->hasInternalLinkage()) Out << "static ";
std::stringstream FunctionInnards;
// Print out the name...
- FunctionInnards << getValueName(F) << "(";
+ FunctionInnards << Mang->getValueName(F) << "(";
if (!F->isExternal()) {
if (!F->aempty()) {
std::string ArgName;
if (F->abegin()->hasName() || !Prototype)
- ArgName = getValueName(F->abegin());
+ ArgName = Mang->getValueName(F->abegin());
printType(FunctionInnards, F->afront().getType(), ArgName);
for (Function::const_aiterator I = ++F->abegin(), E = F->aend();
I != E; ++I) {
FunctionInnards << ", ";
if (I->hasName() || !Prototype)
- ArgName = getValueName(I);
+ ArgName = Mang->getValueName(I);
else
ArgName = "";
printType(FunctionInnards, I->getType(), ArgName);
void CWriter::printFunction(Function *F) {
if (F->isExternal()) return;
- Table->incorporateFunction(F);
-
printFunctionSignature(F, false);
Out << " {\n";
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
if (const AllocaInst *AI = isDirectAlloca(*I)) {
Out << " ";
- printType(Out, AI->getAllocatedType(), getValueName(AI));
+ printType(Out, AI->getAllocatedType(), Mang->getValueName(AI));
Out << "; /* Address exposed local */\n";
} else if ((*I)->getType() != Type::VoidTy && !isInlinableInst(**I)) {
Out << " ";
- printType(Out, (*I)->getType(), getValueName(*I));
+ printType(Out, (*I)->getType(), Mang->getValueName(*I));
Out << ";\n";
if (isa<PHINode>(*I)) { // Print out PHI node temporaries as well...
Out << " ";
- printType(Out, (*I)->getType(), getValueName(*I)+"__PHI_TEMPORARY");
+ printType(Out, (*I)->getType(), Mang->getValueName(*I)+"__PHI_TEMPORARY");
Out << ";\n";
}
}
break;
}
- if (NeedsLabel) Out << getValueName(BB) << ":\n";
+ if (NeedsLabel) Out << Mang->getValueName(BB) << ":\n";
// Output all of the instructions in the basic block...
for (BasicBlock::iterator II = BB->begin(), E = --BB->end(); II != E; ++II){
}
Out << "}\n\n";
- Table->purgeFunction();
FPConstantMap.clear();
}
PHINode *PN = dyn_cast<PHINode>(I); ++I) {
// now we have to do the printing
Out << std::string(Indent, ' ');
- Out << " " << getValueName(I) << "__PHI_TEMPORARY = ";
+ Out << " " << Mang->getValueName(I) << "__PHI_TEMPORARY = ";
writeOperand(PN->getIncomingValue(PN->getBasicBlockIndex(CurBB)));
Out << "; /* for PHI node */\n";
}
#include "llvm/DerivedTypes.h"
#include "Support/StringExtras.h"
#include "llvm/Module.h"
+#include "llvm/Support/Mangler.h"
namespace {
- /// This is properly part of the name mangler; it keeps track of
- /// which global values have had their names mangled. It is cleared
- /// at the end of every module by doFinalization().
- ///
- std::set<const Value *> MangledGlobals;
-
struct Printer : public MachineFunctionPass {
/// Output stream on which we're printing assembly code.
///
///
TargetMachine &TM;
+ /// Name-mangler for global names.
+ ///
+ Mangler *Mang;
+
Printer(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { }
/// We name each basic block in a Function with a unique number, so
return "X86 Assembly Printer";
}
- void printMachineInstruction(const MachineInstr *MI) const;
+ void printMachineInstruction(const MachineInstr *MI);
void printOp(const MachineOperand &MO,
- bool elideOffsetKeyword = false) const;
- void printMemReference(const MachineInstr *MI, unsigned Op) const;
- void printConstantPool(MachineConstantPool *MCP) const;
+ bool elideOffsetKeyword = false);
+ void printMemReference(const MachineInstr *MI, unsigned Op);
+ void printConstantPool(MachineConstantPool *MCP);
bool runOnMachineFunction(MachineFunction &F);
- std::string ConstantExprToString(const ConstantExpr* CE) const;
- std::string valToExprString(const Value* V) const;
+ std::string ConstantExprToString(const ConstantExpr* CE);
+ std::string valToExprString(const Value* V);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
- void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0) const;
- void printSingleConstantValue(const Constant* CV) const;
+ void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0);
+ void printSingleConstantValue(const Constant* CV);
};
} // end of anonymous namespace
return new Printer(o, tm);
}
-/// makeNameProper - We don't want identifier names with ., space, or
-/// - in them, so we mangle these characters into the strings "d_",
-/// "s_", and "D_", respectively.
-///
-static std::string makeNameProper(std::string x) {
- std::string tmp;
- for (std::string::iterator sI = x.begin(), sEnd = x.end(); sI != sEnd; sI++)
- switch (*sI) {
- case '.': tmp += "d_"; break;
- case ' ': tmp += "s_"; break;
- case '-': tmp += "D_"; break;
- default: tmp += *sI;
- }
- return tmp;
-}
-
-static std::string getValueName(const Value *V) {
- if (V->hasName()) { // Print out the label if it exists...
- // Name mangling occurs as follows:
- // - If V is not a global, mangling always occurs.
- // - Otherwise, mangling occurs when any of the following are true:
- // 1) V has internal linkage
- // 2) V's name would collide if it is not mangled.
- //
- if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
- if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
- // No internal linkage, name will not collide -> no mangling.
- return makeNameProper(gv->getName());
- }
- }
- // Non-global, or global with internal linkage / colliding name -> mangle.
- return "l" + utostr(V->getType()->getUniqueID()) + "_" +
- makeNameProper(V->getName());
- }
- static int Count = 0;
- Count++;
- return "ltmp_" + itostr(Count) + "_" + utostr(V->getType()->getUniqueID());
-}
-
/// valToExprString - Helper function for ConstantExprToString().
/// Appends result to argument string S.
///
-std::string Printer::valToExprString(const Value* V) const {
+std::string Printer::valToExprString(const Value* V) {
std::string S;
bool failed = false;
if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known
else
failed = true;
} else if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
- S += getValueName(GV);
+ S += Mang->getValueName(GV);
}
else
failed = true;
/// ConstantExprToString - Convert a ConstantExpr to an asm expression
/// and return this as a string.
///
-std::string Printer::ConstantExprToString(const ConstantExpr* CE) const {
+std::string Printer::ConstantExprToString(const ConstantExpr* CE) {
std::string S;
const TargetData &TD = TM.getTargetData();
switch(CE->getOpcode()) {
/// printSingleConstantValue - Print a single constant value.
///
void
-Printer::printSingleConstantValue(const Constant* CV) const
+Printer::printSingleConstantValue(const Constant* CV)
{
assert(CV->getType() != Type::VoidTy &&
CV->getType() != Type::TypeTy &&
{
// This is a constant address for a global variable or method.
// Use the name of the variable or method as the address value.
- O << getValueName(CPR->getValue()) << "\n";
+ O << Mang->getValueName(CPR->getValue()) << "\n";
}
else if (isa<ConstantPointerNull>(CV))
{
// Uses printSingleConstantValue() to print each individual value.
void
Printer::printConstantValueOnly(const Constant* CV,
- int numPadBytesAfter /* = 0 */) const
+ int numPadBytesAfter /* = 0 */)
{
const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
const TargetData &TD = TM.getTargetData();
/// used to print out constants which have been "spilled to memory" by
/// the code generator.
///
-void Printer::printConstantPool(MachineConstantPool *MCP) const {
+void Printer::printConstantPool(MachineConstantPool *MCP) {
const std::vector<Constant*> &CP = MCP->getConstants();
const TargetData &TD = TM.getTargetData();
static unsigned BBNumber = 0;
// What's my mangled name?
- CurrentFnName = getValueName(MF.getFunction());
+ CurrentFnName = Mang->getValueName(MF.getFunction());
// Print out constants referenced by the function
printConstantPool(MF.getConstantPool());
}
void Printer::printOp(const MachineOperand &MO,
- bool elideOffsetKeyword /* = false */) const {
+ bool elideOffsetKeyword /* = false */) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
switch (MO.getType()) {
case MachineOperand::MO_VirtualRegister:
}
return;
case MachineOperand::MO_GlobalAddress:
- if (!elideOffsetKeyword) O << "OFFSET "; O << getValueName(MO.getGlobal());
+ if (!elideOffsetKeyword) O << "OFFSET "; O << Mang->getValueName(MO.getGlobal());
return;
case MachineOperand::MO_ExternalSymbol:
O << MO.getSymbolName();
}
}
-void Printer::printMemReference(const MachineInstr *MI, unsigned Op) const {
+void Printer::printMemReference(const MachineInstr *MI, unsigned Op) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
assert(isMem(MI, Op) && "Invalid memory reference!");
/// printMachineInstruction -- Print out a single X86 LLVM instruction
/// MI in Intel syntax to the current output stream.
///
-void Printer::printMachineInstruction(const MachineInstr *MI) const {
+void Printer::printMachineInstruction(const MachineInstr *MI) {
unsigned Opcode = MI->getOpcode();
const TargetInstrInfo &TII = TM.getInstrInfo();
const TargetInstrDescriptor &Desc = TII.get(Opcode);
// Tell gas we are outputting Intel syntax (not AT&T syntax) assembly,
// with no % decorations on register names.
O << "\t.intel_syntax noprefix\n";
-
- // Ripped from CWriter:
- // Calculate which global values have names that will collide when we throw
- // away type information.
- { // Scope to delete the FoundNames set when we are done with it...
- std::set<std::string> FoundNames;
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (I->hasName()) // If the global has a name...
- if (FoundNames.count(I->getName())) // And the name is already used
- MangledGlobals.insert(I); // Mangle the name
- else
- FoundNames.insert(I->getName()); // Otherwise, keep track of name
-
- for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
- if (I->hasName()) // If the global has a name...
- if (FoundNames.count(I->getName())) // And the name is already used
- MangledGlobals.insert(I); // Mangle the name
- else
- FoundNames.insert(I->getName()); // Otherwise, keep track of name
- }
-
+ Mang = new Mangler(M);
return false; // success
}
const TargetData &TD = TM.getTargetData();
// Print out module-level global variables here.
for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
- std::string name(getValueName(I));
+ std::string name(Mang->getValueName(I));
if (I->hasInitializer()) {
Constant *C = I->getInitializer();
O << "\t.data\n";
<< (unsigned)TD.getTypeAlignment(I->getType()) << "\n";
}
}
- MangledGlobals.clear();
+ delete Mang;
return false; // success
}
#include "llvm/DerivedTypes.h"
#include "Support/StringExtras.h"
#include "llvm/Module.h"
+#include "llvm/Support/Mangler.h"
namespace {
- /// This is properly part of the name mangler; it keeps track of
- /// which global values have had their names mangled. It is cleared
- /// at the end of every module by doFinalization().
- ///
- std::set<const Value *> MangledGlobals;
-
struct Printer : public MachineFunctionPass {
/// Output stream on which we're printing assembly code.
///
///
TargetMachine &TM;
+ /// Name-mangler for global names.
+ ///
+ Mangler *Mang;
+
Printer(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { }
/// We name each basic block in a Function with a unique number, so
return "X86 Assembly Printer";
}
- void printMachineInstruction(const MachineInstr *MI) const;
+ void printMachineInstruction(const MachineInstr *MI);
void printOp(const MachineOperand &MO,
- bool elideOffsetKeyword = false) const;
- void printMemReference(const MachineInstr *MI, unsigned Op) const;
- void printConstantPool(MachineConstantPool *MCP) const;
+ bool elideOffsetKeyword = false);
+ void printMemReference(const MachineInstr *MI, unsigned Op);
+ void printConstantPool(MachineConstantPool *MCP);
bool runOnMachineFunction(MachineFunction &F);
- std::string ConstantExprToString(const ConstantExpr* CE) const;
- std::string valToExprString(const Value* V) const;
+ std::string ConstantExprToString(const ConstantExpr* CE);
+ std::string valToExprString(const Value* V);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
- void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0) const;
- void printSingleConstantValue(const Constant* CV) const;
+ void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0);
+ void printSingleConstantValue(const Constant* CV);
};
} // end of anonymous namespace
return new Printer(o, tm);
}
-/// makeNameProper - We don't want identifier names with ., space, or
-/// - in them, so we mangle these characters into the strings "d_",
-/// "s_", and "D_", respectively.
-///
-static std::string makeNameProper(std::string x) {
- std::string tmp;
- for (std::string::iterator sI = x.begin(), sEnd = x.end(); sI != sEnd; sI++)
- switch (*sI) {
- case '.': tmp += "d_"; break;
- case ' ': tmp += "s_"; break;
- case '-': tmp += "D_"; break;
- default: tmp += *sI;
- }
- return tmp;
-}
-
-static std::string getValueName(const Value *V) {
- if (V->hasName()) { // Print out the label if it exists...
- // Name mangling occurs as follows:
- // - If V is not a global, mangling always occurs.
- // - Otherwise, mangling occurs when any of the following are true:
- // 1) V has internal linkage
- // 2) V's name would collide if it is not mangled.
- //
- if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
- if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
- // No internal linkage, name will not collide -> no mangling.
- return makeNameProper(gv->getName());
- }
- }
- // Non-global, or global with internal linkage / colliding name -> mangle.
- return "l" + utostr(V->getType()->getUniqueID()) + "_" +
- makeNameProper(V->getName());
- }
- static int Count = 0;
- Count++;
- return "ltmp_" + itostr(Count) + "_" + utostr(V->getType()->getUniqueID());
-}
-
/// valToExprString - Helper function for ConstantExprToString().
/// Appends result to argument string S.
///
-std::string Printer::valToExprString(const Value* V) const {
+std::string Printer::valToExprString(const Value* V) {
std::string S;
bool failed = false;
if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known
else
failed = true;
} else if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
- S += getValueName(GV);
+ S += Mang->getValueName(GV);
}
else
failed = true;
/// ConstantExprToString - Convert a ConstantExpr to an asm expression
/// and return this as a string.
///
-std::string Printer::ConstantExprToString(const ConstantExpr* CE) const {
+std::string Printer::ConstantExprToString(const ConstantExpr* CE) {
std::string S;
const TargetData &TD = TM.getTargetData();
switch(CE->getOpcode()) {
/// printSingleConstantValue - Print a single constant value.
///
void
-Printer::printSingleConstantValue(const Constant* CV) const
+Printer::printSingleConstantValue(const Constant* CV)
{
assert(CV->getType() != Type::VoidTy &&
CV->getType() != Type::TypeTy &&
{
// This is a constant address for a global variable or method.
// Use the name of the variable or method as the address value.
- O << getValueName(CPR->getValue()) << "\n";
+ O << Mang->getValueName(CPR->getValue()) << "\n";
}
else if (isa<ConstantPointerNull>(CV))
{
// Uses printSingleConstantValue() to print each individual value.
void
Printer::printConstantValueOnly(const Constant* CV,
- int numPadBytesAfter /* = 0 */) const
+ int numPadBytesAfter /* = 0 */)
{
const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
const TargetData &TD = TM.getTargetData();
/// used to print out constants which have been "spilled to memory" by
/// the code generator.
///
-void Printer::printConstantPool(MachineConstantPool *MCP) const {
+void Printer::printConstantPool(MachineConstantPool *MCP) {
const std::vector<Constant*> &CP = MCP->getConstants();
const TargetData &TD = TM.getTargetData();
static unsigned BBNumber = 0;
// What's my mangled name?
- CurrentFnName = getValueName(MF.getFunction());
+ CurrentFnName = Mang->getValueName(MF.getFunction());
// Print out constants referenced by the function
printConstantPool(MF.getConstantPool());
}
void Printer::printOp(const MachineOperand &MO,
- bool elideOffsetKeyword /* = false */) const {
+ bool elideOffsetKeyword /* = false */) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
switch (MO.getType()) {
case MachineOperand::MO_VirtualRegister:
}
return;
case MachineOperand::MO_GlobalAddress:
- if (!elideOffsetKeyword) O << "OFFSET "; O << getValueName(MO.getGlobal());
+ if (!elideOffsetKeyword) O << "OFFSET "; O << Mang->getValueName(MO.getGlobal());
return;
case MachineOperand::MO_ExternalSymbol:
O << MO.getSymbolName();
}
}
-void Printer::printMemReference(const MachineInstr *MI, unsigned Op) const {
+void Printer::printMemReference(const MachineInstr *MI, unsigned Op) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
assert(isMem(MI, Op) && "Invalid memory reference!");
/// printMachineInstruction -- Print out a single X86 LLVM instruction
/// MI in Intel syntax to the current output stream.
///
-void Printer::printMachineInstruction(const MachineInstr *MI) const {
+void Printer::printMachineInstruction(const MachineInstr *MI) {
unsigned Opcode = MI->getOpcode();
const TargetInstrInfo &TII = TM.getInstrInfo();
const TargetInstrDescriptor &Desc = TII.get(Opcode);
// Tell gas we are outputting Intel syntax (not AT&T syntax) assembly,
// with no % decorations on register names.
O << "\t.intel_syntax noprefix\n";
-
- // Ripped from CWriter:
- // Calculate which global values have names that will collide when we throw
- // away type information.
- { // Scope to delete the FoundNames set when we are done with it...
- std::set<std::string> FoundNames;
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (I->hasName()) // If the global has a name...
- if (FoundNames.count(I->getName())) // And the name is already used
- MangledGlobals.insert(I); // Mangle the name
- else
- FoundNames.insert(I->getName()); // Otherwise, keep track of name
-
- for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
- if (I->hasName()) // If the global has a name...
- if (FoundNames.count(I->getName())) // And the name is already used
- MangledGlobals.insert(I); // Mangle the name
- else
- FoundNames.insert(I->getName()); // Otherwise, keep track of name
- }
-
+ Mang = new Mangler(M);
return false; // success
}
const TargetData &TD = TM.getTargetData();
// Print out module-level global variables here.
for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
- std::string name(getValueName(I));
+ std::string name(Mang->getValueName(I));
if (I->hasInitializer()) {
Constant *C = I->getInitializer();
O << "\t.data\n";
<< (unsigned)TD.getTypeAlignment(I->getType()) << "\n";
}
}
- MangledGlobals.clear();
+ delete Mang;
return false; // success
}