diff options
Diffstat (limited to 'contrib/llvm/lib/Target/TargetMachine.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/TargetMachine.cpp | 117 |
1 files changed, 75 insertions, 42 deletions
diff --git a/contrib/llvm/lib/Target/TargetMachine.cpp b/contrib/llvm/lib/Target/TargetMachine.cpp index 850c93cb21b8..82c68505c4e1 100644 --- a/contrib/llvm/lib/Target/TargetMachine.cpp +++ b/contrib/llvm/lib/Target/TargetMachine.cpp @@ -18,21 +18,23 @@ #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Mangler.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/SectionKind.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; +cl::opt<bool> EnableIPRA("enable-ipra", cl::init(false), cl::Hidden, + cl::desc("Enable interprocedural register allocation " + "to reduce load/store at procedure calls.")); + //--------------------------------------------------------------------------- // TargetMachine Class // @@ -41,18 +43,23 @@ TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options) : TheTarget(T), DL(DataLayoutString), TargetTriple(TT), TargetCPU(CPU), - TargetFS(FS), CodeGenInfo(nullptr), AsmInfo(nullptr), MRI(nullptr), - MII(nullptr), STI(nullptr), RequireStructuredCFG(false), - Options(Options) {} + TargetFS(FS), AsmInfo(nullptr), MRI(nullptr), MII(nullptr), STI(nullptr), + RequireStructuredCFG(false), Options(Options) { + if (EnableIPRA.getNumOccurrences()) + this->Options.EnableIPRA = EnableIPRA; +} TargetMachine::~TargetMachine() { - delete CodeGenInfo; delete AsmInfo; delete MRI; delete MII; delete STI; } +bool TargetMachine::isPositionIndependent() const { + return getRelocationModel() == Reloc::PIC_; +} + /// \brief Reset the target options based on the function's attributes. // FIXME: This function needs to go away for a number of reasons: // a) global state on the TargetMachine is terrible in general, @@ -72,21 +79,13 @@ void TargetMachine::resetTargetOptions(const Function &F) const { RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math"); } -/// getRelocationModel - Returns the code generation relocation model. The -/// choices are static, PIC, and dynamic-no-pic, and target default. -Reloc::Model TargetMachine::getRelocationModel() const { - if (!CodeGenInfo) - return Reloc::Default; - return CodeGenInfo->getRelocationModel(); -} +/// Returns the code generation relocation model. The choices are static, PIC, +/// and dynamic-no-pic. +Reloc::Model TargetMachine::getRelocationModel() const { return RM; } -/// getCodeModel - Returns the code model. The choices are small, kernel, -/// medium, large, and target default. -CodeModel::Model TargetMachine::getCodeModel() const { - if (!CodeGenInfo) - return CodeModel::Default; - return CodeGenInfo->getCodeModel(); -} +/// Returns the code model. The choices are small, kernel, medium, large, and +/// target default. +CodeModel::Model TargetMachine::getCodeModel() const { return CMModel; } /// Get the IR-specified TLS model for Var. static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) { @@ -106,23 +105,65 @@ static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) { llvm_unreachable("invalid TLS model"); } +// FIXME: make this a proper option +static bool CanUseCopyRelocWithPIE = false; + +bool TargetMachine::shouldAssumeDSOLocal(const Module &M, + const GlobalValue *GV) const { + Reloc::Model RM = getRelocationModel(); + const Triple &TT = getTargetTriple(); + + // DLLImport explicitly marks the GV as external. + if (GV && GV->hasDLLImportStorageClass()) + return false; + + // Every other GV is local on COFF + if (TT.isOSBinFormatCOFF()) + return true; + + if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility())) + return true; + + if (TT.isOSBinFormatMachO()) { + if (RM == Reloc::Static) + return true; + return GV && GV->isStrongDefinitionForLinker(); + } + + assert(TT.isOSBinFormatELF()); + assert(RM != Reloc::DynamicNoPIC); + + bool IsExecutable = + RM == Reloc::Static || M.getPIELevel() != PIELevel::Default; + if (IsExecutable) { + // If the symbol is defined, it cannot be preempted. + if (GV && !GV->isDeclarationForLinker()) + return true; + + bool IsTLS = GV && GV->isThreadLocal(); + // Check if we can use copy relocations. + if (!IsTLS && (RM == Reloc::Static || CanUseCopyRelocWithPIE)) + return true; + } + + // ELF supports preemption of other symbols. + return false; +} + TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const { - bool isLocal = GV->hasLocalLinkage(); - bool isDeclaration = GV->isDeclaration(); - bool isPIC = getRelocationModel() == Reloc::PIC_; - bool isPIE = Options.PositionIndependentExecutable; - // FIXME: what should we do for protected and internal visibility? - // For variables, is internal different from hidden? - bool isHidden = GV->hasHiddenVisibility(); + bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default; + Reloc::Model RM = getRelocationModel(); + bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE; + bool IsLocal = shouldAssumeDSOLocal(*GV->getParent(), GV); TLSModel::Model Model; - if (isPIC && !isPIE) { - if (isLocal || isHidden) + if (IsSharedLibrary) { + if (IsLocal) Model = TLSModel::LocalDynamic; else Model = TLSModel::GeneralDynamic; } else { - if (!isDeclaration || isHidden) + if (IsLocal) Model = TLSModel::LocalExec; else Model = TLSModel::InitialExec; @@ -136,18 +177,10 @@ TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const { return Model; } -/// getOptLevel - Returns the optimization level: None, Less, -/// Default, or Aggressive. -CodeGenOpt::Level TargetMachine::getOptLevel() const { - if (!CodeGenInfo) - return CodeGenOpt::Default; - return CodeGenInfo->getOptLevel(); -} +/// Returns the optimization level: None, Less, Default, or Aggressive. +CodeGenOpt::Level TargetMachine::getOptLevel() const { return OptLevel; } -void TargetMachine::setOptLevel(CodeGenOpt::Level Level) const { - if (CodeGenInfo) - CodeGenInfo->setOptLevel(Level); -} +void TargetMachine::setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; } TargetIRAnalysis TargetMachine::getTargetIRAnalysis() { return TargetIRAnalysis([this](const Function &F) { |