Kill ModuleProvider and ghost linkage by inverting the relationship between
[oota-llvm.git] / lib / Target / XCore / AsmPrinter / XCoreAsmPrinter.cpp
index bf32d697846a998d34a3684e68b154aaa414ce2f..e9813b6f02846206571b8b9ddb0707040f66a1e4 100644 (file)
@@ -28,6 +28,7 @@
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetRegistry.h"
@@ -36,7 +37,6 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
 #include "llvm/Support/MathExtras.h"
 #include <algorithm>
 #include <cctype>
@@ -51,13 +51,12 @@ static cl::opt<unsigned> MaxThreads("xcore-max-threads", cl::Optional,
   cl::init(8));
 
 namespace {
-  class VISIBILITY_HIDDEN XCoreAsmPrinter : public AsmPrinter {
-    DwarfWriter *DW;
+  class XCoreAsmPrinter : public AsmPrinter {
     const XCoreSubtarget &Subtarget;
   public:
     explicit XCoreAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
                              const MCAsmInfo *T, bool V)
-      : AsmPrinter(O, TM, T, V), DW(0),
+      : AsmPrinter(O, TM, T, V),
       Subtarget(TM.getSubtarget<XCoreSubtarget>()) {}
 
     virtual const char *getPassName() const {
@@ -69,19 +68,19 @@ namespace {
     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                         unsigned AsmVariant, const char *ExtraCode);
 
-    void emitGlobalDirective(const std::string &name);
-    void emitExternDirective(const std::string &name);
+    void emitGlobalDirective(const MCSymbol *Sym);
     
-    void emitArrayBound(const std::string &name, const GlobalVariable *GV);
-    virtual void PrintGlobalVariable(const GlobalVariable *GV);
+    void emitArrayBound(const MCSymbol *Sym, const GlobalVariable *GV);
+    virtual void EmitGlobalVariable(const GlobalVariable *GV);
 
     void emitFunctionStart(MachineFunction &MF);
     void emitFunctionEnd(MachineFunction &MF);
 
     void printInstruction(const MachineInstr *MI);  // autogenerated.
+    static const char *getRegisterName(unsigned RegNo);
+
     void printMachineInstruction(const MachineInstr *MI);
     bool runOnMachineFunction(MachineFunction &F);
-    bool doInitialization(Module &M);
     
     void getAnalysisUsage(AnalysisUsage &AU) const {
       AsmPrinter::getAnalysisUsage(AU);
@@ -94,55 +93,44 @@ namespace {
 
 #include "XCoreGenAsmWriter.inc"
 
-void XCoreAsmPrinter::
-emitGlobalDirective(const std::string &name)
-{
-  O << TAI->getGlobalDirective() << name;
-  O << "\n";
+void XCoreAsmPrinter::emitGlobalDirective(const MCSymbol *Sym) {
+  O << MAI->getGlobalDirective() << *Sym << "\n";
 }
 
-void XCoreAsmPrinter::
-emitExternDirective(const std::string &name)
-{
-  O << "\t.extern\t" << name;
-  O << '\n';
-}
-
-void XCoreAsmPrinter::
-emitArrayBound(const std::string &name, const GlobalVariable *GV)
-{
+void XCoreAsmPrinter::emitArrayBound(const MCSymbol *Sym,
+                                     const GlobalVariable *GV) {
   assert(((GV->hasExternalLinkage() ||
     GV->hasWeakLinkage()) ||
     GV->hasLinkOnceLinkage()) && "Unexpected linkage");
   if (const ArrayType *ATy = dyn_cast<ArrayType>(
-    cast<PointerType>(GV->getType())->getElementType()))
-  {
-    O << TAI->getGlobalDirective() << name << ".globound" << "\n";
-    O << TAI->getSetDirective() << name << ".globound" << ","
-      << ATy->getNumElements() << "\n";
+    cast<PointerType>(GV->getType())->getElementType())) {
+    O << MAI->getGlobalDirective() << *Sym;
+    O << ".globound" << "\n";
+    O << "\t.set\t" << *Sym;
+    O << ".globound" << "," << ATy->getNumElements() << "\n";
     if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
       // TODO Use COMDAT groups for LinkOnceLinkage
-      O << TAI->getWeakDefDirective() << name << ".globound" << "\n";
+      O << MAI->getWeakDefDirective() << *Sym << ".globound" << "\n";
     }
   }
 }
 
-void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
+void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   // Check to see if this is a special global used by LLVM, if so, emit it.
   if (!GV->hasInitializer() ||
       EmitSpecialLLVMGlobal(GV))
     return;
 
   const TargetData *TD = TM.getTargetData();
-  
   OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM));
+
   
-  std::string name = Mang->getMangledName(GV);
+  MCSymbol *GVSym = GetGlobalValueSymbol(GV);
   Constant *C = GV->getInitializer();
   unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());
   
   // Mark the start of the global
-  O << "\t.cc_top " << name << ".data," << name << "\n";
+  O << "\t.cc_top " << *GVSym << ".data," << *GVSym << "\n";
 
   switch (GV->getLinkage()) {
   case GlobalValue::AppendingLinkage:
@@ -152,19 +140,16 @@ void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
   case GlobalValue::WeakAnyLinkage:
   case GlobalValue::WeakODRLinkage:
   case GlobalValue::ExternalLinkage:
-    emitArrayBound(name, GV);
-    emitGlobalDirective(name);
+    emitArrayBound(GVSym, GV);
+    emitGlobalDirective(GVSym);
     // TODO Use COMDAT groups for LinkOnceLinkage
-    if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
-      O << TAI->getWeakDefDirective() << name << "\n";
-    }
+    if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
+      O << MAI->getWeakDefDirective() << *GVSym << "\n";
     // FALL THROUGH
   case GlobalValue::InternalLinkage:
   case GlobalValue::PrivateLinkage:
   case GlobalValue::LinkerPrivateLinkage:
     break;
-  case GlobalValue::GhostLinkage:
-    llvm_unreachable("Should not have any unmaterialized functions!");
   case GlobalValue::DLLImportLinkage:
     llvm_unreachable("DLLImport linkage is not supported by this target!");
   case GlobalValue::DLLExportLinkage:
@@ -179,26 +164,24 @@ void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
   if (GV->isThreadLocal()) {
     Size *= MaxThreads;
   }
-  if (TAI->hasDotTypeDotSizeDirective()) {
-    O << "\t.type " << name << ",@object\n";
-    O << "\t.size " << name << "," << Size << "\n";
+  if (MAI->hasDotTypeDotSizeDirective()) {
+    O << "\t.type " << *GVSym << ",@object\n";
+    O << "\t.size " << *GVSym << "," << Size << "\n";
   }
-  O << name << ":\n";
+  O << *GVSym << ":\n";
   
   EmitGlobalConstant(C);
   if (GV->isThreadLocal()) {
-    for (unsigned i = 1; i < MaxThreads; ++i) {
+    for (unsigned i = 1; i < MaxThreads; ++i)
       EmitGlobalConstant(C);
-    }
-  }
-  if (Size < 4) {
-    // The ABI requires that unsigned scalar types smaller than 32 bits
-    // are are padded to 32 bits.
-    EmitZeros(4 - Size);
   }
+  // The ABI requires that unsigned scalar types smaller than 32 bits
+  // are padded to 32 bits.
+  if (Size < 4)
+    OutStreamer.EmitZeros(4 - Size, 0);
   
   // Mark the end of the global
-  O << "\t.cc_bottom " << name << ".data\n";
+  O << "\t.cc_bottom " << *GVSym << ".data\n";
 }
 
 /// Emit the directives on the start of functions
@@ -209,7 +192,7 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
   OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
   
   // Mark the start of the function
-  O << "\t.cc_top " << CurrentFnName << ".function," << CurrentFnName << "\n";
+  O << "\t.cc_top " << *CurrentFnSym << ".function," << *CurrentFnSym << "\n";
 
   switch (F->getLinkage()) {
   default: llvm_unreachable("Unknown linkage type!");
@@ -218,48 +201,40 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
   case Function::LinkerPrivateLinkage:
     break;
   case Function::ExternalLinkage:
-    emitGlobalDirective(CurrentFnName);
+    emitGlobalDirective(CurrentFnSym);
     break;
   case Function::LinkOnceAnyLinkage:
   case Function::LinkOnceODRLinkage:
   case Function::WeakAnyLinkage:
   case Function::WeakODRLinkage:
     // TODO Use COMDAT groups for LinkOnceLinkage
-    O << TAI->getGlobalDirective() << CurrentFnName << "\n";
-    O << TAI->getWeakDefDirective() << CurrentFnName << "\n";
+    O << MAI->getGlobalDirective() << *CurrentFnSym << "\n";
+    O << MAI->getWeakDefDirective() << *CurrentFnSym << "\n";
     break;
   }
   // (1 << 1) byte aligned
   EmitAlignment(MF.getAlignment(), F, 1);
-  if (TAI->hasDotTypeDotSizeDirective()) {
-    O << "\t.type " << CurrentFnName << ",@function\n";
-  }
-  O << CurrentFnName << ":\n";
+  if (MAI->hasDotTypeDotSizeDirective())
+    O << "\t.type " << *CurrentFnSym << ",@function\n";
+
+  O << *CurrentFnSym << ":\n";
 }
 
 /// Emit the directives on the end of functions
-void XCoreAsmPrinter::
-emitFunctionEnd(MachineFunction &MF) 
-{
+void XCoreAsmPrinter::emitFunctionEnd(MachineFunction &MF) {
   // Mark the end of the function
-  O << "\t.cc_bottom " << CurrentFnName << ".function\n";
+  O << "\t.cc_bottom " << *CurrentFnSym << ".function\n";
 }
 
 /// runOnMachineFunction - This uses the printMachineInstruction()
 /// method to print assembly for each instruction.
 ///
-bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF)
-{
-  this->MF = &MF;
-
+bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   SetupMachineFunction(MF);
 
   // Print out constants referenced by the function
   EmitConstantPool(MF.getConstantPool());
 
-  // Print out jump tables referenced by the function
-  EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
-
   // Emit the function start directives
   emitFunctionStart(MF);
   
@@ -272,14 +247,12 @@ bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF)
 
     // Print a label for the basic block.
     if (I != MF.begin()) {
-      printBasicBlockLabel(I, true , true);
-      O << '\n';
+      EmitBasicBlockStart(I);
     }
 
     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
          II != E; ++II) {
       // Print the assembly for the instruction.
-      O << "\t";
       printMachineInstruction(II);
     }
 
@@ -290,6 +263,9 @@ bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF)
   // Emit function end directives
   emitFunctionEnd(MF);
   
+  // Print out jump tables referenced by the function
+  EmitJumpTableInfo(MF);
+
   // Emit post-function debug information.
   DW->EndFunction(&MF);
 
@@ -313,31 +289,31 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
   const MachineOperand &MO = MI->getOperand(opNum);
   switch (MO.getType()) {
   case MachineOperand::MO_Register:
-    if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
-      O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
-    else
-      llvm_unreachable("not implemented");
+    O << getRegisterName(MO.getReg());
     break;
   case MachineOperand::MO_Immediate:
     O << MO.getImm();
     break;
   case MachineOperand::MO_MachineBasicBlock:
-    printBasicBlockLabel(MO.getMBB());
+    O << *MO.getMBB()->getSymbol(OutContext);
     break;
   case MachineOperand::MO_GlobalAddress:
-    O << Mang->getMangledName(MO.getGlobal());
+    O << *GetGlobalValueSymbol(MO.getGlobal());
     break;
   case MachineOperand::MO_ExternalSymbol:
     O << MO.getSymbolName();
     break;
   case MachineOperand::MO_ConstantPoolIndex:
-    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
+    O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
       << '_' << MO.getIndex();
     break;
   case MachineOperand::MO_JumpTableIndex:
-    O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
       << '_' << MO.getIndex();
     break;
+  case MachineOperand::MO_BlockAddress:
+    O << *GetBlockAddressSymbol(MO.getBlockAddress());
+    break;
   default:
     llvm_unreachable("not implemented");
   }
@@ -355,24 +331,21 @@ bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
 void XCoreAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
 
+  processDebugLoc(MI, true);
+
   // Check for mov mnemonic
   unsigned src, dst, srcSR, dstSR;
   if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) {
-    O << "\tmov ";
-    O << TM.getRegisterInfo()->get(dst).AsmName;
-    O << ", ";
-    O << TM.getRegisterInfo()->get(src).AsmName;
-    O << "\n";
+    O << "\tmov " << getRegisterName(dst) << ", ";
+    O << getRegisterName(src) << '\n';
     return;
   }
   printInstruction(MI);
-}
+  if (VerboseAsm)
+    EmitComments(*MI);
+  O << '\n';
 
-bool XCoreAsmPrinter::doInitialization(Module &M) {
-  bool Result = AsmPrinter::doInitialization(M);
-  DW = getAnalysisIfAvailable<DwarfWriter>();
-  
-  return Result;
+  processDebugLoc(MI, false);
 }
 
 // Force static initialization.