aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/TargetLoweringObjectFile.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
commiteb11fae6d08f479c0799db45860a98af528fa6e7 (patch)
tree44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/Target/TargetLoweringObjectFile.cpp
parentb8a2042aa938069e862750553db0e4d82d25822c (diff)
downloadsrc-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.cpp52
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();