diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/Target/TargetLoweringObjectFile.cpp | |
parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) | |
download | src-eb11fae6d08f479c0799db45860a98af528fa6e7.tar.gz src-eb11fae6d08f479c0799db45860a98af528fa6e7.zip |
Vendor import of llvm trunk r338150:vendor/llvm/llvm-trunk-r338150
Notes
Notes:
svn path=/vendor/llvm/dist/; revision=336809
svn path=/vendor/llvm/llvm-trunk-r338150/; revision=336814; tag=vendor/llvm/llvm-trunk-r338150
Diffstat (limited to 'lib/Target/TargetLoweringObjectFile.cpp')
-rw-r--r-- | lib/Target/TargetLoweringObjectFile.cpp | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp index 72baf5985eac..907ecf46e8ff 100644 --- a/lib/Target/TargetLoweringObjectFile.cpp +++ b/lib/Target/TargetLoweringObjectFile.cpp @@ -12,9 +12,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/CodeGen/TargetLowering.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -52,11 +51,24 @@ TargetLoweringObjectFile::~TargetLoweringObjectFile() { delete Mang; } -static bool isSuitableForBSS(const GlobalVariable *GV, bool NoZerosInBSS) { +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 (!C->isNullValue()) + if (!isNullOrUndef(C)) return false; // Leave constant zeros in readonly constant sections, so they can be shared. @@ -67,10 +79,6 @@ static bool isSuitableForBSS(const GlobalVariable *GV, bool NoZerosInBSS) { if (GV->hasSection()) return false; - // If -nozero-initialized-in-bss is specified, don't ever use BSS. - if (NoZerosInBSS) - return false; - // Otherwise, put it in BSS! return true; } @@ -126,25 +134,24 @@ void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer, /// getKindForGlobal - This is a top-level target-independent classifier for -/// a global variable. Given an global variable and information from TM, it -/// classifies the global in a variety of ways that make various target -/// implementations simpler. The target implementation is free to ignore this -/// extra info of course. +/// 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"); - Reloc::Model ReloModel = TM.getRelocationModel(); - - // Early exit - functions should be always in text sections. - const auto *GVar = dyn_cast<GlobalVariable>(GO); - if (!GVar) + // 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)) + if (isSuitableForBSS(GVar) && !TM.Options.NoZerosInBSS) return SectionKind::getThreadBSS(); return SectionKind::getThreadData(); } @@ -153,8 +160,9 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO, if (GVar->hasCommonLinkage()) return SectionKind::getCommon(); - // Variable can be easily put to BSS section. - if (isSuitableForBSS(GVar, TM.Options.NoZerosInBSS)) { + // 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()) @@ -162,14 +170,13 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO, return SectionKind::getBSS(); } - const Constant *C = GVar->getInitializer(); - // 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 @@ -215,6 +222,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO, // 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(); |