add a new AsmPrinter::EmitFunctionEntryLabel virtual function,

which allows targets to override function entry label emission.
Use it to convert linux/ppc to use EmitFunctionHeader().


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94667 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-01-27 07:21:55 +00:00
parent ed240c474d
commit 2cf7251d39
3 changed files with 34 additions and 55 deletions

View File

@ -335,6 +335,8 @@ namespace llvm {
void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0);
protected:
virtual void EmitFunctionEntryLabel();
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
/// processDebugLoc - Processes the debug information of each machine

View File

@ -313,8 +313,11 @@ void AsmPrinter::EmitFunctionHeader() {
/*PrintType=*/false, F->getParent());
OutStreamer.GetCommentOS() << '\n';
}
OutStreamer.EmitLabel(CurrentFnSym);
// Emit the CurrentFnSym. This is is a virtual function to allow targets to
// do their wild and crazy things as required.
EmitFunctionEntryLabel();
// Add some workaround for linkonce linkage on Cygwin\MinGW.
if (MAI->getLinkOnceDirective() != 0 &&
(F->hasLinkOnceLinkage() || F->hasWeakLinkage()))
@ -326,7 +329,11 @@ void AsmPrinter::EmitFunctionHeader() {
DW->BeginFunction(MF);
}
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
/// function. This can be overridden by targets as required to do custom stuff.
void AsmPrinter::EmitFunctionEntryLabel() {
OutStreamer.EmitLabel(CurrentFnSym);
}
bool AsmPrinter::doFinalization(Module &M) {

View File

@ -337,6 +337,8 @@ namespace {
bool runOnMachineFunction(MachineFunction &F);
bool doFinalization(Module &M);
virtual void EmitFunctionEntryLabel();
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineModuleInfo>();
@ -594,77 +596,45 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
processDebugLoc(MI, false);
}
void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label.
return AsmPrinter::EmitFunctionEntryLabel();
// Emit an official procedure descriptor.
// FIXME 64-bit SVR4: Use MCSection here!
O << "\t.section\t\".opd\",\"aw\"\n";
O << "\t.align 3\n";
OutStreamer.EmitLabel(CurrentFnSym);
O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n";
O << "\t.previous\n";
O << ".L." << *CurrentFnSym << ":\n";
}
/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.
///
bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
SetupMachineFunction(MF);
O << "\n\n";
// Print out constants referenced by the function
EmitConstantPool(MF.getConstantPool());
// Print out labels for the function.
const Function *F = MF.getFunction();
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
switch (F->getLinkage()) {
default: llvm_unreachable("Unknown linkage type!");
case Function::PrivateLinkage:
case Function::InternalLinkage: // Symbols default to internal.
break;
case Function::ExternalLinkage:
O << "\t.global\t" << *CurrentFnSym << '\n' << "\t.type\t";
O << *CurrentFnSym << ", @function\n";
break;
case Function::LinkerPrivateLinkage:
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
O << "\t.global\t" << *CurrentFnSym << '\n';
O << "\t.weak\t" << *CurrentFnSym << '\n';
break;
}
printVisibility(CurrentFnSym, F->getVisibility());
EmitAlignment(MF.getAlignment(), F);
if (Subtarget.isPPC64()) {
// Emit an official procedure descriptor.
// FIXME 64-bit SVR4: Use MCSection here!
O << "\t.section\t\".opd\",\"aw\"\n";
O << "\t.align 3\n";
O << *CurrentFnSym << ":\n";
O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n";
O << "\t.previous\n";
O << ".L." << *CurrentFnSym << ":\n";
} else {
O << *CurrentFnSym << ":\n";
}
// Emit pre-function debug information.
DW->BeginFunction(&MF);
EmitFunctionHeader();
// Print out code for the function.
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
// Print a label for the basic block.
if (I != MF.begin()) {
if (I != MF.begin())
EmitBasicBlockStart(I);
}
// Print the assembly for the instructions.
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
II != E; ++II) {
// Print the assembly for the instruction.
II != E; ++II)
printMachineInstruction(II);
}
}
O << "\t.size\t" << *CurrentFnSym << ",.-" << *CurrentFnSym << '\n';
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
// Emit post-function debug information.
DW->EndFunction(&MF);