Use unified CWriter-X86/Printer name mangler. Do not bother using
authorBrian Gaeke <gaeke@uiuc.edu>
Thu, 24 Jul 2003 20:20:44 +0000 (20:20 +0000)
committerBrian Gaeke <gaeke@uiuc.edu>
Thu, 24 Jul 2003 20:20:44 +0000 (20:20 +0000)
SlotCalculator in CWriter.  (Unfortunately, all this means a lot of
X86/Printer's methods have to be de-constified again.  Oh well.)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7299 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/CBackend/CBackend.cpp
lib/Target/CBackend/Writer.cpp
lib/Target/X86/Printer.cpp
lib/Target/X86/X86AsmPrinter.cpp

index 285b3a2a4d7461690dae3845ad032b759af0a4bc..217c0c57ffbcd8394f6e84a8cc073f10291c0a43 100644 (file)
 #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;
@@ -44,17 +45,17 @@ namespace {
 
     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;
@@ -67,8 +68,6 @@ namespace {
     void writeOperand(Value *Operand);
     void writeOperandInternal(Value *Operand);
 
-    std::string getValueName(const Value *V);
-
   private :
     bool nameAllUsedStructureTypes(Module &M);
     void printModule(Module *M);
@@ -143,7 +142,7 @@ namespace {
     }
 
     void outputLValue(Instruction *I) {
-      Out << "  " << getValueName(I) << " = ";
+      Out << "  " << Mang->getValueName(I) << " = ";
     }
     void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
                             unsigned Indent);
@@ -152,48 +151,6 @@ namespace {
   };
 }
 
-// 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);
@@ -523,14 +480,10 @@ void CWriter::writeOperandInternal(Value *Operand) {
       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);
   }
 }
 
@@ -650,7 +603,7 @@ void CWriter::printModule(Module *M) {
     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";
       }
     }
@@ -684,7 +637,7 @@ void CWriter::printModule(Module *M) {
     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";
       }
@@ -697,7 +650,7 @@ void CWriter::printModule(Module *M) {
       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()) {
@@ -742,7 +695,7 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
   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));
     }
@@ -753,7 +706,7 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
   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";
@@ -808,7 +761,7 @@ void CWriter::printContainedStructs(const Type *Ty,
 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 ";
@@ -820,19 +773,19 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   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);
@@ -863,8 +816,6 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
 void CWriter::printFunction(Function *F) {
   if (F->isExternal()) return;
 
-  Table->incorporateFunction(F);
-
   printFunctionSignature(F, false);
   Out << " {\n";
 
@@ -872,16 +823,16 @@ void CWriter::printFunction(Function *F) {
   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";
       }
     }
@@ -936,7 +887,7 @@ void CWriter::printFunction(Function *F) {
           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){
@@ -955,7 +906,6 @@ void CWriter::printFunction(Function *F) {
   }
   
   Out << "}\n\n";
-  Table->purgeFunction();
   FPConstantMap.clear();
 }
 
@@ -1031,7 +981,7 @@ void CWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ,
        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";
   }
index 285b3a2a4d7461690dae3845ad032b759af0a4bc..217c0c57ffbcd8394f6e84a8cc073f10291c0a43 100644 (file)
 #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;
@@ -44,17 +45,17 @@ namespace {
 
     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;
@@ -67,8 +68,6 @@ namespace {
     void writeOperand(Value *Operand);
     void writeOperandInternal(Value *Operand);
 
-    std::string getValueName(const Value *V);
-
   private :
     bool nameAllUsedStructureTypes(Module &M);
     void printModule(Module *M);
@@ -143,7 +142,7 @@ namespace {
     }
 
     void outputLValue(Instruction *I) {
-      Out << "  " << getValueName(I) << " = ";
+      Out << "  " << Mang->getValueName(I) << " = ";
     }
     void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
                             unsigned Indent);
@@ -152,48 +151,6 @@ namespace {
   };
 }
 
-// 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);
@@ -523,14 +480,10 @@ void CWriter::writeOperandInternal(Value *Operand) {
       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);
   }
 }
 
@@ -650,7 +603,7 @@ void CWriter::printModule(Module *M) {
     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";
       }
     }
@@ -684,7 +637,7 @@ void CWriter::printModule(Module *M) {
     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";
       }
@@ -697,7 +650,7 @@ void CWriter::printModule(Module *M) {
       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()) {
@@ -742,7 +695,7 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
   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));
     }
@@ -753,7 +706,7 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
   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";
@@ -808,7 +761,7 @@ void CWriter::printContainedStructs(const Type *Ty,
 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 ";
@@ -820,19 +773,19 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   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);
@@ -863,8 +816,6 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
 void CWriter::printFunction(Function *F) {
   if (F->isExternal()) return;
 
-  Table->incorporateFunction(F);
-
   printFunctionSignature(F, false);
   Out << " {\n";
 
@@ -872,16 +823,16 @@ void CWriter::printFunction(Function *F) {
   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";
       }
     }
@@ -936,7 +887,7 @@ void CWriter::printFunction(Function *F) {
           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){
@@ -955,7 +906,6 @@ void CWriter::printFunction(Function *F) {
   }
   
   Out << "}\n\n";
-  Table->purgeFunction();
   FPConstantMap.clear();
 }
 
@@ -1031,7 +981,7 @@ void CWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ,
        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";
   }
index 75cc6e9e6fe09b0799deed6fef784155312ca18b..24e64e492ce471623faa9817b97f5658e67838c6 100644 (file)
 #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.
     ///
@@ -39,6 +34,10 @@ namespace {
     ///
     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
@@ -58,18 +57,18 @@ namespace {
       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
 
@@ -82,49 +81,10 @@ Pass *createX86CodePrinterPass(std::ostream &o, TargetMachine &tm) {
   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
@@ -145,7 +105,7 @@ std::string Printer::valToExprString(const Value* V) const {
     else
       failed = true;
   } else if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
-    S += getValueName(GV);
+    S += Mang->getValueName(GV);
   }
   else
     failed = true;
@@ -160,7 +120,7 @@ std::string Printer::valToExprString(const Value* V) const {
 /// 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()) {
@@ -207,7 +167,7 @@ std::string Printer::ConstantExprToString(const ConstantExpr* CE) const {
 /// 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 &&
@@ -284,7 +244,7 @@ Printer::printSingleConstantValue(const Constant* CV) const
     {
       // 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))
     {
@@ -362,7 +322,7 @@ static std::string getAsCString(const ConstantArray *CVA) {
 // 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();
@@ -422,7 +382,7 @@ Printer::printConstantValueOnly(const Constant* CV,
 /// 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();
  
@@ -447,7 +407,7 @@ bool Printer::runOnMachineFunction(MachineFunction &MF) {
   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());
@@ -500,7 +460,7 @@ static bool isMem(const MachineInstr *MI, unsigned Op) {
 }
 
 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:
@@ -529,7 +489,7 @@ void Printer::printOp(const MachineOperand &MO,
     }
     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();
@@ -552,7 +512,7 @@ static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
   }
 }
 
-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!");
 
@@ -607,7 +567,7 @@ void Printer::printMemReference(const MachineInstr *MI, unsigned Op) const {
 /// 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);
@@ -957,27 +917,7 @@ bool Printer::doInitialization(Module &M)
   // 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
 }
 
@@ -993,7 +933,7 @@ bool Printer::doFinalization(Module &M)
   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";
@@ -1021,6 +961,6 @@ bool Printer::doFinalization(Module &M)
         << (unsigned)TD.getTypeAlignment(I->getType()) << "\n";
     }
   }
-  MangledGlobals.clear();
+  delete Mang;
   return false; // success
 }
index 75cc6e9e6fe09b0799deed6fef784155312ca18b..24e64e492ce471623faa9817b97f5658e67838c6 100644 (file)
 #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.
     ///
@@ -39,6 +34,10 @@ namespace {
     ///
     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
@@ -58,18 +57,18 @@ namespace {
       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
 
@@ -82,49 +81,10 @@ Pass *createX86CodePrinterPass(std::ostream &o, TargetMachine &tm) {
   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
@@ -145,7 +105,7 @@ std::string Printer::valToExprString(const Value* V) const {
     else
       failed = true;
   } else if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
-    S += getValueName(GV);
+    S += Mang->getValueName(GV);
   }
   else
     failed = true;
@@ -160,7 +120,7 @@ std::string Printer::valToExprString(const Value* V) const {
 /// 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()) {
@@ -207,7 +167,7 @@ std::string Printer::ConstantExprToString(const ConstantExpr* CE) const {
 /// 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 &&
@@ -284,7 +244,7 @@ Printer::printSingleConstantValue(const Constant* CV) const
     {
       // 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))
     {
@@ -362,7 +322,7 @@ static std::string getAsCString(const ConstantArray *CVA) {
 // 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();
@@ -422,7 +382,7 @@ Printer::printConstantValueOnly(const Constant* CV,
 /// 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();
  
@@ -447,7 +407,7 @@ bool Printer::runOnMachineFunction(MachineFunction &MF) {
   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());
@@ -500,7 +460,7 @@ static bool isMem(const MachineInstr *MI, unsigned Op) {
 }
 
 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:
@@ -529,7 +489,7 @@ void Printer::printOp(const MachineOperand &MO,
     }
     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();
@@ -552,7 +512,7 @@ static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
   }
 }
 
-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!");
 
@@ -607,7 +567,7 @@ void Printer::printMemReference(const MachineInstr *MI, unsigned Op) const {
 /// 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);
@@ -957,27 +917,7 @@ bool Printer::doInitialization(Module &M)
   // 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
 }
 
@@ -993,7 +933,7 @@ bool Printer::doFinalization(Module &M)
   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";
@@ -1021,6 +961,6 @@ bool Printer::doFinalization(Module &M)
         << (unsigned)TD.getTypeAlignment(I->getType()) << "\n";
     }
   }
-  MangledGlobals.clear();
+  delete Mang;
   return false; // success
 }