Skip to content
AsmPrinter.cpp 64.4 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/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"
#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()),
    OutStreamer(*createAsmStreamer(OutContext, O, *T, this)),
    PrevDLT(0, ~0U, ~0U) {
  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())
  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
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
       debug info. If we don't, this at helps the user find where
       a function came from. */
    O << "\t.file\t\"" << M.getModuleIdentifier() << "\"\n";
  }

  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";
  if (MAI->doesSupportDebugInformation() ||
      MAI->doesSupportExceptionHandling()) {
    MMI = getAnalysisIfAvailable<MachineModuleInfo>();
    if (MMI)
    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?");
  for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
    if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
      MP->finishAssembly(O, *this, *MAI);
  // If we don't have any trampolines, then we don't require stack memory
  // to be executable. Some targets have a directive to declare this.
Loading
Loading full blame...