It's not legal to output a GV in a coalesced section if it's used in an ARM PIC relative constantpool.

llvm-svn: 54519
This commit is contained in:
Evan Cheng 2008-08-08 06:56:16 +00:00
parent 319548b93c
commit 655fa0fec4
10 changed files with 64 additions and 29 deletions

View File

@ -30,7 +30,8 @@ namespace llvm {
const Section* DataCoalSection; const Section* DataCoalSection;
explicit DarwinTargetAsmInfo(const TargetMachine &TM); explicit DarwinTargetAsmInfo(const TargetMachine &TM);
virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
bool NoCoalesce = false) const;
virtual std::string UniqueSectionForGlobal(const GlobalValue* GV, virtual std::string UniqueSectionForGlobal(const GlobalValue* GV,
SectionKind::Kind kind) const; SectionKind::Kind kind) const;
const Section* MergeableConstSection(const GlobalVariable *GV) const; const Section* MergeableConstSection(const GlobalVariable *GV) const;

View File

@ -26,7 +26,8 @@ namespace llvm {
struct ELFTargetAsmInfo: public virtual TargetAsmInfo { struct ELFTargetAsmInfo: public virtual TargetAsmInfo {
explicit ELFTargetAsmInfo(const TargetMachine &TM); explicit ELFTargetAsmInfo(const TargetMachine &TM);
virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
bool NoCoalesce = false) const;
virtual std::string PrintSectionFlags(unsigned flags) const; virtual std::string PrintSectionFlags(unsigned flags) const;
const Section* MergeableConstSection(const GlobalVariable *GV) const; const Section* MergeableConstSection(const GlobalVariable *GV) const;
inline const Section* MergeableConstSection(const Type *Ty) const; inline const Section* MergeableConstSection(const Type *Ty) const;

View File

@ -544,8 +544,10 @@ namespace llvm {
const char* name = NULL) const; const char* name = NULL) const;
/// SectionForGlobal - This hooks returns proper section name for given /// SectionForGlobal - This hooks returns proper section name for given
/// global with all necessary flags and marks. /// global with all necessary flags and marks. If NoCoalesce is true,
virtual std::string SectionForGlobal(const GlobalValue *GV) const; /// do not use coalesced section.
virtual std::string SectionForGlobal(const GlobalValue *GV,
bool NoCoalesce = false) const;
// Helper methods for SectionForGlobal // Helper methods for SectionForGlobal
virtual std::string UniqueSectionForGlobal(const GlobalValue* GV, virtual std::string UniqueSectionForGlobal(const GlobalValue* GV,
@ -553,7 +555,8 @@ namespace llvm {
virtual std::string PrintSectionFlags(unsigned flags) const { return ""; } virtual std::string PrintSectionFlags(unsigned flags) const { return ""; }
virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
bool NoCoalesce = false) const;
virtual const Section* SelectSectionForMachineConst(const Type *Ty) const; virtual const Section* SelectSectionForMachineConst(const Type *Ty) const;

View File

@ -29,6 +29,7 @@
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
@ -65,14 +66,18 @@ namespace {
typedef std::map<const Value *, unsigned> ValueMapTy; typedef std::map<const Value *, unsigned> ValueMapTy;
ValueMapTy NumberForBB; ValueMapTy NumberForBB;
/// Keeps the set of GlobalValues that require non-lazy-pointers for /// GVNonLazyPtrs - Keeps the set of GlobalValues that require
/// indirect access. /// non-lazy-pointers for indirect access.
std::set<std::string> GVNonLazyPtrs; std::set<std::string> GVNonLazyPtrs;
/// Keeps the set of external function GlobalAddresses that the asm /// FnStubs - Keeps the set of external function GlobalAddresses that the
/// printer should generate stubs for. /// asm printer should generate stubs for.
std::set<std::string> FnStubs; std::set<std::string> FnStubs;
/// PCRelGVs - Keeps the set of GlobalValues used in pc relative
/// constantpool.
SmallPtrSet<const GlobalValue*, 8> PCRelGVs;
/// True if asm printer is printing a series of CONSTPOOL_ENTRY. /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
bool InCPMode; bool InCPMode;
@ -124,10 +129,12 @@ namespace {
/// specified function body into. /// specified function body into.
virtual std::string getSectionForFunction(const Function &F) const; virtual std::string getSectionForFunction(const Function &F) const;
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
/// the .s file.
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
printDataDirective(MCPV->getType()); printDataDirective(MCPV->getType());
ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV; ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
GlobalValue *GV = ACPV->getGV(); GlobalValue *GV = ACPV->getGV();
std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix(); std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
if (!GV) if (!GV)
@ -680,9 +687,15 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun? const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun?
MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI]; MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
if (MCPE.isMachineConstantPoolEntry()) if (MCPE.isMachineConstantPoolEntry()) {
EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
else { ARMConstantPoolValue *ACPV =
static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
if (ACPV->getPCAdjustment() != 0) {
const GlobalValue *GV = ACPV->getGV();
PCRelGVs.insert(GV);
}
} else {
EmitGlobalConstant(MCPE.Val.ConstVal); EmitGlobalConstant(MCPE.Val.ConstVal);
// remember to emit the weak reference // remember to emit the weak reference
if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal)) if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal))
@ -850,7 +863,8 @@ void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
return; return;
} }
std::string SectionName = TAI->SectionForGlobal(GVar); bool NoCoalesc = PCRelGVs.count(GVar);
std::string SectionName = TAI->SectionForGlobal(GVar, NoCoalesc);
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();
@ -887,7 +901,7 @@ void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
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 (TAI->getLCOMMDirective() != NULL) { if (TAI->getLCOMMDirective() != NULL) {
if (GVar->hasInternalLinkage()) { if (NoCoalesc || GVar->hasInternalLinkage()) {
O << TAI->getLCOMMDirective() << name << "," << Size; O << TAI->getLCOMMDirective() << name << "," << Size;
if (Subtarget->isTargetDarwin()) if (Subtarget->isTargetDarwin())
O << "," << Align; O << "," << Align;

View File

@ -51,14 +51,15 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) {
} }
const Section* const Section*
DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
bool NoCoalesce) const {
SectionKind::Kind Kind = SectionKindForGlobal(GV); SectionKind::Kind Kind = SectionKindForGlobal(GV);
bool isWeak = GV->isWeakForLinker(); bool CanCoalesce = !NoCoalesce && GV->isWeakForLinker();
bool isNonStatic = (DTM->getRelocationModel() != Reloc::Static); bool isNonStatic = (DTM->getRelocationModel() != Reloc::Static);
switch (Kind) { switch (Kind) {
case SectionKind::Text: case SectionKind::Text:
if (isWeak) if (CanCoalesce)
return TextCoalSection; return TextCoalSection;
else else
return getTextSection_(); return getTextSection_();
@ -67,18 +68,18 @@ DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
case SectionKind::BSS: case SectionKind::BSS:
case SectionKind::ThreadBSS: case SectionKind::ThreadBSS:
if (cast<GlobalVariable>(GV)->isConstant()) if (cast<GlobalVariable>(GV)->isConstant())
return (isWeak ? ConstDataCoalSection : ConstDataSection); return (CanCoalesce ? ConstDataCoalSection : ConstDataSection);
else else
return (isWeak ? DataCoalSection : getDataSection_()); return (CanCoalesce ? DataCoalSection : getDataSection_());
case SectionKind::ROData: case SectionKind::ROData:
return (isWeak ? ConstDataCoalSection : return (CanCoalesce ? ConstDataCoalSection :
(isNonStatic ? ConstDataSection : getReadOnlySection_())); (isNonStatic ? ConstDataSection : getReadOnlySection_()));
case SectionKind::RODataMergeStr: case SectionKind::RODataMergeStr:
return (isWeak ? return (CanCoalesce ?
ConstDataCoalSection : ConstDataCoalSection :
MergeableStringSection(cast<GlobalVariable>(GV))); MergeableStringSection(cast<GlobalVariable>(GV)));
case SectionKind::RODataMergeConst: case SectionKind::RODataMergeConst:
return (isWeak ? return (CanCoalesce ?
ConstDataCoalSection: ConstDataCoalSection:
MergeableConstSection(cast<GlobalVariable>(GV))); MergeableConstSection(cast<GlobalVariable>(GV)));
default: default:

View File

@ -40,7 +40,8 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) {
} }
const Section* const Section*
ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
bool NoCoalesce) const {
SectionKind::Kind Kind = SectionKindForGlobal(GV); SectionKind::Kind Kind = SectionKindForGlobal(GV);
if (const Function *F = dyn_cast<Function>(GV)) { if (const Function *F = dyn_cast<Function>(GV)) {

View File

@ -82,7 +82,7 @@ SectionKindForGlobal(const GlobalValue *GV) const {
} }
const Section* MipsTargetAsmInfo:: const Section* MipsTargetAsmInfo::
SelectSectionForGlobal(const GlobalValue *GV) const { SelectSectionForGlobal(const GlobalValue *GV, bool NoCoalesce) const {
SectionKind::Kind K = SectionKindForGlobal(GV); SectionKind::Kind K = SectionKindForGlobal(GV);
const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV); const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);

View File

@ -40,7 +40,8 @@ namespace llvm {
SectionFlagsForGlobal(const GlobalValue *GV = NULL, SectionFlagsForGlobal(const GlobalValue *GV = NULL,
const char* name = NULL) const; const char* name = NULL) const;
virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
bool NoCoalesce) const;
private: private:
const MipsSubtarget *Subtarget; const MipsSubtarget *Subtarget;

View File

@ -272,7 +272,7 @@ TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
} }
std::string std::string
TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const { TargetAsmInfo::SectionForGlobal(const GlobalValue *GV, bool NoCoalesce) const {
const Section* S; const Section* S;
// Select section name // Select section name
if (GV->hasSection()) { if (GV->hasSection()) {
@ -282,7 +282,7 @@ TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
S = getNamedSection(GV->getSection().c_str(), Flags); S = getNamedSection(GV->getSection().c_str(), Flags);
} else { } else {
// Use default section depending on the 'type' of global // Use default section depending on the 'type' of global
S = SelectSectionForGlobal(GV); S = SelectSectionForGlobal(GV, NoCoalesce);
} }
if (!S->isNamed()) if (!S->isNamed())
@ -295,8 +295,8 @@ TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
} }
// Lame default implementation. Calculate the section name for global. // Lame default implementation. Calculate the section name for global.
const Section* const Section* TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { bool NoCoalesce) const {
SectionKind::Kind Kind = SectionKindForGlobal(GV); SectionKind::Kind Kind = SectionKindForGlobal(GV);
if (GV->isWeakForLinker()) { if (GV->isWeakForLinker()) {

View File

@ -0,0 +1,13 @@
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -mattr=+v6 -relocation-model=pic | grep lcomm
%struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
%struct.__gcov_var = type { %struct.FILE*, i32, i32, i32, i32, i32, i32, [1025 x i32] }
%struct.__sFILEX = type opaque
%struct.__sbuf = type { i8*, i32 }
@__gcov_var = common global %struct.__gcov_var zeroinitializer ; <%struct.__gcov_var*> [#uses=1]
define i32 @__gcov_close() nounwind {
entry:
load i32* getelementptr (%struct.__gcov_var* @__gcov_var, i32 0, i32 5), align 4 ; <i32>:0 [#uses=1]
ret i32 %0
}