Home | History | Annotate | Download | only in Lanai
      1 //
      2 //                     The LLVM Compiler Infrastructure
      3 //
      4 // This file is distributed under the University of Illinois Open Source
      5 // License. See LICENSE.TXT for details.
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #include "LanaiTargetObjectFile.h"
     10 
     11 #include "LanaiSubtarget.h"
     12 #include "LanaiTargetMachine.h"
     13 #include "llvm/IR/DataLayout.h"
     14 #include "llvm/IR/DerivedTypes.h"
     15 #include "llvm/IR/GlobalVariable.h"
     16 #include "llvm/MC/MCContext.h"
     17 #include "llvm/MC/MCSectionELF.h"
     18 #include "llvm/Support/CommandLine.h"
     19 #include "llvm/Support/ELF.h"
     20 #include "llvm/Target/TargetMachine.h"
     21 
     22 using namespace llvm;
     23 
     24 static cl::opt<unsigned> SSThreshold(
     25     "lanai-ssection-threshold", cl::Hidden,
     26     cl::desc("Small data and bss section threshold size (default=0)"),
     27     cl::init(0));
     28 
     29 void LanaiTargetObjectFile::Initialize(MCContext &Ctx,
     30                                        const TargetMachine &TM) {
     31   TargetLoweringObjectFileELF::Initialize(Ctx, TM);
     32   InitializeELF(TM.Options.UseInitArray);
     33 
     34   SmallDataSection = getContext().getELFSection(
     35       ".sdata", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
     36   SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
     37                                                ELF::SHF_WRITE | ELF::SHF_ALLOC);
     38 }
     39 
     40 // A address must be loaded from a small section if its size is less than the
     41 // small section size threshold. Data in this section must be addressed using
     42 // gp_rel operator.
     43 static bool isInSmallSection(uint64_t Size) {
     44   // gcc has traditionally not treated zero-sized objects as small data, so this
     45   // is effectively part of the ABI.
     46   return Size > 0 && Size <= SSThreshold;
     47 }
     48 
     49 // Return true if this global address should be placed into small data/bss
     50 // section.
     51 bool LanaiTargetObjectFile::isGlobalInSmallSection(
     52     const GlobalValue *GV, const TargetMachine &TM) const {
     53   // We first check the case where global is a declaration, because finding
     54   // section kind using getKindForGlobal() is only allowed for global
     55   // definitions.
     56   if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
     57     return isGlobalInSmallSectionImpl(GV, TM);
     58 
     59   return isGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
     60 }
     61 
     62 // Return true if this global address should be placed into small data/bss
     63 // section.
     64 bool LanaiTargetObjectFile::isGlobalInSmallSection(const GlobalValue *GV,
     65                                                    const TargetMachine &TM,
     66                                                    SectionKind Kind) const {
     67   return (isGlobalInSmallSectionImpl(GV, TM) &&
     68           (Kind.isData() || Kind.isBSS() || Kind.isCommon()));
     69 }
     70 
     71 // Return true if this global address should be placed into small data/bss
     72 // section. This method does all the work, except for checking the section
     73 // kind.
     74 bool LanaiTargetObjectFile::isGlobalInSmallSectionImpl(
     75     const GlobalValue *GV, const TargetMachine &TM) const {
     76   // Only global variables, not functions.
     77   const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
     78   if (!GVA)
     79     return false;
     80 
     81   if (GV->hasLocalLinkage())
     82     return false;
     83 
     84   if (((GV->hasExternalLinkage() && GV->isDeclaration()) ||
     85        GV->hasCommonLinkage()))
     86     return false;
     87 
     88   Type *Ty = GV->getType()->getElementType();
     89   return isInSmallSection(
     90       GV->getParent()->getDataLayout().getTypeAllocSize(Ty));
     91 }
     92 
     93 MCSection *
     94 LanaiTargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV,
     95                                               SectionKind Kind, Mangler &Mang,
     96                                               const TargetMachine &TM) const {
     97   // Handle Small Section classification here.
     98   if (Kind.isBSS() && isGlobalInSmallSection(GV, TM, Kind))
     99     return SmallBSSSection;
    100   if (Kind.isData() && isGlobalInSmallSection(GV, TM, Kind))
    101     return SmallDataSection;
    102 
    103   // Otherwise, we work the same as ELF.
    104   return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,
    105                                                              TM);
    106 }
    107 
    108 /// Return true if this constant should be placed into small data section.
    109 bool LanaiTargetObjectFile::isConstantInSmallSection(const DataLayout &DL,
    110                                                      const Constant *CN) const {
    111   return isInSmallSection(DL.getTypeAllocSize(CN->getType()));
    112 }
    113 
    114 MCSection *LanaiTargetObjectFile::getSectionForConstant(const DataLayout &DL,
    115                                                         SectionKind Kind,
    116                                                         const Constant *C,
    117                                                         unsigned &Align) const {
    118   if (isConstantInSmallSection(DL, C))
    119     return SmallDataSection;
    120 
    121   // Otherwise, we work the same as ELF.
    122   return TargetLoweringObjectFileELF::getSectionForConstant(DL, Kind, C, Align);
    123 }
    124