brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.7 KiB · 118689b Raw
126 lines · cpp
1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7 8#include "LanaiTargetObjectFile.h"9 10#include "llvm/BinaryFormat/ELF.h"11#include "llvm/IR/DataLayout.h"12#include "llvm/IR/GlobalVariable.h"13#include "llvm/MC/MCContext.h"14#include "llvm/MC/MCSectionELF.h"15#include "llvm/Support/CommandLine.h"16#include "llvm/Target/TargetMachine.h"17 18using namespace llvm;19 20static cl::opt<unsigned> SSThreshold(21    "lanai-ssection-threshold", cl::Hidden,22    cl::desc("Small data and bss section threshold size (default=0)"),23    cl::init(0));24 25void LanaiTargetObjectFile::Initialize(MCContext &Ctx,26                                       const TargetMachine &TM) {27  TargetLoweringObjectFileELF::Initialize(Ctx, TM);28 29  SmallDataSection = getContext().getELFSection(30      ".sdata", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);31  SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,32                                               ELF::SHF_WRITE | ELF::SHF_ALLOC);33}34 35// A address must be loaded from a small section if its size is less than the36// small section size threshold. Data in this section must be addressed using37// gp_rel operator.38static bool isInSmallSection(uint64_t Size) {39  // gcc has traditionally not treated zero-sized objects as small data, so this40  // is effectively part of the ABI.41  return Size > 0 && Size <= SSThreshold;42}43 44// Return true if this global address should be placed into small data/bss45// section.46bool LanaiTargetObjectFile::isGlobalInSmallSection(47    const GlobalObject *GO, const TargetMachine &TM) const {48  if (GO == nullptr) return TM.getCodeModel() == CodeModel::Small;49 50  // We first check the case where global is a declaration, because finding51  // section kind using getKindForGlobal() is only allowed for global52  // definitions.53  if (GO->isDeclaration() || GO->hasAvailableExternallyLinkage())54    return isGlobalInSmallSectionImpl(GO, TM);55 56  return isGlobalInSmallSection(GO, TM, getKindForGlobal(GO, TM));57}58 59// Return true if this global address should be placed into small data/bss60// section.61bool LanaiTargetObjectFile::isGlobalInSmallSection(const GlobalObject *GO,62                                                   const TargetMachine &TM,63                                                   SectionKind Kind) const {64  return isGlobalInSmallSectionImpl(GO, TM);65}66 67// Return true if this global address should be placed into small data/bss68// section. This method does all the work, except for checking the section69// kind.70bool LanaiTargetObjectFile::isGlobalInSmallSectionImpl(71    const GlobalObject *GO, const TargetMachine &TM) const {72  const auto *GVA = dyn_cast<GlobalVariable>(GO);73 74  // If not a GlobalVariable, only consider the code model.75  if (!GVA) return TM.getCodeModel() == CodeModel::Small;76 77  // Global values placed in sections starting with .ldata do not fit in78  // 21-bits, so always use large memory access for them. FIXME: This is a79  // workaround for a tool limitation.80  if (GVA->getSection().starts_with(".ldata"))81    return false;82 83  if (TM.getCodeModel() == CodeModel::Small)84    return true;85 86  if (GVA->hasLocalLinkage())87    return false;88 89  if (((GVA->hasExternalLinkage() && GVA->isDeclaration()) ||90       GVA->hasCommonLinkage()))91    return false;92 93  Type *Ty = GVA->getValueType();94  return isInSmallSection(95      GVA->getDataLayout().getTypeAllocSize(Ty));96}97 98MCSection *LanaiTargetObjectFile::SelectSectionForGlobal(99    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {100  // Handle Small Section classification here.101  if (Kind.isBSS() && isGlobalInSmallSection(GO, TM, Kind))102    return SmallBSSSection;103  if (Kind.isData() && isGlobalInSmallSection(GO, TM, Kind))104    return SmallDataSection;105 106  // Otherwise, we work the same as ELF.107  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);108}109 110/// Return true if this constant should be placed into small data section.111bool LanaiTargetObjectFile::isConstantInSmallSection(const DataLayout &DL,112                                                     const Constant *CN) const {113  return isInSmallSection(DL.getTypeAllocSize(CN->getType()));114}115 116MCSection *LanaiTargetObjectFile::getSectionForConstant(117    const DataLayout &DL, SectionKind Kind, const Constant *C,118    Align &Alignment) const {119  if (isConstantInSmallSection(DL, C))120    return SmallDataSection;121 122  // Otherwise, we work the same as ELF.123  return TargetLoweringObjectFileELF::getSectionForConstant(DL, Kind, C,124                                                            Alignment);125}126