diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
commit | 0b57cec536236d46e3dba9bd041533462f33dbb7 (patch) | |
tree | 56229dbdbbf76d18580f72f789003db17246c8d9 /contrib/llvm/lib/Target/TargetLoweringObjectFile.cpp | |
parent | 718ef55ec7785aae63f98f8ca05dc07ed399c16d (diff) |
Notes
Diffstat (limited to 'contrib/llvm/lib/Target/TargetLoweringObjectFile.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/TargetLoweringObjectFile.cpp | 346 |
1 files changed, 0 insertions, 346 deletions
diff --git a/contrib/llvm/lib/Target/TargetLoweringObjectFile.cpp b/contrib/llvm/lib/Target/TargetLoweringObjectFile.cpp deleted file mode 100644 index 17274e1c2c6e..000000000000 --- a/contrib/llvm/lib/Target/TargetLoweringObjectFile.cpp +++ /dev/null @@ -1,346 +0,0 @@ -//===-- llvm/Target/TargetLoweringObjectFile.cpp - Object File Info -------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements classes used to handle lowerings specific to common -// object file formats. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/GlobalVariable.h" -#include "llvm/IR/Mangler.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Generic Code -//===----------------------------------------------------------------------===// - -/// Initialize - this method must be called before any actual lowering is -/// done. This specifies the current context for codegen, and gives the -/// lowering implementations a chance to set up their default sections. -void TargetLoweringObjectFile::Initialize(MCContext &ctx, - const TargetMachine &TM) { - Ctx = &ctx; - // `Initialize` can be called more than once. - delete Mang; - Mang = new Mangler(); - InitMCObjectFileInfo(TM.getTargetTriple(), TM.isPositionIndependent(), *Ctx, - TM.getCodeModel() == CodeModel::Large); - - // Reset various EH DWARF encodings. - PersonalityEncoding = LSDAEncoding = TTypeEncoding = dwarf::DW_EH_PE_absptr; - CallSiteEncoding = dwarf::DW_EH_PE_uleb128; -} - -TargetLoweringObjectFile::~TargetLoweringObjectFile() { - delete Mang; -} - -static bool isNullOrUndef(const Constant *C) { - // Check that the constant isn't all zeros or undefs. - if (C->isNullValue() || isa<UndefValue>(C)) - return true; - if (!isa<ConstantAggregate>(C)) - return false; - for (auto Operand : C->operand_values()) { - if (!isNullOrUndef(cast<Constant>(Operand))) - return false; - } - return true; -} - -static bool isSuitableForBSS(const GlobalVariable *GV) { - const Constant *C = GV->getInitializer(); - - // Must have zero initializer. - if (!isNullOrUndef(C)) - return false; - - // Leave constant zeros in readonly constant sections, so they can be shared. - if (GV->isConstant()) - return false; - - // If the global has an explicit section specified, don't put it in BSS. - if (GV->hasSection()) - return false; - - // Otherwise, put it in BSS! - return true; -} - -/// IsNullTerminatedString - Return true if the specified constant (which is -/// known to have a type that is an array of 1/2/4 byte elements) ends with a -/// nul value and contains no other nuls in it. Note that this is more general -/// than ConstantDataSequential::isString because we allow 2 & 4 byte strings. -static bool IsNullTerminatedString(const Constant *C) { - // First check: is we have constant array terminated with zero - if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(C)) { - unsigned NumElts = CDS->getNumElements(); - assert(NumElts != 0 && "Can't have an empty CDS"); - - if (CDS->getElementAsInteger(NumElts-1) != 0) - return false; // Not null terminated. - - // Verify that the null doesn't occur anywhere else in the string. - for (unsigned i = 0; i != NumElts-1; ++i) - if (CDS->getElementAsInteger(i) == 0) - return false; - return true; - } - - // Another possibility: [1 x i8] zeroinitializer - if (isa<ConstantAggregateZero>(C)) - return cast<ArrayType>(C->getType())->getNumElements() == 1; - - return false; -} - -MCSymbol *TargetLoweringObjectFile::getSymbolWithGlobalValueBase( - const GlobalValue *GV, StringRef Suffix, const TargetMachine &TM) const { - assert(!Suffix.empty()); - - SmallString<60> NameStr; - NameStr += GV->getParent()->getDataLayout().getPrivateGlobalPrefix(); - TM.getNameWithPrefix(NameStr, GV, *Mang); - NameStr.append(Suffix.begin(), Suffix.end()); - return Ctx->getOrCreateSymbol(NameStr); -} - -MCSymbol *TargetLoweringObjectFile::getCFIPersonalitySymbol( - const GlobalValue *GV, const TargetMachine &TM, - MachineModuleInfo *MMI) const { - return TM.getSymbol(GV); -} - -void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer, - const DataLayout &, - const MCSymbol *Sym) const { -} - - -/// getKindForGlobal - This is a top-level target-independent classifier for -/// a global object. Given a global variable and information from the TM, this -/// function classifies the global in a target independent manner. This function -/// may be overridden by the target implementation. -SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO, - const TargetMachine &TM){ - assert(!GO->isDeclaration() && !GO->hasAvailableExternallyLinkage() && - "Can only be used for global definitions"); - - // Functions are classified as text sections. - if (isa<Function>(GO)) - return SectionKind::getText(); - - // Global variables require more detailed analysis. - const auto *GVar = cast<GlobalVariable>(GO); - - // Handle thread-local data first. - if (GVar->isThreadLocal()) { - if (isSuitableForBSS(GVar) && !TM.Options.NoZerosInBSS) - return SectionKind::getThreadBSS(); - return SectionKind::getThreadData(); - } - - // Variables with common linkage always get classified as common. - if (GVar->hasCommonLinkage()) - return SectionKind::getCommon(); - - // Most non-mergeable zero data can be put in the BSS section unless otherwise - // specified. - if (isSuitableForBSS(GVar) && !TM.Options.NoZerosInBSS) { - if (GVar->hasLocalLinkage()) - return SectionKind::getBSSLocal(); - else if (GVar->hasExternalLinkage()) - return SectionKind::getBSSExtern(); - return SectionKind::getBSS(); - } - - // If the global is marked constant, we can put it into a mergable section, - // a mergable string section, or general .data if it contains relocations. - if (GVar->isConstant()) { - // If the initializer for the global contains something that requires a - // relocation, then we may have to drop this into a writable data section - // even though it is marked const. - const Constant *C = GVar->getInitializer(); - if (!C->needsRelocation()) { - // If the global is required to have a unique address, it can't be put - // into a mergable section: just drop it into the general read-only - // section instead. - if (!GVar->hasGlobalUnnamedAddr()) - return SectionKind::getReadOnly(); - - // If initializer is a null-terminated string, put it in a "cstring" - // section of the right width. - if (ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) { - if (IntegerType *ITy = - dyn_cast<IntegerType>(ATy->getElementType())) { - if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 || - ITy->getBitWidth() == 32) && - IsNullTerminatedString(C)) { - if (ITy->getBitWidth() == 8) - return SectionKind::getMergeable1ByteCString(); - if (ITy->getBitWidth() == 16) - return SectionKind::getMergeable2ByteCString(); - - assert(ITy->getBitWidth() == 32 && "Unknown width"); - return SectionKind::getMergeable4ByteCString(); - } - } - } - - // Otherwise, just drop it into a mergable constant section. If we have - // a section for this size, use it, otherwise use the arbitrary sized - // mergable section. - switch ( - GVar->getParent()->getDataLayout().getTypeAllocSize(C->getType())) { - case 4: return SectionKind::getMergeableConst4(); - case 8: return SectionKind::getMergeableConst8(); - case 16: return SectionKind::getMergeableConst16(); - case 32: return SectionKind::getMergeableConst32(); - default: - return SectionKind::getReadOnly(); - } - - } else { - // In static, ROPI and RWPI relocation models, the linker will resolve - // all addresses, so the relocation entries will actually be constants by - // the time the app starts up. However, we can't put this into a - // mergable section, because the linker doesn't take relocations into - // consideration when it tries to merge entries in the section. - Reloc::Model ReloModel = TM.getRelocationModel(); - if (ReloModel == Reloc::Static || ReloModel == Reloc::ROPI || - ReloModel == Reloc::RWPI || ReloModel == Reloc::ROPI_RWPI) - return SectionKind::getReadOnly(); - - // Otherwise, the dynamic linker needs to fix it up, put it in the - // writable data.rel section. - return SectionKind::getReadOnlyWithRel(); - } - } - - // Okay, this isn't a constant. - return SectionKind::getData(); -} - -/// This method computes the appropriate section to emit the specified global -/// variable or function definition. This should not be passed external (or -/// available externally) globals. -MCSection *TargetLoweringObjectFile::SectionForGlobal( - const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { - // Select section name. - if (GO->hasSection()) - return getExplicitSectionGlobal(GO, Kind, TM); - - if (auto *GVar = dyn_cast<GlobalVariable>(GO)) { - auto Attrs = GVar->getAttributes(); - if ((Attrs.hasAttribute("bss-section") && Kind.isBSS()) || - (Attrs.hasAttribute("data-section") && Kind.isData()) || - (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly())) { - return getExplicitSectionGlobal(GO, Kind, TM); - } - } - - if (auto *F = dyn_cast<Function>(GO)) { - if (F->hasFnAttribute("implicit-section-name")) - return getExplicitSectionGlobal(GO, Kind, TM); - } - - // Use default section depending on the 'type' of global - return SelectSectionForGlobal(GO, Kind, TM); -} - -MCSection *TargetLoweringObjectFile::getSectionForJumpTable( - const Function &F, const TargetMachine &TM) const { - unsigned Align = 0; - return getSectionForConstant(F.getParent()->getDataLayout(), - SectionKind::getReadOnly(), /*C=*/nullptr, - Align); -} - -bool TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( - bool UsesLabelDifference, const Function &F) const { - // In PIC mode, we need to emit the jump table to the same section as the - // function body itself, otherwise the label differences won't make sense. - // FIXME: Need a better predicate for this: what about custom entries? - if (UsesLabelDifference) - return true; - - // We should also do if the section name is NULL or function is declared - // in discardable section - // FIXME: this isn't the right predicate, should be based on the MCSection - // for the function. - return F.isWeakForLinker(); -} - -/// Given a mergable constant with the specified size and relocation -/// information, return a section that it should be placed in. -MCSection *TargetLoweringObjectFile::getSectionForConstant( - const DataLayout &DL, SectionKind Kind, const Constant *C, - unsigned &Align) const { - if (Kind.isReadOnly() && ReadOnlySection != nullptr) - return ReadOnlySection; - - return DataSection; -} - -/// getTTypeGlobalReference - Return an MCExpr to use for a -/// reference to the specified global variable from exception -/// handling information. -const MCExpr *TargetLoweringObjectFile::getTTypeGlobalReference( - const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, - MachineModuleInfo *MMI, MCStreamer &Streamer) const { - const MCSymbolRefExpr *Ref = - MCSymbolRefExpr::create(TM.getSymbol(GV), getContext()); - - return getTTypeReference(Ref, Encoding, Streamer); -} - -const MCExpr *TargetLoweringObjectFile:: -getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, - MCStreamer &Streamer) const { - switch (Encoding & 0x70) { - default: - report_fatal_error("We do not support this DWARF encoding yet!"); - case dwarf::DW_EH_PE_absptr: - // Do nothing special - return Sym; - case dwarf::DW_EH_PE_pcrel: { - // Emit a label to the streamer for the current position. This gives us - // .-foo addressing. - MCSymbol *PCSym = getContext().createTempSymbol(); - Streamer.EmitLabel(PCSym); - const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext()); - return MCBinaryExpr::createSub(Sym, PC, getContext()); - } - } -} - -const MCExpr *TargetLoweringObjectFile::getDebugThreadLocalSymbol(const MCSymbol *Sym) const { - // FIXME: It's not clear what, if any, default this should have - perhaps a - // null return could mean 'no location' & we should just do that here. - return MCSymbolRefExpr::create(Sym, *Ctx); -} - -void TargetLoweringObjectFile::getNameWithPrefix( - SmallVectorImpl<char> &OutName, const GlobalValue *GV, - const TargetMachine &TM) const { - Mang->getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/false); -} |