1f22ef01cSRoman Divacky //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements the LLVMTargetMachine class.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
1491bc56edSDimitry Andric #include "llvm/Analysis/Passes.h"
15f22ef01cSRoman Divacky #include "llvm/CodeGen/AsmPrinter.h"
16ff0cc061SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h"
17f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfo.h"
18139f7f9bSDimitry Andric #include "llvm/CodeGen/Passes.h"
193ca95b02SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
20ff0cc061SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
212cab237bSDimitry Andric #include "llvm/MC/MCAsmBackend.h"
22dff0c46cSDimitry Andric #include "llvm/MC/MCAsmInfo.h"
232cab237bSDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
24dff0c46cSDimitry Andric #include "llvm/MC/MCContext.h"
25dff0c46cSDimitry Andric #include "llvm/MC/MCInstrInfo.h"
264ba319b5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
27dff0c46cSDimitry Andric #include "llvm/MC/MCStreamer.h"
28dff0c46cSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
29f22ef01cSRoman Divacky #include "llvm/Support/CommandLine.h"
30dff0c46cSDimitry Andric #include "llvm/Support/ErrorHandling.h"
31139f7f9bSDimitry Andric #include "llvm/Support/FormattedStream.h"
326122f3e6SDimitry Andric #include "llvm/Support/TargetRegistry.h"
334ba319b5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
34db17bf38SDimitry Andric #include "llvm/Target/TargetMachine.h"
35139f7f9bSDimitry Andric #include "llvm/Target/TargetOptions.h"
36f22ef01cSRoman Divacky using namespace llvm;
37f22ef01cSRoman Divacky 
384ba319b5SDimitry Andric static cl::opt<bool> EnableTrapUnreachable("trap-unreachable",
394ba319b5SDimitry Andric   cl::Hidden, cl::ZeroOrMore, cl::init(false),
404ba319b5SDimitry Andric   cl::desc("Enable generating trap for unreachable"));
414ba319b5SDimitry Andric 
initAsmInfo()42f785676fSDimitry Andric void LLVMTargetMachine::initAsmInfo() {
43*b5893f02SDimitry Andric   MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str()));
44*b5893f02SDimitry Andric   MII.reset(TheTarget.createMCInstrInfo());
45ff0cc061SDimitry Andric   // FIXME: Having an MCSubtargetInfo on the target machine is a hack due
46ff0cc061SDimitry Andric   // to some backends having subtarget feature dependent module level
47ff0cc061SDimitry Andric   // code generation. This is similar to the hack in the AsmPrinter for
48ff0cc061SDimitry Andric   // module level assembly etc.
49*b5893f02SDimitry Andric   STI.reset(TheTarget.createMCSubtargetInfo(
50*b5893f02SDimitry Andric       getTargetTriple().str(), getTargetCPU(), getTargetFeatureString()));
51ff0cc061SDimitry Andric 
528f0fd8f6SDimitry Andric   MCAsmInfo *TmpAsmInfo =
538f0fd8f6SDimitry Andric       TheTarget.createMCAsmInfo(*MRI, getTargetTriple().str());
546122f3e6SDimitry Andric   // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
556122f3e6SDimitry Andric   // and if the old one gets included then MCAsmInfo will be NULL and
566122f3e6SDimitry Andric   // we'll crash later.
576122f3e6SDimitry Andric   // Provide the user with a useful error message about what's wrong.
5891bc56edSDimitry Andric   assert(TmpAsmInfo && "MCAsmInfo not initialized. "
59f8254f43SDimitry Andric          "Make sure you include the correct TargetSelect.h"
60f8254f43SDimitry Andric          "and that InitializeAllTargetMCs() is being invoked!");
6191bc56edSDimitry Andric 
6291bc56edSDimitry Andric   if (Options.DisableIntegratedAS)
6391bc56edSDimitry Andric     TmpAsmInfo->setUseIntegratedAssembler(false);
6491bc56edSDimitry Andric 
653ca95b02SDimitry Andric   TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments);
663ca95b02SDimitry Andric 
67db17bf38SDimitry Andric   TmpAsmInfo->setCompressDebugSections(Options.CompressDebugSections);
683ca95b02SDimitry Andric 
693ca95b02SDimitry Andric   TmpAsmInfo->setRelaxELFRelocations(Options.RelaxELFRelocations);
703ca95b02SDimitry Andric 
713ca95b02SDimitry Andric   if (Options.ExceptionModel != ExceptionHandling::None)
723ca95b02SDimitry Andric     TmpAsmInfo->setExceptionsType(Options.ExceptionModel);
7391bc56edSDimitry Andric 
74*b5893f02SDimitry Andric   AsmInfo.reset(TmpAsmInfo);
75f22ef01cSRoman Divacky }
76f22ef01cSRoman Divacky 
LLVMTargetMachine(const Target & T,StringRef DataLayoutString,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Reloc::Model RM,CodeModel::Model CM,CodeGenOpt::Level OL)77ff0cc061SDimitry Andric LLVMTargetMachine::LLVMTargetMachine(const Target &T,
78ff0cc061SDimitry Andric                                      StringRef DataLayoutString,
798f0fd8f6SDimitry Andric                                      const Triple &TT, StringRef CPU,
807a7e6055SDimitry Andric                                      StringRef FS, const TargetOptions &Options,
81f785676fSDimitry Andric                                      Reloc::Model RM, CodeModel::Model CM,
82f785676fSDimitry Andric                                      CodeGenOpt::Level OL)
838f0fd8f6SDimitry Andric     : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) {
843ca95b02SDimitry Andric   this->RM = RM;
853ca95b02SDimitry Andric   this->CMModel = CM;
863ca95b02SDimitry Andric   this->OptLevel = OL;
874ba319b5SDimitry Andric 
884ba319b5SDimitry Andric   if (EnableTrapUnreachable)
894ba319b5SDimitry Andric     this->Options.TrapUnreachable = true;
90f785676fSDimitry Andric }
91f785676fSDimitry Andric 
92da09e106SDimitry Andric TargetTransformInfo
getTargetTransformInfo(const Function & F)93da09e106SDimitry Andric LLVMTargetMachine::getTargetTransformInfo(const Function &F) {
94ff0cc061SDimitry Andric   return TargetTransformInfo(BasicTTIImpl(this, F));
95139f7f9bSDimitry Andric }
96139f7f9bSDimitry Andric 
97dff0c46cSDimitry Andric /// addPassesToX helper drives creation and initialization of TargetPassConfig.
98*b5893f02SDimitry Andric static TargetPassConfig *
addPassesToGenerateCode(LLVMTargetMachine & TM,PassManagerBase & PM,bool DisableVerify,MachineModuleInfo & MMI)99*b5893f02SDimitry Andric addPassesToGenerateCode(LLVMTargetMachine &TM, PassManagerBase &PM,
100*b5893f02SDimitry Andric                         bool DisableVerify, MachineModuleInfo &MMI) {
10191bc56edSDimitry Andric   // Targets may override createPassConfig to provide a target-specific
10291bc56edSDimitry Andric   // subclass.
103*b5893f02SDimitry Andric   TargetPassConfig *PassConfig = TM.createPassConfig(PM);
104dff0c46cSDimitry Andric   // Set PassConfig options provided by TargetMachine.
105dff0c46cSDimitry Andric   PassConfig->setDisableVerify(DisableVerify);
106dff0c46cSDimitry Andric   PM.add(PassConfig);
107*b5893f02SDimitry Andric   PM.add(&MMI);
108dff0c46cSDimitry Andric 
109db17bf38SDimitry Andric   if (PassConfig->addISelPasses())
1103ca95b02SDimitry Andric     return nullptr;
111dff0c46cSDimitry Andric   PassConfig->addMachinePasses();
112dff0c46cSDimitry Andric   PassConfig->setInitialized();
113*b5893f02SDimitry Andric   return PassConfig;
114dff0c46cSDimitry Andric }
115dff0c46cSDimitry Andric 
addAsmPrinter(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,MCContext & Context)116db17bf38SDimitry Andric bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
1174ba319b5SDimitry Andric                                       raw_pwrite_stream &Out,
1184ba319b5SDimitry Andric                                       raw_pwrite_stream *DwoOut,
1194ba319b5SDimitry Andric                                       CodeGenFileType FileType,
120db17bf38SDimitry Andric                                       MCContext &Context) {
12191bc56edSDimitry Andric   if (Options.MCOptions.MCSaveTempLabels)
122db17bf38SDimitry Andric     Context.setAllowTemporaryLabels(false);
1233b0f4066SDimitry Andric 
124ff0cc061SDimitry Andric   const MCSubtargetInfo &STI = *getMCSubtargetInfo();
12539d628a0SDimitry Andric   const MCAsmInfo &MAI = *getMCAsmInfo();
126ff0cc061SDimitry Andric   const MCRegisterInfo &MRI = *getMCRegisterInfo();
127ff0cc061SDimitry Andric   const MCInstrInfo &MII = *getMCInstrInfo();
128ff0cc061SDimitry Andric 
12991bc56edSDimitry Andric   std::unique_ptr<MCStreamer> AsmStreamer;
130f22ef01cSRoman Divacky 
131f22ef01cSRoman Divacky   switch (FileType) {
132f22ef01cSRoman Divacky   case CGFT_AssemblyFile: {
133ff0cc061SDimitry Andric     MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
1348f0fd8f6SDimitry Andric         getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI);
135f22ef01cSRoman Divacky 
136f22ef01cSRoman Divacky     // Create a code emitter if asked to show the encoding.
1374ba319b5SDimitry Andric     std::unique_ptr<MCCodeEmitter> MCE;
13891bc56edSDimitry Andric     if (Options.MCOptions.ShowMCEncoding)
1394ba319b5SDimitry Andric       MCE.reset(getTarget().createMCCodeEmitter(MII, MRI, Context));
140f22ef01cSRoman Divacky 
1414ba319b5SDimitry Andric     std::unique_ptr<MCAsmBackend> MAB(
1424ba319b5SDimitry Andric         getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions));
143ff0cc061SDimitry Andric     auto FOut = llvm::make_unique<formatted_raw_ostream>(Out);
14491bc56edSDimitry Andric     MCStreamer *S = getTarget().createAsmStreamer(
145db17bf38SDimitry Andric         Context, std::move(FOut), Options.MCOptions.AsmVerbose,
1464ba319b5SDimitry Andric         Options.MCOptions.MCUseDwarfDirectory, InstPrinter, std::move(MCE),
1474ba319b5SDimitry Andric         std::move(MAB), Options.MCOptions.ShowMCInst);
1482754fe60SDimitry Andric     AsmStreamer.reset(S);
149f22ef01cSRoman Divacky     break;
150f22ef01cSRoman Divacky   }
151f22ef01cSRoman Divacky   case CGFT_ObjectFile: {
152f22ef01cSRoman Divacky     // Create the code emitter for the target if it exists.  If not, .o file
153f22ef01cSRoman Divacky     // emission fails.
154db17bf38SDimitry Andric     MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);
1558f0fd8f6SDimitry Andric     MCAsmBackend *MAB =
15630785c0eSDimitry Andric         getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
15791bc56edSDimitry Andric     if (!MCE || !MAB)
158f22ef01cSRoman Divacky       return true;
159f22ef01cSRoman Divacky 
160ff0cc061SDimitry Andric     // Don't waste memory on names of temp labels.
161db17bf38SDimitry Andric     Context.setUseNamesOnTempLabels(false);
162ff0cc061SDimitry Andric 
1638f0fd8f6SDimitry Andric     Triple T(getTargetTriple().str());
164ff0cc061SDimitry Andric     AsmStreamer.reset(getTarget().createMCObjectStreamer(
1654ba319b5SDimitry Andric         T, Context, std::unique_ptr<MCAsmBackend>(MAB),
1664ba319b5SDimitry Andric         DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut)
1674ba319b5SDimitry Andric                : MAB->createObjectWriter(Out),
1682cab237bSDimitry Andric         std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll,
1697d523365SDimitry Andric         Options.MCOptions.MCIncrementalLinkerCompatible,
170ff0cc061SDimitry Andric         /*DWARFMustBeAtTheEnd*/ true));
171f22ef01cSRoman Divacky     break;
172f22ef01cSRoman Divacky   }
173f22ef01cSRoman Divacky   case CGFT_Null:
174f22ef01cSRoman Divacky     // The Null output is intended for use for performance analysis and testing,
175f22ef01cSRoman Divacky     // not real users.
176db17bf38SDimitry Andric     AsmStreamer.reset(getTarget().createNullStreamer(Context));
177f22ef01cSRoman Divacky     break;
178f22ef01cSRoman Divacky   }
179f22ef01cSRoman Divacky 
180f22ef01cSRoman Divacky   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
181ff0cc061SDimitry Andric   FunctionPass *Printer =
182ff0cc061SDimitry Andric       getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
18391bc56edSDimitry Andric   if (!Printer)
184f22ef01cSRoman Divacky     return true;
185f22ef01cSRoman Divacky 
186f22ef01cSRoman Divacky   PM.add(Printer);
187db17bf38SDimitry Andric   return false;
188db17bf38SDimitry Andric }
189f22ef01cSRoman Divacky 
addPassesToEmitFile(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,bool DisableVerify,MachineModuleInfo * MMI)1902cab237bSDimitry Andric bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
1912cab237bSDimitry Andric                                             raw_pwrite_stream &Out,
1924ba319b5SDimitry Andric                                             raw_pwrite_stream *DwoOut,
1932cab237bSDimitry Andric                                             CodeGenFileType FileType,
1942cab237bSDimitry Andric                                             bool DisableVerify,
1952cab237bSDimitry Andric                                             MachineModuleInfo *MMI) {
196db17bf38SDimitry Andric   // Add common CodeGen passes.
197*b5893f02SDimitry Andric   if (!MMI)
198*b5893f02SDimitry Andric     MMI = new MachineModuleInfo(this);
199*b5893f02SDimitry Andric   TargetPassConfig *PassConfig =
200*b5893f02SDimitry Andric       addPassesToGenerateCode(*this, PM, DisableVerify, *MMI);
201*b5893f02SDimitry Andric   if (!PassConfig)
202db17bf38SDimitry Andric     return true;
203db17bf38SDimitry Andric 
204*b5893f02SDimitry Andric   if (!TargetPassConfig::willCompleteCodeGenPipeline()) {
205*b5893f02SDimitry Andric     PM.add(createPrintMIRPass(Out));
206*b5893f02SDimitry Andric   } else if (addAsmPrinter(PM, Out, DwoOut, FileType, MMI->getContext()))
207db17bf38SDimitry Andric     return true;
208db17bf38SDimitry Andric 
209db17bf38SDimitry Andric   PM.add(createFreeMachineFunctionPass());
210f22ef01cSRoman Divacky   return false;
211f22ef01cSRoman Divacky }
212f22ef01cSRoman Divacky 
213e580952dSDimitry Andric /// addPassesToEmitMC - Add passes to the specified pass manager to get
214e580952dSDimitry Andric /// machine code emitted with the MCJIT. This method returns true if machine
215e580952dSDimitry Andric /// code is not supported. It fills the MCContext Ctx pointer which can be
216e580952dSDimitry Andric /// used to build custom MCStreamer.
217e580952dSDimitry Andric ///
addPassesToEmitMC(PassManagerBase & PM,MCContext * & Ctx,raw_pwrite_stream & Out,bool DisableVerify)218ff0cc061SDimitry Andric bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
219ff0cc061SDimitry Andric                                           raw_pwrite_stream &Out,
220e580952dSDimitry Andric                                           bool DisableVerify) {
221e580952dSDimitry Andric   // Add common CodeGen passes.
222*b5893f02SDimitry Andric   MachineModuleInfo *MMI = new MachineModuleInfo(this);
223*b5893f02SDimitry Andric   TargetPassConfig *PassConfig =
224*b5893f02SDimitry Andric       addPassesToGenerateCode(*this, PM, DisableVerify, *MMI);
225*b5893f02SDimitry Andric   if (!PassConfig)
226e580952dSDimitry Andric     return true;
227*b5893f02SDimitry Andric   assert(TargetPassConfig::willCompleteCodeGenPipeline() &&
228*b5893f02SDimitry Andric          "Cannot emit MC with limited codegen pipeline");
2293b0f4066SDimitry Andric 
230*b5893f02SDimitry Andric   Ctx = &MMI->getContext();
23191bc56edSDimitry Andric   if (Options.MCOptions.MCSaveTempLabels)
2323b0f4066SDimitry Andric     Ctx->setAllowTemporaryLabels(false);
2333b0f4066SDimitry Andric 
2343b0f4066SDimitry Andric   // Create the code emitter for the target if it exists.  If not, .o file
2353b0f4066SDimitry Andric   // emission fails.
23630785c0eSDimitry Andric   const MCSubtargetInfo &STI = *getMCSubtargetInfo();
237ff0cc061SDimitry Andric   const MCRegisterInfo &MRI = *getMCRegisterInfo();
238ff0cc061SDimitry Andric   MCCodeEmitter *MCE =
239ff0cc061SDimitry Andric       getTarget().createMCCodeEmitter(*getMCInstrInfo(), MRI, *Ctx);
2408f0fd8f6SDimitry Andric   MCAsmBackend *MAB =
24130785c0eSDimitry Andric       getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
24291bc56edSDimitry Andric   if (!MCE || !MAB)
2433b0f4066SDimitry Andric     return true;
2443b0f4066SDimitry Andric 
2458f0fd8f6SDimitry Andric   const Triple &T = getTargetTriple();
246ff0cc061SDimitry Andric   std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
2474ba319b5SDimitry Andric       T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out),
2482cab237bSDimitry Andric       std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll,
2497d523365SDimitry Andric       Options.MCOptions.MCIncrementalLinkerCompatible,
250ff0cc061SDimitry Andric       /*DWARFMustBeAtTheEnd*/ true));
2513b0f4066SDimitry Andric 
2523b0f4066SDimitry Andric   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
253ff0cc061SDimitry Andric   FunctionPass *Printer =
254ff0cc061SDimitry Andric       getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
25591bc56edSDimitry Andric   if (!Printer)
2563b0f4066SDimitry Andric     return true;
2573b0f4066SDimitry Andric 
2583b0f4066SDimitry Andric   PM.add(Printer);
259d88c1a5aSDimitry Andric   PM.add(createFreeMachineFunctionPass());
2603b0f4066SDimitry Andric 
261e580952dSDimitry Andric   return false; // success!
262e580952dSDimitry Andric }
263