HexagonTargetObjectFile.cpp revision 280031
1234285Sdim//===-- HexagonTargetObjectFile.cpp - Hexagon asm properties --------------===// 2234285Sdim// 3234285Sdim// The LLVM Compiler Infrastructure 4234285Sdim// 5234285Sdim// This file is distributed under the University of Illinois Open Source 6234285Sdim// License. See LICENSE.TXT for details. 7234285Sdim// 8234285Sdim//===----------------------------------------------------------------------===// 9234285Sdim// 10234285Sdim// This file contains the declarations of the HexagonTargetAsmInfo properties. 11234285Sdim// 12234285Sdim//===----------------------------------------------------------------------===// 13234285Sdim 14234285Sdim#include "HexagonTargetObjectFile.h" 15234285Sdim#include "HexagonSubtarget.h" 16234285Sdim#include "HexagonTargetMachine.h" 17249423Sdim#include "llvm/IR/DataLayout.h" 18249423Sdim#include "llvm/IR/DerivedTypes.h" 19249423Sdim#include "llvm/IR/Function.h" 20249423Sdim#include "llvm/IR/GlobalVariable.h" 21234285Sdim#include "llvm/MC/MCContext.h" 22249423Sdim#include "llvm/Support/CommandLine.h" 23234285Sdim#include "llvm/Support/ELF.h" 24234285Sdim 25234285Sdimusing namespace llvm; 26234285Sdim 27234285Sdimstatic cl::opt<int> SmallDataThreshold("hexagon-small-data-threshold", 28261991Sdim cl::init(8), cl::Hidden, 29261991Sdim cl::desc("The maximum size of an object in the sdata section")); 30234285Sdim 31234285Sdimvoid HexagonTargetObjectFile::Initialize(MCContext &Ctx, 32234285Sdim const TargetMachine &TM) { 33234285Sdim TargetLoweringObjectFileELF::Initialize(Ctx, TM); 34280031Sdim InitializeELF(TM.Options.UseInitArray); 35234285Sdim 36234285Sdim SmallDataSection = 37234285Sdim getContext().getELFSection(".sdata", ELF::SHT_PROGBITS, 38234285Sdim ELF::SHF_WRITE | ELF::SHF_ALLOC, 39234285Sdim SectionKind::getDataRel()); 40234285Sdim SmallBSSSection = 41234285Sdim getContext().getELFSection(".sbss", ELF::SHT_NOBITS, 42234285Sdim ELF::SHF_WRITE | ELF::SHF_ALLOC, 43234285Sdim SectionKind::getBSS()); 44234285Sdim} 45234285Sdim 46234285Sdim// sdata/sbss support taken largely from the MIPS Backend. 47234285Sdimstatic bool IsInSmallSection(uint64_t Size) { 48234285Sdim return Size > 0 && Size <= (uint64_t)SmallDataThreshold; 49234285Sdim} 50261991Sdim 51261991Sdimbool HexagonTargetObjectFile::IsSmallDataEnabled () const { 52261991Sdim return SmallDataThreshold > 0; 53261991Sdim} 54261991Sdim 55234285Sdim/// IsGlobalInSmallSection - Return true if this global value should be 56234285Sdim/// placed into small data/bss section. 57234285Sdimbool HexagonTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV, 58234285Sdim const TargetMachine &TM) const { 59234285Sdim // If the primary definition of this global value is outside the current 60234285Sdim // translation unit or the global value is available for inspection but not 61234285Sdim // emission, then do nothing. 62234285Sdim if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) 63234285Sdim return false; 64234285Sdim 65234285Sdim // Otherwise, Check if GV should be in sdata/sbss, when normally it would end 66234285Sdim // up in getKindForGlobal(GV, TM). 67234285Sdim return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM)); 68234285Sdim} 69234285Sdim 70234285Sdim/// IsGlobalInSmallSection - Return true if this global value should be 71234285Sdim/// placed into small data/bss section. 72234285Sdimbool HexagonTargetObjectFile:: 73234285SdimIsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM, 74234285Sdim SectionKind Kind) const { 75234285Sdim // Only global variables, not functions. 76234285Sdim const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV); 77234285Sdim if (!GVA) 78234285Sdim return false; 79234285Sdim 80234285Sdim if (Kind.isBSS() || Kind.isDataNoRel() || Kind.isCommon()) { 81234285Sdim Type *Ty = GV->getType()->getElementType(); 82280031Sdim return IsInSmallSection( 83280031Sdim TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(Ty)); 84234285Sdim } 85234285Sdim 86234285Sdim return false; 87234285Sdim} 88234285Sdim 89276479Sdimconst MCSection * 90276479SdimHexagonTargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV, 91276479Sdim SectionKind Kind, Mangler &Mang, 92276479Sdim const TargetMachine &TM) const { 93234285Sdim 94234285Sdim // Handle Small Section classification here. 95234285Sdim if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind)) 96234285Sdim return SmallBSSSection; 97234285Sdim if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind)) 98234285Sdim return SmallDataSection; 99234285Sdim 100234285Sdim // Otherwise, we work the same as ELF. 101234285Sdim return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM); 102234285Sdim} 103