From ed13893ff729bc3b91697f6d80a3ba303782efcc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 13 Dec 2005 06:32:10 +0000 Subject: [PATCH] Add a couple more fields, move ctor init list to .cpp file, add support for emitting the ctor/dtor list for common targets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24694 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 52 +++++++++++------------ lib/CodeGen/AsmPrinter.cpp | 70 +++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 26 deletions(-) diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 5c2c15f3dd7..6fc48ee6e2d 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -22,6 +22,7 @@ namespace llvm { class Constant; class Mangler; + class GlobalVariable; class AsmPrinter : public MachineFunctionPass { /// CurrentSection - The current section we are emitting to. This is @@ -134,6 +135,16 @@ namespace llvm { /// before emitting the constant pool for a function. const char *ConstantPoolSection; // Defaults to "\t.section .rodata\n" + /// StaticCtorsSection - This is the directive that is emitted to switch to + /// a section to emit the static constructor list. + /// Defaults to "\t.section .ctors,\"aw\",@progbits". + const char *StaticCtorsSection; + + /// StaticDtorsSection - This is the directive that is emitted to switch to + /// a section to emit the static destructor list. + /// Defaults to "\t.section .dtors,\"aw\",@progbits". + const char *StaticDtorsSection; + //===--- Global Variable Emission Directives --------------------------===// /// LCOMMDirective - This is the name of a directive (if supported) that can @@ -152,32 +163,8 @@ namespace llvm { /// directives, this is true for most ELF targets. bool HasDotTypeDotSizeDirective; // Defaults to true. - AsmPrinter(std::ostream &o, TargetMachine &tm) - : FunctionNumber(0), O(o), TM(tm), - CommentString("#"), - GlobalPrefix(""), - PrivateGlobalPrefix("."), - GlobalVarAddrPrefix(""), - GlobalVarAddrSuffix(""), - FunctionAddrPrefix(""), - FunctionAddrSuffix(""), - ZeroDirective("\t.zero\t"), - AsciiDirective("\t.ascii\t"), - AscizDirective("\t.asciz\t"), - Data8bitsDirective("\t.byte\t"), - Data16bitsDirective("\t.short\t"), - Data32bitsDirective("\t.long\t"), - Data64bitsDirective("\t.quad\t"), - AlignDirective("\t.align\t"), - AlignmentIsInBytes(true), - SwitchToSectionDirective("\t.section\t"), - ConstantPoolSection("\t.section .rodata\n"), - LCOMMDirective(0), - COMMDirective("\t.comm\t"), - COMMDirectiveTakesAlignment(true), - HasDotTypeDotSizeDirective(true) { - } - + AsmPrinter(std::ostream &o, TargetMachine &TM); + /// SwitchSection - Switch to the specified section of the executable if we /// are not already in it! If GV is non-null and if the global has an /// explicitly requested section, we switch to the section indicated for the @@ -210,8 +197,18 @@ namespace llvm { /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); + /// EmitConstantPool - Print to the current output stream assembly + /// representations of the constants in the constant pool MCP. This is + /// used to print out constants which have been "spilled to memory" by + /// the code generator. + /// void EmitConstantPool(MachineConstantPool *MCP); + /// EmitSpecialLLVMGlobal - Check to see if the specified global is a + /// special global used by LLVM. If so, emit it and return true, otherwise + /// do nothing and return false. + bool EmitSpecialLLVMGlobal(const GlobalVariable *GV); + /// EmitAlignment - Emit an alignment directive to the specified power of /// two boundary. For example, if you pass in 3 here, you will get an 8 /// byte alignment. If a global value is specified, and if that global has @@ -229,6 +226,9 @@ namespace llvm { /// EmitGlobalConstant - Print a general LLVM constant to the .s file. /// void EmitGlobalConstant(const Constant* CV); + + private: + void EmitXXStructorList(Constant *List); }; } diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index dd100c6e19c..0539d463250 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -21,6 +21,35 @@ #include "llvm/Target/TargetMachine.h" using namespace llvm; +AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm) +: FunctionNumber(0), O(o), TM(tm), + CommentString("#"), + GlobalPrefix(""), + PrivateGlobalPrefix("."), + GlobalVarAddrPrefix(""), + GlobalVarAddrSuffix(""), + FunctionAddrPrefix(""), + FunctionAddrSuffix(""), + ZeroDirective("\t.zero\t"), + AsciiDirective("\t.ascii\t"), + AscizDirective("\t.asciz\t"), + Data8bitsDirective("\t.byte\t"), + Data16bitsDirective("\t.short\t"), + Data32bitsDirective("\t.long\t"), + Data64bitsDirective("\t.quad\t"), + AlignDirective("\t.align\t"), + AlignmentIsInBytes(true), + SwitchToSectionDirective("\t.section\t"), + ConstantPoolSection("\t.section .rodata\n"), + StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"), + StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"), + LCOMMDirective(0), + COMMDirective("\t.comm\t"), + COMMDirectiveTakesAlignment(true), + HasDotTypeDotSizeDirective(true) { +} + + /// SwitchSection - Switch to the specified section of the executable if we /// are not already in it! /// @@ -80,6 +109,47 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { } } +/// EmitSpecialLLVMGlobal - Check to see if the specified global is a +/// special global used by LLVM. If so, emit it and return true, otherwise +/// do nothing and return false. +bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { + assert(GV->hasInitializer() && GV->hasAppendingLinkage() && + "Not a special LLVM global!"); + + if (GV->getName() == "llvm.used") + return true; // No need to emit this at all. + + if (GV->getName() == "llvm.global_ctors") { + SwitchSection(StaticCtorsSection, 0); + EmitAlignment(2, 0); + EmitXXStructorList(GV->getInitializer()); + return true; + } + + if (GV->getName() == "llvm.global_dtors") { + SwitchSection(StaticDtorsSection, 0); + EmitAlignment(2, 0); + EmitXXStructorList(GV->getInitializer()); + return true; + } + + return false; +} + +/// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the +/// function pointers, ignoring the init priority. +void AsmPrinter::EmitXXStructorList(Constant *List) { + // Should be an array of '{ int, void ()* }' structs. The first value is the + // init priority, which we ignore. + if (!isa(List)) return; + ConstantArray *InitList = cast(List); + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) + if (ConstantStruct *CS = dyn_cast(InitList->getOperand(i))){ + if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. + // Emit the function pointer. + EmitGlobalConstant(CS->getOperand(1)); + } +} // EmitAlignment - Emit an alignment directive to the specified power of two.