diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 443 |
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()); } |