Skip to content
AsmPrinter.cpp 67.5 KiB
Newer Older
//===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the AsmPrinter class.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
David Greene's avatar
 
David Greene committed
#include "llvm/CodeGen/MachineFrameInfo.h"
David Greene's avatar
 
David Greene committed
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
David Greene's avatar
 
David Greene committed
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/DwarfWriter.h"
David Greene's avatar
 
David Greene committed
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/ErrorHandling.h"
David Greene's avatar
 
David Greene committed
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
David Greene's avatar
 
David Greene committed
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
static cl::opt<cl::boolOrDefault>
AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
           cl::init(cl::BOU_UNSET));

Devang Patel's avatar
Devang Patel committed
char AsmPrinter::ID = 0;
David Greene's avatar
 
David Greene committed
AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
                       const MCAsmInfo *T, bool VDef)
  : MachineFunctionPass(&ID), FunctionNumber(0), O(o),
    TM(tm), MAI(T), TRI(tm.getRegisterInfo()),
    // FIXME: Pass instprinter to streamer.
    OutStreamer(*createAsmStreamer(OutContext, O, *T, 0)),
  switch (AsmVerbose) {
  case cl::BOU_UNSET: VerboseAsm = VDef;  break;
  case cl::BOU_TRUE:  VerboseAsm = true;  break;
  case cl::BOU_FALSE: VerboseAsm = false; break;
  }
}
AsmPrinter::~AsmPrinter() {
  for (gcp_iterator I = GCMetadataPrinters.begin(),
                    E = GCMetadataPrinters.end(); I != E; ++I)
    delete I->second;
TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const {
  return TM.getTargetLowering()->getObjFileLowering();
}

/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *AsmPrinter::getCurrentSection() const {
  return OutStreamer.getCurrentSection();
void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
  MachineFunctionPass::getAnalysisUsage(AU);
David Greene's avatar
 
David Greene committed
  if (VerboseAsm)
David Greene's avatar
 
David Greene committed
    AU.addRequired<MachineLoopInfo>();
bool AsmPrinter::doInitialization(Module &M) {
  // Initialize TargetLoweringObjectFile.
  const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
    .Initialize(OutContext, TM);
  
  Mang = new Mangler(M, MAI->getGlobalPrefix(), MAI->getPrivateGlobalPrefix(),
                     MAI->getLinkerPrivateGlobalPrefix());
  if (MAI->doesAllowQuotesInName())

  if (MAI->doesAllowNameToStartWithDigit())
    Mang->setSymbolsCanStartWithDigit(true);
  // Allow the target to emit any magic that it wants at the start of the file.
  EmitStartOfAsmFile(M);
Rafael Espindola's avatar
Rafael Espindola committed

  if (MAI->hasSingleParameterDotFile()) {
Rafael Espindola's avatar
Rafael Espindola committed
    /* Very minimal debug info. It is ignored if we emit actual
Bob Wilson's avatar
Bob Wilson committed
       debug info. If we don't, this at least helps the user find where
Rafael Espindola's avatar
Rafael Espindola committed
       a function came from. */
    O << "\t.file\t\"" << M.getModuleIdentifier() << "\"\n";
  }

  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
  for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
    if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
      MP->beginAssembly(O, *this, *MAI);
Chris Lattner's avatar
Chris Lattner committed
  if (!M.getModuleInlineAsm().empty())
    O << MAI->getCommentString() << " Start of file scope inline assembly\n"
Chris Lattner's avatar
Chris Lattner committed
      << M.getModuleInlineAsm()
      << '\n' << MAI->getCommentString()
      << " End of file scope inline assembly\n";
  MMI = getAnalysisIfAvailable<MachineModuleInfo>();
  if (MMI)
    MMI->AnalyzeModule(M);
  DW = getAnalysisIfAvailable<DwarfWriter>();
  if (DW)
    DW->BeginModule(&M, MMI, O, this, MAI);
  return false;
}

bool AsmPrinter::doFinalization(Module &M) {
  // Emit global variables.
  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    PrintGlobalVariable(I);
  
  if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
  // If the target wants to know about weak references, print them all.
  if (MAI->getWeakRefDirective()) {
    // FIXME: This is not lazy, it would be nice to only print weak references
    // to stuff that is actually used.  Note that doing so would require targets
    // to notice uses in operands (due to constant exprs etc).  This should
    // happen with the MC stuff eventually.

    // Print out module-level global variables here.
    for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
         I != E; ++I) {
      if (I->hasExternalWeakLinkage())
        O << MAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n';
    for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
      if (I->hasExternalWeakLinkage())
        O << MAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n';
    for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
      std::string Name = Mang->getMangledName(I);

      const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal());
      std::string Target = Mang->getMangledName(GV);
Anton Korobeynikov's avatar
Anton Korobeynikov committed

      if (I->hasExternalLinkage() || !MAI->getWeakRefDirective())
        O << "\t.globl\t" << Name << '\n';
        O << MAI->getWeakRefDirective() << Name << '\n';
      else if (!I->hasLocalLinkage())
        llvm_unreachable("Invalid alias linkage");
Anton Korobeynikov's avatar
Anton Korobeynikov committed
      printVisibility(Name, I->getVisibility());
      O << MAI->getSetDirective() << ' ' << Name << ", " << Target << '\n';
  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
Loading
Loading full blame...