LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LLVMTargetMachine.cpp
Go to the documentation of this file.
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 
15 #include "llvm/ADT/OwningPtr.h"
20 #include "llvm/CodeGen/Passes.h"
21 #include "llvm/MC/MCAsmInfo.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/PassManager.h"
37 #include "llvm/Transforms/Scalar.h"
38 using namespace llvm;
39 
40 // Enable or disable FastISel. Both options are needed, because
41 // FastISel is enabled by default with -fast, and we wish to be
42 // able to enable or disable fast-isel independently from -O0.
44 EnableFastISelOption("fast-isel", cl::Hidden,
45  cl::desc("Enable the \"fast\" instruction selector"));
46 
47 static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden,
48  cl::desc("Show encoding in .s output"));
49 static cl::opt<bool> ShowMCInst("show-mc-inst", cl::Hidden,
50  cl::desc("Show instruction structure in .s output"));
51 
53 AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
55 
56 static bool getVerboseAsm() {
57  switch (AsmVerbose) {
59  case cl::BOU_TRUE: return true;
60  case cl::BOU_FALSE: return false;
61  }
62  llvm_unreachable("Invalid verbose asm state");
63 }
64 
67  // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
68  // and if the old one gets included then MCAsmInfo will be NULL and
69  // we'll crash later.
70  // Provide the user with a useful error message about what's wrong.
71  assert(AsmInfo && "MCAsmInfo not initialized. "
72  "Make sure you include the correct TargetSelect.h"
73  "and that InitializeAllTargetMCs() is being invoked!");
74 }
75 
77  StringRef CPU, StringRef FS,
78  TargetOptions Options,
81  : TargetMachine(T, Triple, CPU, FS, Options) {
82  CodeGenInfo = T.createMCCodeGenInfo(Triple, RM, CM, OL);
83 }
84 
85 void LLVMTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
87 }
88 
89 /// addPassesToX helper drives creation and initialization of TargetPassConfig.
91  PassManagerBase &PM,
92  bool DisableVerify,
95  // Targets may override createPassConfig to provide a target-specific sublass.
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 
106  PassConfig->addCodeGenPrepare();
107 
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.
114  MachineModuleInfo *MMI =
117  PM.add(MMI);
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.
124  (TM->getOptLevel() == CodeGenOpt::None &&
126  TM->setFastISel(true);
127 
128  // Ask the target for an isel.
129  if (PassConfig->addInstSelector())
130  return NULL;
131 
132  PassConfig->addMachinePasses();
133 
134  PassConfig->setInitialized();
135 
136  return &MMI->getContext();
137 }
138 
139 bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
142  bool DisableVerify,
145  // Add common CodeGen passes.
146  MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
147  StartAfter, StopAfter);
148  if (!Context)
149  return true;
150 
151  if (StopAfter) {
152  // FIXME: The intent is that this should eventually write out a YAML file,
153  // containing the LLVM IR, the machine-level IR (when stopping after a
154  // machine-level pass), and whatever other information is needed to
155  // deserialize the code and resume compilation. For now, just write the
156  // LLVM IR.
157  PM.add(createPrintModulePass(&Out));
158  return false;
159  }
160 
161  if (hasMCSaveTempLabels())
162  Context->setAllowTemporaryLabels(false);
163 
164  const MCAsmInfo &MAI = *getMCAsmInfo();
165  const MCRegisterInfo &MRI = *getRegisterInfo();
166  const MCInstrInfo &MII = *getInstrInfo();
167  const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
168  OwningPtr<MCStreamer> AsmStreamer;
169 
170  switch (FileType) {
171  case CGFT_AssemblyFile: {
172  MCInstPrinter *InstPrinter =
174  MII, MRI, STI);
175 
176  // Create a code emitter if asked to show the encoding.
177  MCCodeEmitter *MCE = 0;
178  if (ShowMCEncoding)
179  MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, *Context);
180 
182  TargetCPU);
183  MCStreamer *S = getTarget().createAsmStreamer(*Context, Out,
184  getVerboseAsm(),
185  hasMCUseLoc(),
186  hasMCUseCFI(),
188  InstPrinter,
189  MCE, MAB,
190  ShowMCInst);
191  AsmStreamer.reset(S);
192  break;
193  }
194  case CGFT_ObjectFile: {
195  // Create the code emitter for the target if it exists. If not, .o file
196  // emission fails.
197  MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, STI,
198  *Context);
200  TargetCPU);
201  if (MCE == 0 || MAB == 0)
202  return true;
203 
204  AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(),
205  *Context, *MAB, Out,
206  MCE, hasMCRelaxAll(),
207  hasMCNoExecStack()));
208  AsmStreamer.get()->setAutoInitSections(true);
209  break;
210  }
211  case CGFT_Null:
212  // The Null output is intended for use for performance analysis and testing,
213  // not real users.
214  AsmStreamer.reset(createNullStreamer(*Context));
215  break;
216  }
217 
218  // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
219  FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
220  if (Printer == 0)
221  return true;
222 
223  // If successful, createAsmPrinter took ownership of AsmStreamer.
224  AsmStreamer.take();
225 
226  PM.add(Printer);
227 
228  return false;
229 }
230 
231 /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
232 /// get machine code emitted. This uses a JITCodeEmitter object to handle
233 /// actually outputting the machine code and resolving things like the address
234 /// of functions. This method should return true if machine code emission is
235 /// not supported.
236 ///
238  JITCodeEmitter &JCE,
239  bool DisableVerify) {
240  // Add common CodeGen passes.
241  MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, 0, 0);
242  if (!Context)
243  return true;
244 
245  addCodeEmitter(PM, JCE);
246 
247  return false; // success!
248 }
249 
250 /// addPassesToEmitMC - Add passes to the specified pass manager to get
251 /// machine code emitted with the MCJIT. This method returns true if machine
252 /// code is not supported. It fills the MCContext Ctx pointer which can be
253 /// used to build custom MCStreamer.
254 ///
255 bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
256  MCContext *&Ctx,
257  raw_ostream &Out,
258  bool DisableVerify) {
259  // Add common CodeGen passes.
260  Ctx = addPassesToGenerateCode(this, PM, DisableVerify, 0, 0);
261  if (!Ctx)
262  return true;
263 
264  if (hasMCSaveTempLabels())
265  Ctx->setAllowTemporaryLabels(false);
266 
267  // Create the code emitter for the target if it exists. If not, .o file
268  // emission fails.
269  const MCRegisterInfo &MRI = *getRegisterInfo();
270  const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
272  STI, *Ctx);
274  TargetCPU);
275  if (MCE == 0 || MAB == 0)
276  return true;
277 
278  OwningPtr<MCStreamer> AsmStreamer;
279  AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Ctx,
280  *MAB, Out, MCE,
281  hasMCRelaxAll(),
282  hasMCNoExecStack()));
283  AsmStreamer.get()->InitSections();
284 
285  // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
286  FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
287  if (Printer == 0)
288  return true;
289 
290  // If successful, createAsmPrinter took ownership of AsmStreamer.
291  AsmStreamer.take();
292 
293  PM.add(Printer);
294 
295  return false; // success!
296 }
unsigned getAssemblerDialect() const
Definition: MCAsmInfo.h:455
virtual const TargetLowering * getTargetLowering() const
virtual void addIRPasses()
Definition: Passes.cpp:362
virtual void InitSections()=0
InitSections - Create the default sections and set the initial one.
void setDisableVerify(bool Disable)
ImmutablePass * createBasicTargetTransformInfoPass(const TargetMachine *TM)
Create a basic TargetTransformInfo analysis pass.
virtual bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, bool DisableVerify=true, AnalysisID StartAfter=0, AnalysisID StopAfter=0)
virtual void reset()
Definition: MCStreamer.cpp:43
MCStreamer * createNullStreamer(MCContext &Ctx)
ModulePass * createPrintModulePass(raw_ostream *OS, bool DeleteStream=false, const std::string &Banner="")
MCCodeEmitter * createMCCodeEmitter(const MCInstrInfo &II, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx) const
createMCCodeEmitter - Create a target specific code emitter.
print alias Alias Set Printer
static cl::opt< bool > ShowMCInst("show-mc-inst", cl::Hidden, cl::desc("Show instruction structure in .s output"))
virtual TargetPassConfig * createPassConfig(PassManagerBase &PM)
Definition: Passes.cpp:257
MCAsmInfo * createMCAsmInfo(const MCRegisterInfo &MRI, StringRef Triple) const
MCCodeGenInfo * createMCCodeGenInfo(StringRef Triple, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL) const
const MCAsmInfo * getMCAsmInfo() const
#define llvm_unreachable(msg)
static cl::opt< cl::boolOrDefault > AsmVerbose("asm-verbose", cl::desc("Add comments to directives."), cl::init(cl::BOU_UNSET))
static cl::opt< bool > ShowMCEncoding("show-mc-encoding", cl::Hidden, cl::desc("Show encoding in .s output"))
const MCAsmInfo * AsmInfo
virtual void addMachinePasses()
Definition: Passes.cpp:458
MCInstPrinter * createMCInstPrinter(unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI) const
bool hasMCSaveTempLabels() const
void setStartStopPasses(AnalysisID Start, AnalysisID Stop)
CodeGenOpt::Level getOptLevel() const
const TargetLoweringObjectFile & getObjFileLowering() const
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:314
void setAllowTemporaryLabels(bool Value)
Definition: MCContext.h:181
MCAsmBackend * createMCAsmBackend(const MCRegisterInfo &MRI, StringRef Triple, StringRef CPU) const
void reset(T *P=0)
Definition: OwningPtr.h:51
virtual bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, raw_ostream &OS, bool DisableVerify=true)
const MCInstrInfo & MII
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:22
static bool getAsmVerbosityDefault()
static MCContext * addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM, bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter)
addPassesToX helper drives creation and initialization of TargetPassConfig.
virtual bool addInstSelector()
virtual bool addPassesToEmitMachineCode(PassManagerBase &PM, JITCodeEmitter &MCE, bool DisableVerify=true)
virtual void addISelPrepare()
Definition: Passes.cpp:424
virtual void addCodeGenPrepare()
Definition: Passes.cpp:417
const Target & TheTarget
TheTarget - The Target that this machine was created for.
virtual bool addCodeEmitter(PassManagerBase &, JITCodeEmitter &)
void addPassesToHandleExceptions()
Add passes to lower exception handling for the code generator.
Definition: Passes.cpp:390
T * get() const
Definition: OwningPtr.h:72
LLVMTargetMachine(const Target &T, StringRef TargetTriple, StringRef CPU, StringRef FS, TargetOptions Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL)
static cl::opt< cl::boolOrDefault > EnableFastISelOption("fast-isel", cl::Hidden, cl::desc("Enable the \"fast\" instruction selector"))
virtual const TargetInstrInfo * getInstrInfo() const
const MCContext & getContext() const
AsmPrinter * createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const
MCCodeGenInfo * CodeGenInfo
void setFastISel(bool Enable)
virtual void addAnalysisPasses(PassManagerBase &PM)
Register analysis passes for this target with a pass manager.
static bool getVerboseAsm()
const StringRef getTargetTriple() const
cl::opt< std::string > StopAfter("stop-after", cl::desc("Stop compilation after a specific pass"), cl::value_desc("pass-name"), cl::init(""))
cl::opt< std::string > StartAfter("start-after", cl::desc("Resume compilation after a specific pass"), cl::value_desc("pass-name"), cl::init(""))
virtual const TargetRegisterInfo * getRegisterInfo() const
cl::opt< TargetMachine::CodeGenFileType > FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile), cl::desc("Choose a file type (not all types are supported by all targets):"), cl::values(clEnumValN(TargetMachine::CGFT_AssemblyFile,"asm","Emit an assembly ('.s') file"), clEnumValN(TargetMachine::CGFT_ObjectFile,"obj","Emit a native object ('.o') file"), clEnumValN(TargetMachine::CGFT_Null,"null","Emit nothing, for performance testing"), clEnumValEnd))
const void * AnalysisID
Definition: Pass.h:47
bool hasMCUseCFI() const
hasMCUseCFI - Check whether we should use dwarf's .cfi_* directives.
bool hasMCUseLoc() const
hasMCUseLoc - Check whether we should use dwarf's .loc directive.
bool hasMCNoExecStack() const
hasMCNoExecStack - Check whether an executable stack is not needed.
bool hasMCUseDwarfDirectory() const
MCAsmBackend - Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:34
MCStreamer * createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, bool useCFI, bool useDwarfDirectory, MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) const
createAsmStreamer - Create a target specific MCStreamer.
const Target & getTarget() const
const MCRegisterInfo & MRI
virtual void reset()
lifetime management
Definition: MCAsmBackend.h:48