Add a couple more fields, move ctor init list to .cpp file, add support

for emitting the ctor/dtor list for common targets.

llvm-svn: 24694
This commit is contained in:
Chris Lattner 2005-12-13 06:32:10 +00:00
parent 4d80f6e52e
commit f0e9aef954
2 changed files with 96 additions and 26 deletions

View File

@ -22,6 +22,7 @@
namespace llvm { namespace llvm {
class Constant; class Constant;
class Mangler; class Mangler;
class GlobalVariable;
class AsmPrinter : public MachineFunctionPass { class AsmPrinter : public MachineFunctionPass {
/// CurrentSection - The current section we are emitting to. This is /// CurrentSection - The current section we are emitting to. This is
@ -134,6 +135,16 @@ namespace llvm {
/// before emitting the constant pool for a function. /// before emitting the constant pool for a function.
const char *ConstantPoolSection; // Defaults to "\t.section .rodata\n" 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 --------------------------===// //===--- Global Variable Emission Directives --------------------------===//
/// LCOMMDirective - This is the name of a directive (if supported) that can /// 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. /// directives, this is true for most ELF targets.
bool HasDotTypeDotSizeDirective; // Defaults to true. bool HasDotTypeDotSizeDirective; // Defaults to true.
AsmPrinter(std::ostream &o, TargetMachine &tm) 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) {
}
/// SwitchSection - Switch to the specified section of the executable if we /// 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 /// 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 /// explicitly requested section, we switch to the section indicated for the
@ -210,8 +197,18 @@ namespace llvm {
/// is being processed from runOnMachineFunction. /// is being processed from runOnMachineFunction.
void SetupMachineFunction(MachineFunction &MF); 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); 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 /// 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 /// 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 /// 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. /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
/// ///
void EmitGlobalConstant(const Constant* CV); void EmitGlobalConstant(const Constant* CV);
private:
void EmitXXStructorList(Constant *List);
}; };
} }

View File

@ -21,6 +21,35 @@
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
using namespace llvm; 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 /// SwitchSection - Switch to the specified section of the executable if we
/// are not already in it! /// 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<ConstantArray>(List)) return;
ConstantArray *InitList = cast<ConstantArray>(List);
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(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. // EmitAlignment - Emit an alignment directive to the specified power of two.