xref: /aosp_15_r20/external/llvm/lib/Target/TargetMachine.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- TargetMachine.cpp - General Target Information ---------------------==//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file describes the general parts of a Target machine.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/TargetTransformInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalAlias.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalValue.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LegacyPassManager.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionMachO.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCTargetOptions.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/SectionKind.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLowering.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLoweringObjectFile.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
32*9880d681SAndroid Build Coastguard Worker using namespace llvm;
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker cl::opt<bool> EnableIPRA("enable-ipra", cl::init(false), cl::Hidden,
35*9880d681SAndroid Build Coastguard Worker                          cl::desc("Enable interprocedural register allocation "
36*9880d681SAndroid Build Coastguard Worker                                   "to reduce load/store at procedure calls."));
37*9880d681SAndroid Build Coastguard Worker 
38*9880d681SAndroid Build Coastguard Worker //---------------------------------------------------------------------------
39*9880d681SAndroid Build Coastguard Worker // TargetMachine Class
40*9880d681SAndroid Build Coastguard Worker //
41*9880d681SAndroid Build Coastguard Worker 
TargetMachine(const Target & T,StringRef DataLayoutString,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options)42*9880d681SAndroid Build Coastguard Worker TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
43*9880d681SAndroid Build Coastguard Worker                              const Triple &TT, StringRef CPU, StringRef FS,
44*9880d681SAndroid Build Coastguard Worker                              const TargetOptions &Options)
45*9880d681SAndroid Build Coastguard Worker     : TheTarget(T), DL(DataLayoutString), TargetTriple(TT), TargetCPU(CPU),
46*9880d681SAndroid Build Coastguard Worker       TargetFS(FS), AsmInfo(nullptr), MRI(nullptr), MII(nullptr), STI(nullptr),
47*9880d681SAndroid Build Coastguard Worker       RequireStructuredCFG(false), Options(Options) {
48*9880d681SAndroid Build Coastguard Worker   if (EnableIPRA.getNumOccurrences())
49*9880d681SAndroid Build Coastguard Worker     this->Options.EnableIPRA = EnableIPRA;
50*9880d681SAndroid Build Coastguard Worker }
51*9880d681SAndroid Build Coastguard Worker 
~TargetMachine()52*9880d681SAndroid Build Coastguard Worker TargetMachine::~TargetMachine() {
53*9880d681SAndroid Build Coastguard Worker   delete AsmInfo;
54*9880d681SAndroid Build Coastguard Worker   delete MRI;
55*9880d681SAndroid Build Coastguard Worker   delete MII;
56*9880d681SAndroid Build Coastguard Worker   delete STI;
57*9880d681SAndroid Build Coastguard Worker }
58*9880d681SAndroid Build Coastguard Worker 
isPositionIndependent() const59*9880d681SAndroid Build Coastguard Worker bool TargetMachine::isPositionIndependent() const {
60*9880d681SAndroid Build Coastguard Worker   return getRelocationModel() == Reloc::PIC_;
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker /// \brief Reset the target options based on the function's attributes.
64*9880d681SAndroid Build Coastguard Worker // FIXME: This function needs to go away for a number of reasons:
65*9880d681SAndroid Build Coastguard Worker // a) global state on the TargetMachine is terrible in general,
66*9880d681SAndroid Build Coastguard Worker // b) there's no default state here to keep,
67*9880d681SAndroid Build Coastguard Worker // c) these target options should be passed only on the function
68*9880d681SAndroid Build Coastguard Worker //    and not on the TargetMachine (via TargetOptions) at all.
resetTargetOptions(const Function & F) const69*9880d681SAndroid Build Coastguard Worker void TargetMachine::resetTargetOptions(const Function &F) const {
70*9880d681SAndroid Build Coastguard Worker #define RESET_OPTION(X, Y)                                                     \
71*9880d681SAndroid Build Coastguard Worker   do {                                                                         \
72*9880d681SAndroid Build Coastguard Worker     if (F.hasFnAttribute(Y))                                                   \
73*9880d681SAndroid Build Coastguard Worker       Options.X = (F.getFnAttribute(Y).getValueAsString() == "true");          \
74*9880d681SAndroid Build Coastguard Worker   } while (0)
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker   RESET_OPTION(LessPreciseFPMADOption, "less-precise-fpmad");
77*9880d681SAndroid Build Coastguard Worker   RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
78*9880d681SAndroid Build Coastguard Worker   RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
79*9880d681SAndroid Build Coastguard Worker   RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker /// Returns the code generation relocation model. The choices are static, PIC,
83*9880d681SAndroid Build Coastguard Worker /// and dynamic-no-pic.
getRelocationModel() const84*9880d681SAndroid Build Coastguard Worker Reloc::Model TargetMachine::getRelocationModel() const { return RM; }
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker /// Returns the code model. The choices are small, kernel, medium, large, and
87*9880d681SAndroid Build Coastguard Worker /// target default.
getCodeModel() const88*9880d681SAndroid Build Coastguard Worker CodeModel::Model TargetMachine::getCodeModel() const { return CMModel; }
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker /// Get the IR-specified TLS model for Var.
getSelectedTLSModel(const GlobalValue * GV)91*9880d681SAndroid Build Coastguard Worker static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
92*9880d681SAndroid Build Coastguard Worker   switch (GV->getThreadLocalMode()) {
93*9880d681SAndroid Build Coastguard Worker   case GlobalVariable::NotThreadLocal:
94*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("getSelectedTLSModel for non-TLS variable");
95*9880d681SAndroid Build Coastguard Worker     break;
96*9880d681SAndroid Build Coastguard Worker   case GlobalVariable::GeneralDynamicTLSModel:
97*9880d681SAndroid Build Coastguard Worker     return TLSModel::GeneralDynamic;
98*9880d681SAndroid Build Coastguard Worker   case GlobalVariable::LocalDynamicTLSModel:
99*9880d681SAndroid Build Coastguard Worker     return TLSModel::LocalDynamic;
100*9880d681SAndroid Build Coastguard Worker   case GlobalVariable::InitialExecTLSModel:
101*9880d681SAndroid Build Coastguard Worker     return TLSModel::InitialExec;
102*9880d681SAndroid Build Coastguard Worker   case GlobalVariable::LocalExecTLSModel:
103*9880d681SAndroid Build Coastguard Worker     return TLSModel::LocalExec;
104*9880d681SAndroid Build Coastguard Worker   }
105*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("invalid TLS model");
106*9880d681SAndroid Build Coastguard Worker }
107*9880d681SAndroid Build Coastguard Worker 
108*9880d681SAndroid Build Coastguard Worker // FIXME: make this a proper option
109*9880d681SAndroid Build Coastguard Worker static bool CanUseCopyRelocWithPIE = false;
110*9880d681SAndroid Build Coastguard Worker 
shouldAssumeDSOLocal(const Module & M,const GlobalValue * GV) const111*9880d681SAndroid Build Coastguard Worker bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
112*9880d681SAndroid Build Coastguard Worker                                          const GlobalValue *GV) const {
113*9880d681SAndroid Build Coastguard Worker   Reloc::Model RM = getRelocationModel();
114*9880d681SAndroid Build Coastguard Worker   const Triple &TT = getTargetTriple();
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker   // DLLImport explicitly marks the GV as external.
117*9880d681SAndroid Build Coastguard Worker   if (GV && GV->hasDLLImportStorageClass())
118*9880d681SAndroid Build Coastguard Worker     return false;
119*9880d681SAndroid Build Coastguard Worker 
120*9880d681SAndroid Build Coastguard Worker   // Every other GV is local on COFF
121*9880d681SAndroid Build Coastguard Worker   if (TT.isOSBinFormatCOFF())
122*9880d681SAndroid Build Coastguard Worker     return true;
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker   if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility()))
125*9880d681SAndroid Build Coastguard Worker     return true;
126*9880d681SAndroid Build Coastguard Worker 
127*9880d681SAndroid Build Coastguard Worker   if (TT.isOSBinFormatMachO()) {
128*9880d681SAndroid Build Coastguard Worker     if (RM == Reloc::Static)
129*9880d681SAndroid Build Coastguard Worker       return true;
130*9880d681SAndroid Build Coastguard Worker     return GV && GV->isStrongDefinitionForLinker();
131*9880d681SAndroid Build Coastguard Worker   }
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker   assert(TT.isOSBinFormatELF());
134*9880d681SAndroid Build Coastguard Worker   assert(RM != Reloc::DynamicNoPIC);
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker   bool IsExecutable =
137*9880d681SAndroid Build Coastguard Worker       RM == Reloc::Static || M.getPIELevel() != PIELevel::Default;
138*9880d681SAndroid Build Coastguard Worker   if (IsExecutable) {
139*9880d681SAndroid Build Coastguard Worker     // If the symbol is defined, it cannot be preempted.
140*9880d681SAndroid Build Coastguard Worker     if (GV && !GV->isDeclarationForLinker())
141*9880d681SAndroid Build Coastguard Worker       return true;
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker     bool IsTLS = GV && GV->isThreadLocal();
144*9880d681SAndroid Build Coastguard Worker     // Check if we can use copy relocations.
145*9880d681SAndroid Build Coastguard Worker     if (!IsTLS && (RM == Reloc::Static || CanUseCopyRelocWithPIE))
146*9880d681SAndroid Build Coastguard Worker       return true;
147*9880d681SAndroid Build Coastguard Worker   }
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   // ELF supports preemption of other symbols.
150*9880d681SAndroid Build Coastguard Worker   return false;
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker 
getTLSModel(const GlobalValue * GV) const153*9880d681SAndroid Build Coastguard Worker TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
154*9880d681SAndroid Build Coastguard Worker   bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
155*9880d681SAndroid Build Coastguard Worker   Reloc::Model RM = getRelocationModel();
156*9880d681SAndroid Build Coastguard Worker   bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;
157*9880d681SAndroid Build Coastguard Worker   bool IsLocal = shouldAssumeDSOLocal(*GV->getParent(), GV);
158*9880d681SAndroid Build Coastguard Worker 
159*9880d681SAndroid Build Coastguard Worker   TLSModel::Model Model;
160*9880d681SAndroid Build Coastguard Worker   if (IsSharedLibrary) {
161*9880d681SAndroid Build Coastguard Worker     if (IsLocal)
162*9880d681SAndroid Build Coastguard Worker       Model = TLSModel::LocalDynamic;
163*9880d681SAndroid Build Coastguard Worker     else
164*9880d681SAndroid Build Coastguard Worker       Model = TLSModel::GeneralDynamic;
165*9880d681SAndroid Build Coastguard Worker   } else {
166*9880d681SAndroid Build Coastguard Worker     if (IsLocal)
167*9880d681SAndroid Build Coastguard Worker       Model = TLSModel::LocalExec;
168*9880d681SAndroid Build Coastguard Worker     else
169*9880d681SAndroid Build Coastguard Worker       Model = TLSModel::InitialExec;
170*9880d681SAndroid Build Coastguard Worker   }
171*9880d681SAndroid Build Coastguard Worker 
172*9880d681SAndroid Build Coastguard Worker   // If the user specified a more specific model, use that.
173*9880d681SAndroid Build Coastguard Worker   TLSModel::Model SelectedModel = getSelectedTLSModel(GV);
174*9880d681SAndroid Build Coastguard Worker   if (SelectedModel > Model)
175*9880d681SAndroid Build Coastguard Worker     return SelectedModel;
176*9880d681SAndroid Build Coastguard Worker 
177*9880d681SAndroid Build Coastguard Worker   return Model;
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker 
180*9880d681SAndroid Build Coastguard Worker /// Returns the optimization level: None, Less, Default, or Aggressive.
getOptLevel() const181*9880d681SAndroid Build Coastguard Worker CodeGenOpt::Level TargetMachine::getOptLevel() const { return OptLevel; }
182*9880d681SAndroid Build Coastguard Worker 
setOptLevel(CodeGenOpt::Level Level)183*9880d681SAndroid Build Coastguard Worker void TargetMachine::setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
184*9880d681SAndroid Build Coastguard Worker 
getTargetIRAnalysis()185*9880d681SAndroid Build Coastguard Worker TargetIRAnalysis TargetMachine::getTargetIRAnalysis() {
186*9880d681SAndroid Build Coastguard Worker   return TargetIRAnalysis([this](const Function &F) {
187*9880d681SAndroid Build Coastguard Worker     return TargetTransformInfo(F.getParent()->getDataLayout());
188*9880d681SAndroid Build Coastguard Worker   });
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker 
getNameWithPrefix(SmallVectorImpl<char> & Name,const GlobalValue * GV,Mangler & Mang,bool MayAlwaysUsePrivate) const191*9880d681SAndroid Build Coastguard Worker void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
192*9880d681SAndroid Build Coastguard Worker                                       const GlobalValue *GV, Mangler &Mang,
193*9880d681SAndroid Build Coastguard Worker                                       bool MayAlwaysUsePrivate) const {
194*9880d681SAndroid Build Coastguard Worker   if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
195*9880d681SAndroid Build Coastguard Worker     // Simple case: If GV is not private, it is not important to find out if
196*9880d681SAndroid Build Coastguard Worker     // private labels are legal in this case or not.
197*9880d681SAndroid Build Coastguard Worker     Mang.getNameWithPrefix(Name, GV, false);
198*9880d681SAndroid Build Coastguard Worker     return;
199*9880d681SAndroid Build Coastguard Worker   }
200*9880d681SAndroid Build Coastguard Worker   const TargetLoweringObjectFile *TLOF = getObjFileLowering();
201*9880d681SAndroid Build Coastguard Worker   TLOF->getNameWithPrefix(Name, GV, Mang, *this);
202*9880d681SAndroid Build Coastguard Worker }
203*9880d681SAndroid Build Coastguard Worker 
getSymbol(const GlobalValue * GV,Mangler & Mang) const204*9880d681SAndroid Build Coastguard Worker MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV, Mangler &Mang) const {
205*9880d681SAndroid Build Coastguard Worker   SmallString<128> NameStr;
206*9880d681SAndroid Build Coastguard Worker   getNameWithPrefix(NameStr, GV, Mang);
207*9880d681SAndroid Build Coastguard Worker   const TargetLoweringObjectFile *TLOF = getObjFileLowering();
208*9880d681SAndroid Build Coastguard Worker   return TLOF->getContext().getOrCreateSymbol(NameStr);
209*9880d681SAndroid Build Coastguard Worker }
210