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/Assembly/Writer.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
Gordon Henriksen
committed
#include "llvm/CodeGen/Collector.h"
#include "llvm/CodeGen/CollectorMetadata.h"
Chris Lattner
committed
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Streams.h"
#include "llvm/Target/TargetAsmInfo.h"
Owen Anderson
committed
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <cerrno>
using namespace llvm;
static cl::opt<bool>
AsmVerbose("asm-verbose", cl::Hidden, cl::desc("Add comments to directives."));
AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm,
const TargetAsmInfo *T)
: MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o),
TM(tm), TAI(T), TRI(tm.getRegisterInfo()),
Evan Cheng
committed
IsInTextSection(false)
std::string AsmPrinter::getSectionForFunction(const Function &F) const {
return TAI->getTextSection();
}
/// SwitchToTextSection - Switch to the specified text section of the executable
/// if we are not already in it!
void AsmPrinter::SwitchToTextSection(const char *NewSection,
const GlobalValue *GV) {
std::string NS;
if (GV && GV->hasSection())
NS = TAI->getSwitchToSectionDirective() + GV->getSection();
else
NS = NewSection;
// If we're already in this section, we're done.
if (CurrentSection == NS) return;
Chris Lattner
committed
// Close the current section, if applicable.
if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty())
O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << "\n";
Chris Lattner
committed
CurrentSection = NS;
if (!CurrentSection.empty())
O << CurrentSection << TAI->getTextSectionStartSuffix() << '\n';
Evan Cheng
committed
IsInTextSection = true;
}
/// SwitchToDataSection - Switch to the specified data section of the executable
/// if we are not already in it!
///
void AsmPrinter::SwitchToDataSection(const char *NewSection,
const GlobalValue *GV) {
std::string NS;
Chris Lattner
committed
if (GV && GV->hasSection())
NS = TAI->getSwitchToSectionDirective() + GV->getSection();
Chris Lattner
committed
else
NS = NewSection;
Chris Lattner
committed
// If we're already in this section, we're done.
if (CurrentSection == NS) return;
Chris Lattner
committed
// Close the current section, if applicable.
if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty())
O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << "\n";
Chris Lattner
committed
CurrentSection = NS;
Chris Lattner
committed
if (!CurrentSection.empty())
O << CurrentSection << TAI->getDataSectionStartSuffix() << '\n';
Evan Cheng
committed
IsInTextSection = false;
Gordon Henriksen
committed
void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
AU.addRequired<CollectorModuleMetadata>();
}
bool AsmPrinter::doInitialization(Module &M) {
Mang = new Mangler(M, TAI->getGlobalPrefix());
Gordon Henriksen
committed
CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
for (CollectorModuleMetadata::iterator I = CMM->begin(),
E = CMM->end(); I != E; ++I)
(*I)->beginAssembly(O, *this, *TAI);
O << TAI->getCommentString() << " Start of file scope inline assembly\n"
<< "\n" << TAI->getCommentString()
<< " End of file scope inline assembly\n";
SwitchToDataSection(""); // Reset back to no section.
Evan Cheng
committed
MMI = getAnalysisToUpdate<MachineModuleInfo>();
if (MMI) MMI->AnalyzeModule(M);
return false;
}
bool AsmPrinter::doFinalization(Module &M) {
if (!ExtWeakSymbols.empty())
SwitchToDataSection("");
for (std::set<const GlobalValue*>::iterator i = ExtWeakSymbols.begin(),
e = ExtWeakSymbols.end(); i != e; ++i) {
const GlobalValue *GV = *i;
std::string Name = Mang->getValueName(GV);
O << TAI->getWeakRefDirective() << Name << "\n";
}
}
if (TAI->getSetDirective()) {
if (!M.alias_empty())
SwitchToTextSection(TAI->getTextSection());
O << "\n";
for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I!=E; ++I) {
std::string Name = Mang->getValueName(I);
std::string Target;
Anton Korobeynikov
committed
const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal());
Target = Mang->getValueName(GV);
Anton Korobeynikov
committed
if (I->hasExternalLinkage() || !TAI->getWeakRefDirective())
O << "\t.globl\t" << Name << "\n";
else if (I->hasWeakLinkage())
O << TAI->getWeakRefDirective() << Name << "\n";
else if (!I->hasInternalLinkage())
assert(0 && "Invalid alias linkage");
if (I->hasHiddenVisibility()) {
if (const char *Directive = TAI->getHiddenDirective())
O << Directive << Name << "\n";
} else if (I->hasProtectedVisibility()) {
if (const char *Directive = TAI->getProtectedDirective())
O << Directive << Name << "\n";
}
O << TAI->getSetDirective() << ' ' << Name << ", " << Target << "\n";
Anton Korobeynikov
committed
// If the aliasee has external weak linkage it can be referenced only by
// alias itself. In this case it can be not in ExtWeakSymbols list. Emit
// weak reference in such case.
if (GV->hasExternalWeakLinkage()) {
Anton Korobeynikov
committed
if (TAI->getWeakRefDirective())
O << TAI->getWeakRefDirective() << Target << "\n";
else
O << "\t.globl\t" << Target << "\n";
}
}
Gordon Henriksen
committed
CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
for (CollectorModuleMetadata::iterator I = CMM->end(),
E = CMM->begin(); I != E; )
(*--I)->finishAssembly(O, *this, *TAI);
delete Mang; Mang = 0;
return false;
}
std::string AsmPrinter::getCurrentFunctionEHName(const MachineFunction *MF) {
assert(MF && "No machine function?");
Loading
Loading full blame...