aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp443
1 files changed, 311 insertions, 132 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 27bebe503ce6..fe64b38cf0be 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -21,6 +21,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/CodeGen/BasicBlockSectionUtils.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -39,6 +40,7 @@
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/PseudoProbe.h"
#include "llvm/IR/Type.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
@@ -104,10 +106,14 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
// ELF
//===----------------------------------------------------------------------===//
+TargetLoweringObjectFileELF::TargetLoweringObjectFileELF()
+ : TargetLoweringObjectFile() {
+ SupportDSOLocalEquivalentLowering = true;
+}
+
void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
const TargetMachine &TgtM) {
TargetLoweringObjectFile::Initialize(Ctx, TgtM);
- TM = &TgtM;
CodeModel::Model CM = TgtM.getCodeModel();
InitializeELF(TgtM.Options.UseInitArray);
@@ -122,6 +128,7 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
// Fallthrough if not using EHABI
LLVM_FALLTHROUGH;
case Triple::ppc:
+ case Triple::ppcle:
case Triple::x86:
PersonalityEncoding = isPositionIndependent()
? dwarf::DW_EH_PE_indirect |
@@ -174,11 +181,20 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
// will be in memory. Most of these could end up >2GB away so even a signed
// pc-relative 32-bit address is insufficient, theoretically.
if (isPositionIndependent()) {
- PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
- dwarf::DW_EH_PE_sdata8;
- LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
- TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
- dwarf::DW_EH_PE_sdata8;
+ // ILP32 uses sdata4 instead of sdata8
+ if (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32) {
+ PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata4;
+ LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata4;
+ } else {
+ PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata8;
+ LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
+ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata8;
+ }
} else {
PersonalityEncoding = dwarf::DW_EH_PE_absptr;
LSDAEncoding = dwarf::DW_EH_PE_absptr;
@@ -310,6 +326,29 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
}
}
+ if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) {
+ // Emit a descriptor for every function including functions that have an
+ // available external linkage. We may not want this for imported functions
+ // that has code in another thinLTO module but we don't have a good way to
+ // tell them apart from inline functions defined in header files. Therefore
+ // we put each descriptor in a separate comdat section and rely on the
+ // linker to deduplicate.
+ for (const auto *Operand : FuncInfo->operands()) {
+ const auto *MD = cast<MDNode>(Operand);
+ auto *GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
+ auto *Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
+ auto *Name = cast<MDString>(MD->getOperand(2));
+ auto *S = C.getObjectFileInfo()->getPseudoProbeDescSection(
+ TM->getFunctionSections() ? Name->getString() : StringRef());
+
+ Streamer.SwitchSection(S);
+ Streamer.emitInt64(GUID->getZExtValue());
+ Streamer.emitInt64(Hash->getZExtValue());
+ Streamer.emitULEB128IntValue(Name->getString().size());
+ Streamer.emitBytes(Name->getString());
+ }
+ }
+
unsigned Version = 0;
unsigned Flags = 0;
StringRef Section;
@@ -324,46 +363,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
Streamer.AddBlankLine();
}
- SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
- M.getModuleFlagsMetadata(ModuleFlags);
-
- MDNode *CFGProfile = nullptr;
-
- for (const auto &MFE : ModuleFlags) {
- StringRef Key = MFE.Key->getString();
- if (Key == "CG Profile") {
- CFGProfile = cast<MDNode>(MFE.Val);
- break;
- }
- }
-
- if (!CFGProfile)
- return;
-
- auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * {
- if (!MDO)
- return nullptr;
- auto V = cast<ValueAsMetadata>(MDO);
- const Function *F = cast<Function>(V->getValue());
- return TM->getSymbol(F);
- };
-
- for (const auto &Edge : CFGProfile->operands()) {
- MDNode *E = cast<MDNode>(Edge);
- const MCSymbol *From = GetSym(E->getOperand(0));
- const MCSymbol *To = GetSym(E->getOperand(1));
- // Skip null functions. This can happen if functions are dead stripped after
- // the CGProfile pass has been run.
- if (!From || !To)
- continue;
- uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2))
- ->getValue()
- ->getUniqueInteger()
- .getZExtValue();
- Streamer.emitCGProfileEntry(
- MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C),
- MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count);
- }
+ emitCGProfileMetadata(Streamer, M);
}
MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
@@ -436,7 +436,8 @@ static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF,
/*AddSegmentInfo=*/false) ||
Name == getInstrProfSectionName(IPSK_covfun, Triple::ELF,
- /*AddSegmentInfo=*/false))
+ /*AddSegmentInfo=*/false) ||
+ Name == ".llvmbc" || Name == ".llvmcmd")
return SectionKind::getMetadata();
if (Name.empty() || Name[0] != '.') return K;
@@ -614,7 +615,7 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
bool HasPrefix = false;
if (const auto *F = dyn_cast<Function>(GO)) {
if (Optional<StringRef> Prefix = F->getSectionPrefix()) {
- Name += *Prefix;
+ raw_svector_ostream(Name) << '.' << *Prefix;
HasPrefix = true;
}
}
@@ -680,11 +681,12 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
// MD_associated in a unique section.
unsigned UniqueID = MCContext::GenericSectionID;
const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
- if (LinkedToSym) {
+ if (GO->getMetadata(LLVMContext::MD_associated)) {
UniqueID = NextUniqueID++;
Flags |= ELF::SHF_LINK_ORDER;
} else {
- if (getContext().getAsmInfo()->useIntegratedAssembler()) {
+ if (getContext().getAsmInfo()->useIntegratedAssembler() ||
+ getContext().getAsmInfo()->binutilsIsAtLeast(2, 35)) {
// Symbols must be placed into sections with compatible entry
// sizes. Generate unique sections for symbols that have not
// been assigned to compatible sections.
@@ -735,8 +737,9 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
assert(Section->getLinkedToSymbol() == LinkedToSym &&
"Associated symbol mismatch between sections");
- if (!getContext().getAsmInfo()->useIntegratedAssembler()) {
- // If we are not using the integrated assembler then this symbol might have
+ if (!(getContext().getAsmInfo()->useIntegratedAssembler() ||
+ getContext().getAsmInfo()->binutilsIsAtLeast(2, 35))) {
+ // If we are using GNU as before 2.35, then this symbol might have
// been placed in an incompatible mergeable section. Emit an error if this
// is the case to avoid creating broken output.
if ((Section->getFlags() & ELF::SHF_MERGE) &&
@@ -831,6 +834,43 @@ MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
/* AssociatedSymbol */ nullptr);
}
+MCSection *
+TargetLoweringObjectFileELF::getSectionForLSDA(const Function &F,
+ const TargetMachine &TM) const {
+ // If neither COMDAT nor function sections, use the monolithic LSDA section.
+ // Re-use this path if LSDASection is null as in the Arm EHABI.
+ if (!LSDASection || (!F.hasComdat() && !TM.getFunctionSections()))
+ return LSDASection;
+
+ const auto *LSDA = cast<MCSectionELF>(LSDASection);
+ unsigned Flags = LSDA->getFlags();
+ StringRef Group;
+ if (F.hasComdat()) {
+ Group = F.getComdat()->getName();
+ Flags |= ELF::SHF_GROUP;
+ }
+
+ // Append the function name as the suffix like GCC, assuming
+ // -funique-section-names applies to .gcc_except_table sections.
+ if (TM.getUniqueSectionNames())
+ return getContext().getELFSection(LSDA->getName() + "." + F.getName(),
+ LSDA->getType(), Flags, 0, Group,
+ MCSection::NonUniqueID, nullptr);
+
+ // Allocate a unique ID if function sections && (integrated assembler or GNU
+ // as>=2.35). Note we could use SHF_LINK_ORDER to facilitate --gc-sections but
+ // that would require that we know the linker is a modern LLD (12.0 or later).
+ // GNU ld as of 2.35 does not support mixed SHF_LINK_ORDER &
+ // non-SHF_LINK_ORDER components in an output section
+ // https://sourceware.org/bugzilla/show_bug.cgi?id=26256
+ unsigned ID = TM.getFunctionSections() &&
+ getContext().getAsmInfo()->useIntegratedAssembler()
+ ? NextUniqueID++
+ : MCSection::NonUniqueID;
+ return getContext().getELFSection(LSDA->getName(), LSDA->getType(), Flags, 0,
+ Group, ID, nullptr);
+}
+
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
bool UsesLabelDifference, const Function &F) const {
// We can always create relative relocations, so use another section
@@ -865,14 +905,14 @@ MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
assert(MBB.isBeginSection() && "Basic block does not start a section!");
unsigned UniqueID = MCContext::GenericSectionID;
- // For cold sections use the .text.unlikely prefix along with the parent
+ // For cold sections use the .text.split. prefix along with the parent
// function name. All cold blocks for the same function go to the same
// section. Similarly all exception blocks are grouped by symbol name
// under the .text.eh prefix. For regular sections, we either use a unique
// name, or a unique ID for the section.
SmallString<128> Name;
if (MBB.getSectionID() == MBBSectionID::ColdSectionID) {
- Name += ".text.unlikely.";
+ Name += BBSectionsColdTextPrefix;
Name += MBB.getParent()->getName();
} else if (MBB.getSectionID() == MBBSectionID::ExceptionSectionID) {
Name += ".text.eh.";
@@ -888,7 +928,7 @@ MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
}
unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
- std::string GroupName = "";
+ std::string GroupName;
if (F.hasComdat()) {
Flags |= ELF::SHF_GROUP;
GroupName = F.getComdat()->getName().str();
@@ -968,6 +1008,20 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
}
+const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent(
+ const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const {
+ assert(supportDSOLocalEquivalentLowering());
+
+ const auto *GV = Equiv->getGlobalValue();
+
+ // A PLT entry is not needed for dso_local globals.
+ if (GV->isDSOLocal() || GV->isImplicitDSOLocal())
+ return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext());
+
+ return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeVariantKind,
+ getContext());
+}
+
MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
// Use ".GCC.command.line" since this feature is to support clang's
// -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the
@@ -1515,6 +1569,10 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
MCSymbol *Sym = TM.getSymbol(ComdatGV);
StringRef COMDATSymName = Sym->getName();
+ if (const auto *F = dyn_cast<Function>(GO))
+ if (Optional<StringRef> Prefix = F->getSectionPrefix())
+ raw_svector_ostream(Name) << '$' << *Prefix;
+
// Append "$symbol" to the section name *before* IR-level mangling is
// applied when targetting mingw. This is what GCC does, and the ld.bfd
// COFF linker will not properly handle comdats otherwise.
@@ -1590,6 +1648,31 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
Module &M) const {
+ emitLinkerDirectives(Streamer, M);
+
+ unsigned Version = 0;
+ unsigned Flags = 0;
+ StringRef Section;
+
+ GetObjCImageInfo(M, Version, Flags, Section);
+ if (!Section.empty()) {
+ auto &C = getContext();
+ auto *S = C.getCOFFSection(Section,
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getReadOnly());
+ Streamer.SwitchSection(S);
+ Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
+ Streamer.emitInt32(Version);
+ Streamer.emitInt32(Flags);
+ Streamer.AddBlankLine();
+ }
+
+ emitCGProfileMetadata(Streamer, M);
+}
+
+void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
+ MCStreamer &Streamer, Module &M) const {
if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
// Emit the linker options to the linker .drectve section. According to the
// spec, this section is a space-separated string containing flags for
@@ -1606,28 +1689,51 @@ void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
}
}
- unsigned Version = 0;
- unsigned Flags = 0;
- StringRef Section;
-
- GetObjCImageInfo(M, Version, Flags, Section);
- if (Section.empty())
- return;
+ // Emit /EXPORT: flags for each exported global as necessary.
+ std::string Flags;
+ for (const GlobalValue &GV : M.global_values()) {
+ raw_string_ostream OS(Flags);
+ emitLinkerFlagsForGlobalCOFF(OS, &GV, getTargetTriple(), getMangler());
+ OS.flush();
+ if (!Flags.empty()) {
+ Streamer.SwitchSection(getDrectveSection());
+ Streamer.emitBytes(Flags);
+ }
+ Flags.clear();
+ }
- auto &C = getContext();
- auto *S = C.getCOFFSection(
- Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getReadOnly());
- Streamer.SwitchSection(S);
- Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
- Streamer.emitInt32(Version);
- Streamer.emitInt32(Flags);
- Streamer.AddBlankLine();
+ // Emit /INCLUDE: flags for each used global as necessary.
+ if (const auto *LU = M.getNamedGlobal("llvm.used")) {
+ assert(LU->hasInitializer() && "expected llvm.used to have an initializer");
+ assert(isa<ArrayType>(LU->getValueType()) &&
+ "expected llvm.used to be an array type");
+ if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {
+ for (const Value *Op : A->operands()) {
+ const auto *GV = cast<GlobalValue>(Op->stripPointerCasts());
+ // Global symbols with internal or private linkage are not visible to
+ // the linker, and thus would cause an error when the linker tried to
+ // preserve the symbol due to the `/include:` directive.
+ if (GV->hasLocalLinkage())
+ continue;
+
+ raw_string_ostream OS(Flags);
+ emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
+ OS.flush();
+
+ if (!Flags.empty()) {
+ Streamer.SwitchSection(getDrectveSection());
+ Streamer.emitBytes(Flags);
+ }
+ Flags.clear();
+ }
+ }
+ }
}
void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
TargetLoweringObjectFile::Initialize(Ctx, TM);
+ this->TM = &TM;
const Triple &T = TM.getTargetTriple();
if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
StaticCtorSection =
@@ -1702,16 +1808,6 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
cast<MCSectionCOFF>(StaticDtorSection));
}
-void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
- raw_ostream &OS, const GlobalValue *GV) const {
- emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler());
-}
-
-void TargetLoweringObjectFileCOFF::emitLinkerFlagsForUsed(
- raw_ostream &OS, const GlobalValue *GV) const {
- emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
-}
-
const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
const GlobalValue *LHS, const GlobalValue *RHS,
const TargetMachine &TM) const {
@@ -1882,7 +1978,7 @@ static MCSectionWasm *selectWasmSectionForGlobal(
if (const auto *F = dyn_cast<Function>(GO)) {
const auto &OptionalPrefix = F->getSectionPrefix();
if (OptionalPrefix)
- Name += *OptionalPrefix;
+ raw_svector_ostream(Name) << '.' << *OptionalPrefix;
}
if (EmitUniqueSection && UniqueSectionNames) {
@@ -1970,14 +2066,36 @@ MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection(
//===----------------------------------------------------------------------===//
// XCOFF
//===----------------------------------------------------------------------===//
+bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(
+ const MachineFunction *MF) {
+ if (!MF->getLandingPads().empty())
+ return true;
+
+ const Function &F = MF->getFunction();
+ if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry())
+ return false;
+
+ const Function *Per =
+ dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
+ if (isNoOpWithoutInvoke(classifyEHPersonality(Per)))
+ return false;
+
+ return true;
+}
+
+MCSymbol *
+TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) {
+ return MF->getMMI().getContext().getOrCreateSymbol(
+ "__ehinfo." + Twine(MF->getFunctionNumber()));
+}
+
MCSymbol *
TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
const TargetMachine &TM) const {
- if (TM.getDataSections())
- report_fatal_error("XCOFF unique data sections not yet implemented");
-
// We always use a qualname symbol for a GV that represents
// a declaration, a function descriptor, or a common symbol.
+ // If a GV represents a GlobalVariable and -fdata-sections is enabled, we
+ // also return a qualname so that a label symbol could be avoided.
// It is inherently ambiguous when the GO represents the address of a
// function, as the GO could either represent a function descriptor or a
// function entry point. We choose to always return a function descriptor
@@ -1992,21 +2110,34 @@ TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
return cast<MCSectionXCOFF>(
getSectionForFunctionDescriptor(cast<Function>(GO), TM))
->getQualNameSymbol();
- if (GOKind.isCommon() || GOKind.isBSSLocal())
+ if ((TM.getDataSections() && !GO->hasSection()) || GOKind.isCommon() ||
+ GOKind.isBSSLocal())
return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM))
->getQualNameSymbol();
}
// For all other cases, fall back to getSymbol to return the unqualified name.
- // This could change for a GV that is a GlobalVariable when we decide to
- // support -fdata-sections since we could avoid having label symbols if the
- // linkage name is applied to the csect symbol.
return nullptr;
}
MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
- report_fatal_error("XCOFF explicit sections not yet implemented.");
+ if (!GO->hasSection())
+ report_fatal_error("#pragma clang section is not yet supported");
+
+ StringRef SectionName = GO->getSection();
+ XCOFF::StorageMappingClass MappingClass;
+ if (Kind.isText())
+ MappingClass = XCOFF::XMC_PR;
+ else if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS())
+ MappingClass = XCOFF::XMC_RW;
+ else if (Kind.isReadOnly())
+ MappingClass = XCOFF::XMC_RO;
+ else
+ report_fatal_error("XCOFF other section types not yet implemented.");
+
+ return getContext().getXCOFFSection(SectionName, MappingClass, XCOFF::XTY_SD,
+ Kind, /* MultiSymbolsAllowed*/ true);
}
MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference(
@@ -2016,30 +2147,23 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference(
SmallString<128> Name;
getNameWithPrefix(Name, GO, TM);
- XCOFF::StorageClass SC =
- TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO);
// Externals go into a csect of type ER.
return getContext().getXCOFFSection(
Name, isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA, XCOFF::XTY_ER,
- SC, SectionKind::getMetadata());
+ SectionKind::getMetadata());
}
MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
- assert(!TM.getFunctionSections() && !TM.getDataSections() &&
- "XCOFF unique sections not yet implemented.");
-
// Common symbols go into a csect with matching name which will get mapped
// into the .bss section.
if (Kind.isBSSLocal() || Kind.isCommon()) {
SmallString<128> Name;
getNameWithPrefix(Name, GO, TM);
- XCOFF::StorageClass SC =
- TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO);
return getContext().getXCOFFSection(
Name, Kind.isBSSLocal() ? XCOFF::XMC_BS : XCOFF::XMC_RW, XCOFF::XTY_CM,
- SC, Kind, /* BeginSymbolName */ nullptr);
+ Kind);
}
if (Kind.isMergeableCString()) {
@@ -2051,40 +2175,65 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
SmallString<128> Name;
Name = SizeSpec + utostr(Alignment.value());
+ if (TM.getDataSections())
+ getNameWithPrefix(Name, GO, TM);
+
return getContext().getXCOFFSection(
- Name, XCOFF::XMC_RO, XCOFF::XTY_SD,
- TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO),
- Kind, /* BeginSymbolName */ nullptr);
+ Name, XCOFF::XMC_RO, XCOFF::XTY_SD, Kind,
+ /* MultiSymbolsAllowed*/ !TM.getDataSections());
}
- if (Kind.isText())
+ if (Kind.isText()) {
+ if (TM.getFunctionSections()) {
+ return cast<MCSymbolXCOFF>(getFunctionEntryPointSymbol(GO, TM))
+ ->getRepresentedCsect();
+ }
return TextSection;
+ }
- if (Kind.isData() || Kind.isReadOnlyWithRel())
- // TODO: We may put this under option control, because user may want to
- // have read-only data with relocations placed into a read-only section by
- // the compiler.
- return DataSection;
-
- // Zero initialized data must be emitted to the .data section because external
- // linkage control sections that get mapped to the .bss section will be linked
- // as tentative defintions, which is only appropriate for SectionKind::Common.
- if (Kind.isBSS())
+ // TODO: We may put Kind.isReadOnlyWithRel() under option control, because
+ // user may want to have read-only data with relocations placed into a
+ // read-only section by the compiler.
+ // For BSS kind, zero initialized data must be emitted to the .data section
+ // because external linkage control sections that get mapped to the .bss
+ // section will be linked as tentative defintions, which is only appropriate
+ // for SectionKind::Common.
+ if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS()) {
+ if (TM.getDataSections()) {
+ SmallString<128> Name;
+ getNameWithPrefix(Name, GO, TM);
+ return getContext().getXCOFFSection(Name, XCOFF::XMC_RW, XCOFF::XTY_SD,
+ SectionKind::getData());
+ }
return DataSection;
+ }
- if (Kind.isReadOnly())
+ if (Kind.isReadOnly()) {
+ if (TM.getDataSections()) {
+ SmallString<128> Name;
+ getNameWithPrefix(Name, GO, TM);
+ return getContext().getXCOFFSection(Name, XCOFF::XMC_RO, XCOFF::XTY_SD,
+ SectionKind::getReadOnly());
+ }
return ReadOnlySection;
+ }
report_fatal_error("XCOFF other section types not yet implemented.");
}
MCSection *TargetLoweringObjectFileXCOFF::getSectionForJumpTable(
const Function &F, const TargetMachine &TM) const {
- assert (!TM.getFunctionSections() && "Unique sections not supported on XCOFF"
- " yet.");
assert (!F.getComdat() && "Comdat not supported on XCOFF.");
- //TODO: Enable emiting jump table to unique sections when we support it.
- return ReadOnlySection;
+
+ if (!TM.getFunctionSections())
+ return ReadOnlySection;
+
+ // If the function can be removed, produce a unique section so that
+ // the table doesn't prevent the removal.
+ SmallString<128> NameStr(".rodata.jmp..");
+ getNameWithPrefix(NameStr, &F, TM);
+ return getContext().getXCOFFSection(NameStr, XCOFF::XMC_RO, XCOFF::XTY_SD,
+ SectionKind::getReadOnly());
}
bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection(
@@ -2104,19 +2253,23 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForConstant(
void TargetLoweringObjectFileXCOFF::Initialize(MCContext &Ctx,
const TargetMachine &TgtM) {
TargetLoweringObjectFile::Initialize(Ctx, TgtM);
- TTypeEncoding = 0;
+ TTypeEncoding =
+ dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
+ (TgtM.getTargetTriple().isArch32Bit() ? dwarf::DW_EH_PE_sdata4
+ : dwarf::DW_EH_PE_sdata8);
PersonalityEncoding = 0;
LSDAEncoding = 0;
+ CallSiteEncoding = dwarf::DW_EH_PE_udata4;
}
MCSection *TargetLoweringObjectFileXCOFF::getStaticCtorSection(
- unsigned Priority, const MCSymbol *KeySym) const {
- report_fatal_error("XCOFF ctor section not yet implemented.");
+ unsigned Priority, const MCSymbol *KeySym) const {
+ report_fatal_error("no static constructor section on AIX");
}
MCSection *TargetLoweringObjectFileXCOFF::getStaticDtorSection(
- unsigned Priority, const MCSymbol *KeySym) const {
- report_fatal_error("XCOFF dtor section not yet implemented.");
+ unsigned Priority, const MCSymbol *KeySym) const {
+ report_fatal_error("no static destructor section on AIX");
}
const MCExpr *TargetLoweringObjectFileXCOFF::lowerRelativeReference(
@@ -2125,9 +2278,11 @@ const MCExpr *TargetLoweringObjectFileXCOFF::lowerRelativeReference(
report_fatal_error("XCOFF not yet implemented.");
}
-XCOFF::StorageClass TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(
- const GlobalObject *GO) {
- switch (GO->getLinkage()) {
+XCOFF::StorageClass
+TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) {
+ assert(!isa<GlobalIFunc>(GV) && "GlobalIFunc is not supported on AIX.");
+
+ switch (GV->getLinkage()) {
case GlobalValue::InternalLinkage:
case GlobalValue::PrivateLinkage:
return XCOFF::C_HIDEXT;
@@ -2149,10 +2304,32 @@ XCOFF::StorageClass TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(
}
MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol(
- const Function *F, const TargetMachine &TM) const {
+ const GlobalValue *Func, const TargetMachine &TM) const {
+ assert(
+ (isa<Function>(Func) ||
+ (isa<GlobalAlias>(Func) &&
+ isa_and_nonnull<Function>(cast<GlobalAlias>(Func)->getBaseObject()))) &&
+ "Func must be a function or an alias which has a function as base "
+ "object.");
+
SmallString<128> NameStr;
NameStr.push_back('.');
- getNameWithPrefix(NameStr, F, TM);
+ getNameWithPrefix(NameStr, Func, TM);
+
+ // When -function-sections is enabled and explicit section is not specified,
+ // it's not necessary to emit function entry point label any more. We will use
+ // function entry point csect instead. And for function delcarations, the
+ // undefined symbols gets treated as csect with XTY_ER property.
+ if (((TM.getFunctionSections() && !Func->hasSection()) ||
+ Func->isDeclaration()) &&
+ isa<Function>(Func)) {
+ return getContext()
+ .getXCOFFSection(NameStr, XCOFF::XMC_PR,
+ Func->isDeclaration() ? XCOFF::XTY_ER : XCOFF::XTY_SD,
+ SectionKind::getText())
+ ->getQualNameSymbol();
+ }
+
return getContext().getOrCreateSymbol(NameStr);
}
@@ -2161,13 +2338,15 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForFunctionDescriptor(
SmallString<128> NameStr;
getNameWithPrefix(NameStr, F, TM);
return getContext().getXCOFFSection(NameStr, XCOFF::XMC_DS, XCOFF::XTY_SD,
- getStorageClassForGlobal(F),
SectionKind::getData());
}
MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry(
- const MCSymbol *Sym) const {
+ const MCSymbol *Sym, const TargetMachine &TM) const {
+ // Use TE storage-mapping class when large code model is enabled so that
+ // the chance of needing -bbigtoc is decreased.
return getContext().getXCOFFSection(
- cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(), XCOFF::XMC_TC,
- XCOFF::XTY_SD, XCOFF::C_HIDEXT, SectionKind::getData());
+ cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(),
+ TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC,
+ XCOFF::XTY_SD, SectionKind::getData());
}