diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp | 76 |
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 { |
