aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp76
1 files changed, 68 insertions, 8 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp b/contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp
index bc465168f1db..3f96bd37755e 100644
--- a/contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp
@@ -35,18 +35,64 @@ TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
: TheTarget(T), DL(DataLayoutString), TargetTriple(TT),
TargetCPU(std::string(CPU)), TargetFS(std::string(FS)), AsmInfo(nullptr),
MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false),
- O0WantsFastISel(false), DefaultOptions(Options), Options(Options) {}
+ O0WantsFastISel(false), Options(Options) {}
TargetMachine::~TargetMachine() = default;
-bool TargetMachine::isLargeData() const {
+bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
if (getTargetTriple().getArch() != Triple::x86_64)
return false;
- // Large data under the large code model still needs to be thought about, so
- // restrict this to medium.
- if (getCodeModel() != CodeModel::Medium)
+
+ auto *GO = GVal->getAliaseeObject();
+
+ // Be conservative if we can't find an underlying GlobalObject.
+ if (!GO)
+ return true;
+
+ auto *GV = dyn_cast<GlobalVariable>(GO);
+
+ // Functions/GlobalIFuncs are only large under the large code model.
+ if (!GV)
+ return getCodeModel() == CodeModel::Large;
+
+ if (GV->isThreadLocal())
return false;
- return true;
+
+ // We should properly mark well-known section name prefixes as small/large,
+ // because otherwise the output section may have the wrong section flags and
+ // the linker will lay it out in an unexpected way.
+ // TODO: bring back lbss/ldata/lrodata checks after fixing accesses to large
+ // globals in the small code model.
+ StringRef Name = GV->getSection();
+ if (!Name.empty()) {
+ auto IsPrefix = [&](StringRef Prefix) {
+ StringRef S = Name;
+ return S.consume_front(Prefix) && (S.empty() || S[0] == '.');
+ };
+ if (IsPrefix(".bss") || IsPrefix(".data") || IsPrefix(".rodata"))
+ return false;
+ }
+
+ // For x86-64, we treat an explicit GlobalVariable small code model to mean
+ // that the global should be placed in a small section, and ditto for large.
+ // Well-known section names above take precedence for correctness.
+ if (auto CM = GV->getCodeModel()) {
+ if (*CM == CodeModel::Small)
+ return false;
+ if (*CM == CodeModel::Large)
+ return true;
+ }
+
+ if (getCodeModel() == CodeModel::Medium ||
+ getCodeModel() == CodeModel::Large) {
+ if (!GV->getValueType()->isSized())
+ return true;
+ const DataLayout &DL = GV->getParent()->getDataLayout();
+ uint64_t Size = DL.getTypeSizeInBits(GV->getValueType()) / 8;
+ return Size == 0 || Size > LargeDataThreshold;
+ }
+
+ return false;
}
bool TargetMachine::isPositionIndependent() const {
@@ -78,6 +124,20 @@ void TargetMachine::resetTargetOptions(const Function &F) const {
/// and dynamic-no-pic.
Reloc::Model TargetMachine::getRelocationModel() const { return RM; }
+uint64_t TargetMachine::getMaxCodeSize() const {
+ switch (getCodeModel()) {
+ case CodeModel::Tiny:
+ return llvm::maxUIntN(10);
+ case CodeModel::Small:
+ case CodeModel::Kernel:
+ case CodeModel::Medium:
+ return llvm::maxUIntN(31);
+ case CodeModel::Large:
+ return llvm::maxUIntN(64);
+ }
+ llvm_unreachable("Unhandled CodeModel enum");
+}
+
/// Get the IR-specified TLS model for Var.
static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
switch (GV->getThreadLocalMode()) {
@@ -184,9 +244,9 @@ TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
}
/// Returns the optimization level: None, Less, Default, or Aggressive.
-CodeGenOpt::Level TargetMachine::getOptLevel() const { return OptLevel; }
+CodeGenOptLevel TargetMachine::getOptLevel() const { return OptLevel; }
-void TargetMachine::setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
+void TargetMachine::setOptLevel(CodeGenOptLevel Level) { OptLevel = Level; }
TargetTransformInfo
TargetMachine::getTargetTransformInfo(const Function &F) const {