LLVMTargetMachine.cpp revision d5422654016b3ac7494db1d2ba16bd8febadb0a8
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
14#include "llvm/Target/TargetMachine.h"
15#include "llvm/PassManager.h"
16#include "llvm/CodeGen/AsmPrinter.h"
17#include "llvm/CodeGen/Passes.h"
18#include "llvm/Target/TargetOptions.h"
19#include "llvm/MC/MCAsmInfo.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCInstrInfo.h"
22#include "llvm/MC/MCStreamer.h"
23#include "llvm/MC/MCSubtargetInfo.h"
24#include "llvm/Target/TargetInstrInfo.h"
25#include "llvm/Target/TargetSubtargetInfo.h"
26#include "llvm/ADT/OwningPtr.h"
27#include "llvm/Support/CommandLine.h"
28#include "llvm/Support/FormattedStream.h"
29#include "llvm/Support/ErrorHandling.h"
30#include "llvm/Support/TargetRegistry.h"
31using namespace llvm;
32
33static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden,
34    cl::desc("Show encoding in .s output"));
35static cl::opt<bool> ShowMCInst("show-mc-inst", cl::Hidden,
36    cl::desc("Show instruction structure in .s output"));
37
38static cl::opt<cl::boolOrDefault>
39AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
40           cl::init(cl::BOU_UNSET));
41
42static bool getVerboseAsm() {
43  switch (AsmVerbose) {
44  case cl::BOU_UNSET: return TargetMachine::getAsmVerbosityDefault();
45  case cl::BOU_TRUE:  return true;
46  case cl::BOU_FALSE: return false;
47  }
48  llvm_unreachable("Invalid verbose asm state");
49}
50
51LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple,
52                                     StringRef CPU, StringRef FS,
53                                     TargetOptions Options,
54                                     Reloc::Model RM, CodeModel::Model CM,
55                                     CodeGenOpt::Level OL)
56  : TargetMachine(T, Triple, CPU, FS, Options) {
57  CodeGenInfo = T.createMCCodeGenInfo(Triple, RM, CM, OL);
58  AsmInfo = T.createMCAsmInfo(Triple);
59  // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
60  // and if the old one gets included then MCAsmInfo will be NULL and
61  // we'll crash later.
62  // Provide the user with a useful error message about what's wrong.
63  assert(AsmInfo && "MCAsmInfo not initialized."
64         "Make sure you include the correct TargetSelect.h"
65         "and that InitializeAllTargetMCs() is being invoked!");
66}
67
68bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
69                                            formatted_raw_ostream &Out,
70                                            CodeGenFileType FileType,
71                                            bool DisableVerify) {
72  // Add common CodeGen passes.
73  MCContext *Context = 0;
74  TargetPassConfig *PassConfig = createPassConfig(PM, DisableVerify);
75  PM.add(PassConfig);
76  if (PassConfig->addCodeGenPasses(Context))
77    return true;
78  assert(Context != 0 && "Failed to get MCContext");
79
80  if (hasMCSaveTempLabels())
81    Context->setAllowTemporaryLabels(false);
82
83  const MCAsmInfo &MAI = *getMCAsmInfo();
84  const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
85  OwningPtr<MCStreamer> AsmStreamer;
86
87  switch (FileType) {
88  case CGFT_AssemblyFile: {
89    MCInstPrinter *InstPrinter =
90      getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, STI);
91
92    // Create a code emitter if asked to show the encoding.
93    MCCodeEmitter *MCE = 0;
94    MCAsmBackend *MAB = 0;
95    if (ShowMCEncoding) {
96      const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
97      MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI, *Context);
98      MAB = getTarget().createMCAsmBackend(getTargetTriple());
99    }
100
101    MCStreamer *S = getTarget().createAsmStreamer(*Context, Out,
102                                                  getVerboseAsm(),
103                                                  hasMCUseLoc(),
104                                                  hasMCUseCFI(),
105                                                  hasMCUseDwarfDirectory(),
106                                                  InstPrinter,
107                                                  MCE, MAB,
108                                                  ShowMCInst);
109    AsmStreamer.reset(S);
110    break;
111  }
112  case CGFT_ObjectFile: {
113    // Create the code emitter for the target if it exists.  If not, .o file
114    // emission fails.
115    MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI,
116                                                         *Context);
117    MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple());
118    if (MCE == 0 || MAB == 0)
119      return true;
120
121    AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(),
122                                                         *Context, *MAB, Out,
123                                                         MCE, hasMCRelaxAll(),
124                                                         hasMCNoExecStack()));
125    AsmStreamer.get()->InitSections();
126    break;
127  }
128  case CGFT_Null:
129    // The Null output is intended for use for performance analysis and testing,
130    // not real users.
131    AsmStreamer.reset(createNullStreamer(*Context));
132    break;
133  }
134
135  // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
136  FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
137  if (Printer == 0)
138    return true;
139
140  // If successful, createAsmPrinter took ownership of AsmStreamer.
141  AsmStreamer.take();
142
143  PM.add(Printer);
144
145  PM.add(createGCInfoDeleter());
146  return false;
147}
148
149/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
150/// get machine code emitted.  This uses a JITCodeEmitter object to handle
151/// actually outputting the machine code and resolving things like the address
152/// of functions.  This method should returns true if machine code emission is
153/// not supported.
154///
155bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
156                                                   JITCodeEmitter &JCE,
157                                                   bool DisableVerify) {
158  // Add common CodeGen passes.
159  MCContext *Ctx = 0;
160  OwningPtr<TargetPassConfig> PassConfig(createPassConfig(PM, DisableVerify));
161  if (PassConfig->addCodeGenPasses(Ctx))
162    return true;
163
164  addCodeEmitter(PM, JCE);
165  PM.add(createGCInfoDeleter());
166
167  return false; // success!
168}
169
170/// addPassesToEmitMC - Add passes to the specified pass manager to get
171/// machine code emitted with the MCJIT. This method returns true if machine
172/// code is not supported. It fills the MCContext Ctx pointer which can be
173/// used to build custom MCStreamer.
174///
175bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
176                                          MCContext *&Ctx,
177                                          raw_ostream &Out,
178                                          bool DisableVerify) {
179  // Add common CodeGen passes.
180  OwningPtr<TargetPassConfig> PassConfig(createPassConfig(PM, DisableVerify));
181  if (PassConfig->addCodeGenPasses(Ctx))
182    return true;
183
184  if (hasMCSaveTempLabels())
185    Ctx->setAllowTemporaryLabels(false);
186
187  // Create the code emitter for the target if it exists.  If not, .o file
188  // emission fails.
189  const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
190  MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(),STI, *Ctx);
191  MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple());
192  if (MCE == 0 || MAB == 0)
193    return true;
194
195  OwningPtr<MCStreamer> AsmStreamer;
196  AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Ctx,
197                                                       *MAB, Out, MCE,
198                                                       hasMCRelaxAll(),
199                                                       hasMCNoExecStack()));
200  AsmStreamer.get()->InitSections();
201
202  // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
203  FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
204  if (Printer == 0)
205    return true;
206
207  // If successful, createAsmPrinter took ownership of AsmStreamer.
208  AsmStreamer.take();
209
210  PM.add(Printer);
211
212  return false; // success!
213}
214