forked from OSchip/llvm-project
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:
parent
319548b93c
commit
655fa0fec4
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue