Switch ARM to new section handling stuff

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54458 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anton Korobeynikov 2008-08-07 09:54:23 +00:00
parent 79579c911f
commit 0f3cc65738
5 changed files with 231 additions and 240 deletions

View File

@ -113,12 +113,17 @@ namespace {
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode); unsigned AsmVariant, const char *ExtraCode);
void printModuleLevelGV(const GlobalVariable* GVar);
bool printInstruction(const MachineInstr *MI); // autogenerated. bool printInstruction(const MachineInstr *MI); // autogenerated.
void printMachineInstruction(const MachineInstr *MI); void printMachineInstruction(const MachineInstr *MI);
bool runOnMachineFunction(MachineFunction &F); bool runOnMachineFunction(MachineFunction &F);
bool doInitialization(Module &M); bool doInitialization(Module &M);
bool doFinalization(Module &M); bool doFinalization(Module &M);
/// getSectionForFunction - Return the section that we should emit the
/// specified function body into.
virtual std::string getSectionForFunction(const Function &F) const;
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
printDataDirective(MCPV->getType()); printDataDirective(MCPV->getType());
@ -172,6 +177,11 @@ FunctionPass *llvm::createARMCodePrinterPass(std::ostream &o,
return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo()); return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo());
} }
// Substitute old hook with new one temporary
std::string ARMAsmPrinter::getSectionForFunction(const Function &F) const {
return TAI->SectionForGlobal(&F);
}
/// runOnMachineFunction - This uses the printInstruction() /// runOnMachineFunction - This uses the printInstruction()
/// method to print assembly for each instruction. /// method to print assembly for each instruction.
/// ///
@ -821,35 +831,36 @@ static void PrintUnmangledNameSafely(const Value *V, std::ostream &OS) {
OS << *Name; OS << *Name;
} }
bool ARMAsmPrinter::doFinalization(Module &M) { void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
const TargetData *TD = TM.getTargetData(); const TargetData *TD = TM.getTargetData();
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); if (!GVar->hasInitializer()) // External global require no code
I != E; ++I) { return;
if (!I->hasInitializer()) // External global require no code
continue;
if (EmitSpecialLLVMGlobal(I)) { // Check to see if this is a special global used by LLVM, if so, emit it.
if (EmitSpecialLLVMGlobal(GVar)) {
if (Subtarget->isTargetDarwin() && if (Subtarget->isTargetDarwin() &&
TM.getRelocationModel() == Reloc::Static) { TM.getRelocationModel() == Reloc::Static) {
if (I->getName() == "llvm.global_ctors") if (GVar->getName() == "llvm.global_ctors")
O << ".reference .constructors_used\n"; O << ".reference .constructors_used\n";
else if (I->getName() == "llvm.global_dtors") else if (GVar->getName() == "llvm.global_dtors")
O << ".reference .destructors_used\n"; O << ".reference .destructors_used\n";
} }
continue; return;
} }
std::string name = Mang->getValueName(I); std::string SectionName = TAI->SectionForGlobal(GVar);
Constant *C = I->getInitializer(); std::string name = Mang->getValueName(GVar);
Constant *C = GVar->getInitializer();
const Type *Type = C->getType(); const Type *Type = C->getType();
unsigned Size = TD->getABITypeSize(Type); unsigned Size = TD->getABITypeSize(Type);
unsigned Align = TD->getPreferredAlignmentLog(I); unsigned Align = TD->getPreferredAlignmentLog(GVar);
const char *VisibilityDirective = NULL; const char *VisibilityDirective = NULL;
if (I->hasHiddenVisibility()) if (GVar->hasHiddenVisibility())
VisibilityDirective = TAI->getHiddenDirective(); VisibilityDirective = TAI->getHiddenDirective();
else if (I->hasProtectedVisibility()) else if (GVar->hasProtectedVisibility())
VisibilityDirective = TAI->getProtectedDirective(); VisibilityDirective = TAI->getProtectedDirective();
if (VisibilityDirective) if (VisibilityDirective)
@ -858,56 +869,51 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
if (Subtarget->isTargetELF()) if (Subtarget->isTargetELF())
O << "\t.type " << name << ",%object\n"; O << "\t.type " << name << ",%object\n";
if (C->isNullValue() && !I->hasSection() && !I->isThreadLocal()) { SwitchToDataSection(SectionName.c_str());
if (I->hasExternalLinkage()) {
if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal()) {
// FIXME: This seems to be pretty darwin-specific
if (GVar->hasExternalLinkage()) {
if (const char *Directive = TAI->getZeroFillDirective()) { if (const char *Directive = TAI->getZeroFillDirective()) {
O << "\t.globl\t" << name << "\n"; O << "\t.globl\t" << name << "\n";
O << Directive << "__DATA, __common, " << name << ", " O << Directive << "__DATA, __common, " << name << ", "
<< Size << ", " << Align << "\n"; << Size << ", " << Align << "\n";
continue; return;
} }
} }
if (I->hasInternalLinkage() || I->hasWeakLinkage() || if (GVar->hasInternalLinkage() || GVar->isWeakForLinker()) {
I->hasLinkOnceLinkage()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
if (!NoZerosInBSS && TAI->getBSSSection())
SwitchToDataSection(TAI->getBSSSection(), I);
else
SwitchToDataSection(TAI->getDataSection(), I);
if (TAI->getLCOMMDirective() != NULL) { if (TAI->getLCOMMDirective() != NULL) {
if (I->hasInternalLinkage()) { if (GVar->hasInternalLinkage()) {
O << TAI->getLCOMMDirective() << name << "," << Size; O << TAI->getLCOMMDirective() << name << "," << Size;
if (Subtarget->isTargetDarwin()) if (Subtarget->isTargetDarwin())
O << "," << Align; O << "," << Align;
} else } else
O << TAI->getCOMMDirective() << name << "," << Size; O << TAI->getCOMMDirective() << name << "," << Size;
} else { } else {
if (I->hasInternalLinkage()) if (GVar->hasInternalLinkage())
O << "\t.local\t" << name << "\n"; O << "\t.local\t" << name << "\n";
O << TAI->getCOMMDirective() << name << "," << Size; O << TAI->getCOMMDirective() << name << "," << Size;
if (TAI->getCOMMDirectiveTakesAlignment()) if (TAI->getCOMMDirectiveTakesAlignment())
O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
} }
O << "\t\t" << TAI->getCommentString() << " "; O << "\t\t" << TAI->getCommentString() << " ";
PrintUnmangledNameSafely(I, O); PrintUnmangledNameSafely(GVar, O);
O << "\n"; O << "\n";
continue; return;
} }
} }
switch (I->getLinkage()) { switch (GVar->getLinkage()) {
case GlobalValue::LinkOnceLinkage: case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage: case GlobalValue::WeakLinkage:
if (Subtarget->isTargetDarwin()) { if (Subtarget->isTargetDarwin()) {
O << "\t.globl " << name << "\n" O << "\t.globl " << name << "\n"
<< "\t.weak_definition " << name << "\n"; << "\t.weak_definition " << name << "\n";
SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I);
} else { } else {
std::string SectionName("\t.section\t.llvm.linkonce.d." +
name +
",\"aw\",%progbits");
SwitchToDataSection(SectionName.c_str(), I);
O << "\t.weak " << name << "\n"; O << "\t.weak " << name << "\n";
} }
break; break;
@ -917,71 +923,20 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
case GlobalValue::ExternalLinkage: case GlobalValue::ExternalLinkage:
O << "\t.globl " << name << "\n"; O << "\t.globl " << name << "\n";
// FALL THROUGH // FALL THROUGH
case GlobalValue::InternalLinkage: { case GlobalValue::InternalLinkage:
if (I->isConstant()) {
const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
if (TAI->getCStringSection() && CVA && CVA->isCString()) {
SwitchToDataSection(TAI->getCStringSection(), I);
break; break;
}
}
// FIXME: special handling for ".ctors" & ".dtors" sections
if (I->hasSection() &&
(I->getSection() == ".ctors" ||
I->getSection() == ".dtors")) {
assert(!Subtarget->isTargetDarwin());
std::string SectionName = ".section " + I->getSection();
SectionName += ",\"aw\",%progbits";
SwitchToDataSection(SectionName.c_str());
} else if (I->hasSection() && Subtarget->isTargetDarwin()) {
// Honor all section names on Darwin; ObjC uses this
std::string SectionName = ".section " + I->getSection();
SwitchToDataSection(SectionName.c_str());
} else {
if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSBSSSection() :
TAI->getBSSSection(), I);
else if (!I->isConstant())
SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSDataSection() :
TAI->getDataSection(), I);
else if (I->isThreadLocal())
SwitchToDataSection(TAI->getTLSDataSection());
else {
// Read-only data.
bool HasReloc = C->ContainsRelocations();
if (HasReloc &&
Subtarget->isTargetDarwin() &&
TM.getRelocationModel() != Reloc::Static)
SwitchToDataSection("\t.const_data\n");
else if (!HasReloc && Size == 4 &&
TAI->getFourByteConstantSection())
SwitchToDataSection(TAI->getFourByteConstantSection(), I);
else if (!HasReloc && Size == 8 &&
TAI->getEightByteConstantSection())
SwitchToDataSection(TAI->getEightByteConstantSection(), I);
else if (!HasReloc && Size == 16 &&
TAI->getSixteenByteConstantSection())
SwitchToDataSection(TAI->getSixteenByteConstantSection(), I);
else if (TAI->getReadOnlySection())
SwitchToDataSection(TAI->getReadOnlySection(), I);
else
SwitchToDataSection(TAI->getDataSection(), I);
}
}
break;
}
default: default:
assert(0 && "Unknown linkage type!"); assert(0 && "Unknown linkage type!");
break; break;
} }
EmitAlignment(Align, I); EmitAlignment(Align, GVar);
O << name << ":\t\t\t\t" << TAI->getCommentString() << " "; O << name << ":\t\t\t\t" << TAI->getCommentString() << " ";
PrintUnmangledNameSafely(I, O); PrintUnmangledNameSafely(GVar, O);
O << "\n"; O << "\n";
if (TAI->hasDotTypeDotSizeDirective()) if (TAI->hasDotTypeDotSizeDirective())
O << "\t.size " << name << ", " << Size << "\n"; O << "\t.size " << name << ", " << Size << "\n";
// If the initializer is a extern weak symbol, remember to emit the weak // If the initializer is a extern weak symbol, remember to emit the weak
// reference! // reference!
if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
@ -990,7 +945,13 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
EmitGlobalConstant(C); EmitGlobalConstant(C);
O << '\n'; O << '\n';
} }
bool ARMAsmPrinter::doFinalization(Module &M) {
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I)
printModuleLevelGV(I);
if (Subtarget->isTargetDarwin()) { if (Subtarget->isTargetDarwin()) {
SwitchToDataSection(""); SwitchToDataSection("");

View File

@ -43,13 +43,28 @@ static const char *const arm_asm_table[] = {
0,0}; 0,0};
ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) { ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) {
Subtarget = &TM.getSubtarget<ARMSubtarget>();
AsmTransCBE = arm_asm_table; AsmTransCBE = arm_asm_table;
if (Subtarget->isTargetDarwin()) {
AlignmentIsInBytes = false;
Data64bitsDirective = 0;
CommentString = "@";
DataSection = "\t.data";
ConstantPoolSection = "\t.text\n";
COMMDirectiveTakesAlignment = false;
InlineAsmStart = "@ InlineAsm Start";
InlineAsmEnd = "@ InlineAsm End";
LCOMMDirective = "\t.lcomm\t";
}
ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM):
ARMTargetAsmInfo(TM), DarwinTargetAsmInfo(TM) {
Subtarget = &DTM->getSubtarget<ARMSubtarget>();
GlobalPrefix = "_"; GlobalPrefix = "_";
PrivateGlobalPrefix = "L"; PrivateGlobalPrefix = "L";
StringConstantPrefix = "\1LC"; StringConstantPrefix = "\1LC";
BSSSection = 0; // no BSS section. BSSSection = 0; // no BSS section
ZeroDirective = "\t.space\t";
ZeroFillDirective = "\t.zerofill\t"; // Uses .zerofill ZeroFillDirective = "\t.zerofill\t"; // Uses .zerofill
SetDirective = "\t.set\t"; SetDirective = "\t.set\t";
WeakRefDirective = "\t.weak_reference\t"; WeakRefDirective = "\t.weak_reference\t";
@ -89,11 +104,20 @@ ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) {
DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
} else { }
ARMELFTargetAsmInfo::ARMELFTargetAsmInfo(const ARMTargetMachine &TM):
ARMTargetAsmInfo(TM), ELFTargetAsmInfo(TM) {
Subtarget = &ETM->getSubtarget<ARMSubtarget>();
NeedsSet = false; NeedsSet = false;
HasLEB128 = true; HasLEB128 = true;
AbsoluteDebugSectionOffsets = true; AbsoluteDebugSectionOffsets = true;
CStringSection = ".rodata.str";
ReadOnlySection = "\t.section\t.rodata\n"; ReadOnlySection = "\t.section\t.rodata\n";
FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4";
EightByteConstantSection = "\t.section\t.rodata.cst8,\"aM\",@progbits,8";
SixteenByteConstantSection = "\t.section\t.rodata.cst16,\"aM\",@progbits,16";
PrivateGlobalPrefix = ".L"; PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t"; WeakRefDirective = "\t.weak\t";
SetDirective = "\t.set\t"; SetDirective = "\t.set\t";
@ -119,18 +143,6 @@ ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) {
} }
TLSDataSection = "\t.section .tdata,\"awT\",%progbits"; TLSDataSection = "\t.section .tdata,\"awT\",%progbits";
TLSBSSSection = "\t.section .tbss,\"awT\",%nobits"; TLSBSSSection = "\t.section .tbss,\"awT\",%nobits";
}
ZeroDirective = "\t.space\t";
AlignmentIsInBytes = false;
Data64bitsDirective = 0;
CommentString = "@";
DataSection = "\t.data";
ConstantPoolSection = "\t.text\n";
COMMDirectiveTakesAlignment = false;
InlineAsmStart = "@ InlineAsm Start";
InlineAsmEnd = "@ InlineAsm End";
LCOMMDirective = "\t.lcomm\t";
} }
/// Count the number of comma-separated arguments. /// Count the number of comma-separated arguments.

View File

@ -15,6 +15,9 @@
#define ARMTARGETASMINFO_H #define ARMTARGETASMINFO_H
#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/ELFTargetAsmInfo.h"
#include "llvm/Target/DarwinTargetAsmInfo.h"
#include "ARMSubtarget.h" #include "ARMSubtarget.h"
namespace llvm { namespace llvm {
@ -22,7 +25,7 @@ namespace llvm {
// Forward declaration. // Forward declaration.
class ARMTargetMachine; class ARMTargetMachine;
struct ARMTargetAsmInfo : public TargetAsmInfo { struct ARMTargetAsmInfo : public virtual TargetAsmInfo {
explicit ARMTargetAsmInfo(const ARMTargetMachine &TM); explicit ARMTargetAsmInfo(const ARMTargetMachine &TM);
const ARMSubtarget *Subtarget; const ARMSubtarget *Subtarget;
@ -32,6 +35,15 @@ namespace llvm {
unsigned countString(const char *p) const; unsigned countString(const char *p) const;
}; };
struct ARMDarwinTargetAsmInfo : public virtual ARMTargetAsmInfo,
public virtual DarwinTargetAsmInfo {
explicit ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM);
};
struct ARMELFTargetAsmInfo : public virtual ARMTargetAsmInfo,
public virtual ELFTargetAsmInfo {
explicit ARMELFTargetAsmInfo(const ARMTargetMachine &TM);
};
} // namespace llvm } // namespace llvm

View File

@ -110,7 +110,14 @@ unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
const TargetAsmInfo *ARMTargetMachine::createTargetAsmInfo() const { const TargetAsmInfo *ARMTargetMachine::createTargetAsmInfo() const {
switch (Subtarget.TargetType) {
case ARMSubtarget::isDarwin:
return new ARMDarwinTargetAsmInfo(*this);
case ARMSubtarget::isELF:
return new ARMELFTargetAsmInfo(*this);
default:
return new ARMTargetAsmInfo(*this); return new ARMTargetAsmInfo(*this);
}
} }

View File

@ -754,8 +754,6 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
if (!GVar->hasInitializer()) if (!GVar->hasInitializer())
return; // External global require no code return; // External global require no code
std::string SectionName = TAI->SectionForGlobal(GVar);
// Check to see if this is a special global used by LLVM, if so, emit it. // Check to see if this is a special global used by LLVM, if so, emit it.
if (EmitSpecialLLVMGlobal(GVar)) { if (EmitSpecialLLVMGlobal(GVar)) {
if (Subtarget->isTargetDarwin() && if (Subtarget->isTargetDarwin() &&
@ -768,6 +766,7 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
return; return;
} }
std::string SectionName = TAI->SectionForGlobal(GVar);
std::string name = Mang->getValueName(GVar); std::string name = Mang->getValueName(GVar);
Constant *C = GVar->getInitializer(); Constant *C = GVar->getInitializer();
const Type *Type = C->getType(); const Type *Type = C->getType();