]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This file implements the LLVMTargetMachine class. | |
11 | // | |
12 | //===----------------------------------------------------------------------===// | |
13 | ||
970d7e83 | 14 | #include "llvm/Target/TargetMachine.h" |
85aaf69f | 15 | #include "llvm/Analysis/JumpInstrTableInfo.h" |
1a4d82fc | 16 | #include "llvm/Analysis/Passes.h" |
223e47cc | 17 | #include "llvm/CodeGen/AsmPrinter.h" |
85aaf69f | 18 | #include "llvm/CodeGen/ForwardControlFlowIntegrity.h" |
1a4d82fc | 19 | #include "llvm/CodeGen/JumpInstrTables.h" |
223e47cc LB |
20 | #include "llvm/CodeGen/MachineFunctionAnalysis.h" |
21 | #include "llvm/CodeGen/MachineModuleInfo.h" | |
970d7e83 | 22 | #include "llvm/CodeGen/Passes.h" |
1a4d82fc JJ |
23 | #include "llvm/IR/IRPrintingPasses.h" |
24 | #include "llvm/IR/Verifier.h" | |
223e47cc LB |
25 | #include "llvm/MC/MCAsmInfo.h" |
26 | #include "llvm/MC/MCContext.h" | |
27 | #include "llvm/MC/MCInstrInfo.h" | |
28 | #include "llvm/MC/MCStreamer.h" | |
29 | #include "llvm/MC/MCSubtargetInfo.h" | |
970d7e83 | 30 | #include "llvm/PassManager.h" |
223e47cc | 31 | #include "llvm/Support/CommandLine.h" |
223e47cc | 32 | #include "llvm/Support/ErrorHandling.h" |
970d7e83 | 33 | #include "llvm/Support/FormattedStream.h" |
223e47cc | 34 | #include "llvm/Support/TargetRegistry.h" |
970d7e83 LB |
35 | #include "llvm/Target/TargetInstrInfo.h" |
36 | #include "llvm/Target/TargetLowering.h" | |
37 | #include "llvm/Target/TargetLoweringObjectFile.h" | |
38 | #include "llvm/Target/TargetOptions.h" | |
39 | #include "llvm/Target/TargetRegisterInfo.h" | |
40 | #include "llvm/Target/TargetSubtargetInfo.h" | |
41 | #include "llvm/Transforms/Scalar.h" | |
223e47cc LB |
42 | using namespace llvm; |
43 | ||
44 | // Enable or disable FastISel. Both options are needed, because | |
45 | // FastISel is enabled by default with -fast, and we wish to be | |
46 | // able to enable or disable fast-isel independently from -O0. | |
47 | static cl::opt<cl::boolOrDefault> | |
48 | EnableFastISelOption("fast-isel", cl::Hidden, | |
49 | cl::desc("Enable the \"fast\" instruction selector")); | |
50 | ||
1a4d82fc JJ |
51 | void LLVMTargetMachine::initAsmInfo() { |
52 | MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo( | |
53 | *getSubtargetImpl()->getRegisterInfo(), getTargetTriple()); | |
54 | // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0, | |
55 | // and if the old one gets included then MCAsmInfo will be NULL and | |
56 | // we'll crash later. | |
57 | // Provide the user with a useful error message about what's wrong. | |
58 | assert(TmpAsmInfo && "MCAsmInfo not initialized. " | |
59 | "Make sure you include the correct TargetSelect.h" | |
60 | "and that InitializeAllTargetMCs() is being invoked!"); | |
223e47cc | 61 | |
1a4d82fc JJ |
62 | if (Options.DisableIntegratedAS) |
63 | TmpAsmInfo->setUseIntegratedAssembler(false); | |
64 | ||
65 | if (Options.CompressDebugSections) | |
66 | TmpAsmInfo->setCompressDebugSections(true); | |
67 | ||
68 | AsmInfo = TmpAsmInfo; | |
223e47cc LB |
69 | } |
70 | ||
71 | LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple, | |
72 | StringRef CPU, StringRef FS, | |
73 | TargetOptions Options, | |
74 | Reloc::Model RM, CodeModel::Model CM, | |
75 | CodeGenOpt::Level OL) | |
76 | : TargetMachine(T, Triple, CPU, FS, Options) { | |
77 | CodeGenInfo = T.createMCCodeGenInfo(Triple, RM, CM, OL); | |
223e47cc LB |
78 | } |
79 | ||
970d7e83 | 80 | void LLVMTargetMachine::addAnalysisPasses(PassManagerBase &PM) { |
1a4d82fc | 81 | PM.add(createBasicTargetTransformInfoPass(this)); |
970d7e83 LB |
82 | } |
83 | ||
223e47cc LB |
84 | /// addPassesToX helper drives creation and initialization of TargetPassConfig. |
85 | static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM, | |
86 | PassManagerBase &PM, | |
87 | bool DisableVerify, | |
88 | AnalysisID StartAfter, | |
89 | AnalysisID StopAfter) { | |
1a4d82fc JJ |
90 | |
91 | // Add internal analysis passes from the target machine. | |
92 | TM->addAnalysisPasses(PM); | |
93 | ||
94 | // Targets may override createPassConfig to provide a target-specific | |
95 | // subclass. | |
223e47cc LB |
96 | TargetPassConfig *PassConfig = TM->createPassConfig(PM); |
97 | PassConfig->setStartStopPasses(StartAfter, StopAfter); | |
98 | ||
99 | // Set PassConfig options provided by TargetMachine. | |
100 | PassConfig->setDisableVerify(DisableVerify); | |
101 | ||
102 | PM.add(PassConfig); | |
103 | ||
104 | PassConfig->addIRPasses(); | |
105 | ||
970d7e83 LB |
106 | PassConfig->addCodeGenPrepare(); |
107 | ||
223e47cc LB |
108 | PassConfig->addPassesToHandleExceptions(); |
109 | ||
110 | PassConfig->addISelPrepare(); | |
111 | ||
112 | // Install a MachineModuleInfo class, which is an immutable pass that holds | |
113 | // all the per-module stuff we're generating, including MCContext. | |
1a4d82fc JJ |
114 | MachineModuleInfo *MMI = new MachineModuleInfo( |
115 | *TM->getMCAsmInfo(), *TM->getSubtargetImpl()->getRegisterInfo(), | |
116 | &TM->getSubtargetImpl()->getTargetLowering()->getObjFileLowering()); | |
223e47cc | 117 | PM.add(MMI); |
223e47cc LB |
118 | |
119 | // Set up a MachineFunction for the rest of CodeGen to work on. | |
120 | PM.add(new MachineFunctionAnalysis(*TM)); | |
121 | ||
122 | // Enable FastISel with -fast, but allow that to be overridden. | |
123 | if (EnableFastISelOption == cl::BOU_TRUE || | |
124 | (TM->getOptLevel() == CodeGenOpt::None && | |
125 | EnableFastISelOption != cl::BOU_FALSE)) | |
126 | TM->setFastISel(true); | |
127 | ||
128 | // Ask the target for an isel. | |
129 | if (PassConfig->addInstSelector()) | |
1a4d82fc | 130 | return nullptr; |
223e47cc LB |
131 | |
132 | PassConfig->addMachinePasses(); | |
133 | ||
134 | PassConfig->setInitialized(); | |
135 | ||
1a4d82fc | 136 | return &MMI->getContext(); |
223e47cc LB |
137 | } |
138 | ||
139 | bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, | |
140 | formatted_raw_ostream &Out, | |
141 | CodeGenFileType FileType, | |
142 | bool DisableVerify, | |
143 | AnalysisID StartAfter, | |
144 | AnalysisID StopAfter) { | |
1a4d82fc JJ |
145 | // Passes to handle jumptable function annotations. These can't be handled at |
146 | // JIT time, so we don't add them directly to addPassesToGenerateCode. | |
85aaf69f SL |
147 | PM.add(createJumpInstrTableInfoPass( |
148 | getSubtargetImpl()->getInstrInfo()->getJumpInstrTableEntryBound())); | |
1a4d82fc | 149 | PM.add(createJumpInstrTablesPass(Options.JTType)); |
85aaf69f SL |
150 | if (Options.FCFI) |
151 | PM.add(createForwardControlFlowIntegrityPass( | |
152 | Options.JTType, Options.CFIType, Options.CFIEnforcing, | |
153 | Options.getCFIFuncName())); | |
1a4d82fc | 154 | |
223e47cc LB |
155 | // Add common CodeGen passes. |
156 | MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, | |
157 | StartAfter, StopAfter); | |
158 | if (!Context) | |
159 | return true; | |
160 | ||
161 | if (StopAfter) { | |
162 | // FIXME: The intent is that this should eventually write out a YAML file, | |
163 | // containing the LLVM IR, the machine-level IR (when stopping after a | |
164 | // machine-level pass), and whatever other information is needed to | |
165 | // deserialize the code and resume compilation. For now, just write the | |
166 | // LLVM IR. | |
1a4d82fc | 167 | PM.add(createPrintModulePass(Out)); |
223e47cc LB |
168 | return false; |
169 | } | |
170 | ||
1a4d82fc | 171 | if (Options.MCOptions.MCSaveTempLabels) |
223e47cc LB |
172 | Context->setAllowTemporaryLabels(false); |
173 | ||
223e47cc | 174 | const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); |
1a4d82fc JJ |
175 | const MCAsmInfo &MAI = *getMCAsmInfo(); |
176 | const MCRegisterInfo &MRI = *getSubtargetImpl()->getRegisterInfo(); | |
177 | const MCInstrInfo &MII = *getSubtargetImpl()->getInstrInfo(); | |
178 | std::unique_ptr<MCStreamer> AsmStreamer; | |
223e47cc LB |
179 | |
180 | switch (FileType) { | |
181 | case CGFT_AssemblyFile: { | |
182 | MCInstPrinter *InstPrinter = | |
183 | getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, | |
1a4d82fc | 184 | MII, MRI, STI); |
223e47cc LB |
185 | |
186 | // Create a code emitter if asked to show the encoding. | |
1a4d82fc JJ |
187 | MCCodeEmitter *MCE = nullptr; |
188 | if (Options.MCOptions.ShowMCEncoding) | |
189 | MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, *Context); | |
190 | ||
191 | MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), | |
192 | TargetCPU); | |
193 | MCStreamer *S = getTarget().createAsmStreamer( | |
194 | *Context, Out, Options.MCOptions.AsmVerbose, | |
195 | Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB, | |
196 | Options.MCOptions.ShowMCInst); | |
223e47cc LB |
197 | AsmStreamer.reset(S); |
198 | break; | |
199 | } | |
200 | case CGFT_ObjectFile: { | |
201 | // Create the code emitter for the target if it exists. If not, .o file | |
202 | // emission fails. | |
1a4d82fc JJ |
203 | MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, |
204 | *Context); | |
205 | MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), | |
970d7e83 | 206 | TargetCPU); |
1a4d82fc | 207 | if (!MCE || !MAB) |
223e47cc LB |
208 | return true; |
209 | ||
85aaf69f SL |
210 | AsmStreamer.reset( |
211 | getTarget() | |
212 | .createMCObjectStreamer(getTargetTriple(), *Context, *MAB, Out, MCE, | |
213 | STI, Options.MCOptions.MCRelaxAll)); | |
223e47cc LB |
214 | break; |
215 | } | |
216 | case CGFT_Null: | |
217 | // The Null output is intended for use for performance analysis and testing, | |
218 | // not real users. | |
1a4d82fc | 219 | AsmStreamer.reset(getTarget().createNullStreamer(*Context)); |
223e47cc LB |
220 | break; |
221 | } | |
222 | ||
223 | // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. | |
224 | FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); | |
1a4d82fc | 225 | if (!Printer) |
223e47cc LB |
226 | return true; |
227 | ||
228 | // If successful, createAsmPrinter took ownership of AsmStreamer. | |
1a4d82fc | 229 | AsmStreamer.release(); |
223e47cc LB |
230 | |
231 | PM.add(Printer); | |
232 | ||
223e47cc LB |
233 | return false; |
234 | } | |
235 | ||
223e47cc LB |
236 | /// addPassesToEmitMC - Add passes to the specified pass manager to get |
237 | /// machine code emitted with the MCJIT. This method returns true if machine | |
238 | /// code is not supported. It fills the MCContext Ctx pointer which can be | |
239 | /// used to build custom MCStreamer. | |
240 | /// | |
241 | bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, | |
242 | MCContext *&Ctx, | |
243 | raw_ostream &Out, | |
244 | bool DisableVerify) { | |
245 | // Add common CodeGen passes. | |
1a4d82fc | 246 | Ctx = addPassesToGenerateCode(this, PM, DisableVerify, nullptr, nullptr); |
223e47cc LB |
247 | if (!Ctx) |
248 | return true; | |
249 | ||
1a4d82fc | 250 | if (Options.MCOptions.MCSaveTempLabels) |
223e47cc LB |
251 | Ctx->setAllowTemporaryLabels(false); |
252 | ||
253 | // Create the code emitter for the target if it exists. If not, .o file | |
254 | // emission fails. | |
1a4d82fc | 255 | const MCRegisterInfo &MRI = *getSubtargetImpl()->getRegisterInfo(); |
223e47cc | 256 | const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); |
1a4d82fc JJ |
257 | MCCodeEmitter *MCE = getTarget().createMCCodeEmitter( |
258 | *getSubtargetImpl()->getInstrInfo(), MRI, STI, *Ctx); | |
259 | MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), | |
260 | TargetCPU); | |
261 | if (!MCE || !MAB) | |
223e47cc LB |
262 | return true; |
263 | ||
1a4d82fc | 264 | std::unique_ptr<MCStreamer> AsmStreamer; |
85aaf69f SL |
265 | AsmStreamer.reset(getTarget() |
266 | .createMCObjectStreamer(getTargetTriple(), *Ctx, *MAB, | |
267 | Out, MCE, STI, | |
268 | Options.MCOptions.MCRelaxAll)); | |
223e47cc LB |
269 | |
270 | // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. | |
271 | FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); | |
1a4d82fc | 272 | if (!Printer) |
223e47cc LB |
273 | return true; |
274 | ||
275 | // If successful, createAsmPrinter took ownership of AsmStreamer. | |
1a4d82fc | 276 | AsmStreamer.release(); |
223e47cc LB |
277 | |
278 | PM.add(Printer); | |
279 | ||
280 | return false; // success! | |
281 | } |