Added -print-emitted-asm to print out JIT generated asm to cerr.
[oota-llvm.git] / lib / CodeGen / LLVMTargetMachine.cpp
1 //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Chris Lattner and is distributed under
6 // the University of Illinois Open Source 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/Pass.h"
17 #include "llvm/Assembly/PrintModulePass.h"
18 #include "llvm/Analysis/LoopPass.h"
19 #include "llvm/CodeGen/Passes.h"
20 #include "llvm/Target/TargetOptions.h"
21 #include "llvm/Transforms/Scalar.h"
22 #include "llvm/Support/CommandLine.h"
23 using namespace llvm;
24
25 static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
26     cl::desc("Print LLVM IR produced by the loop-reduce pass"));
27 static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
28     cl::desc("Print LLVM IR input to isel pass"));
29 static cl::opt<bool> PrintEmittedAsm("print-emitted-asm", cl::Hidden,
30     cl::desc("Dump emitter generated instructions as assembly"));
31
32 FileModel::Model
33 LLVMTargetMachine::addPassesToEmitFile(FunctionPassManager &PM,
34                                        std::ostream &Out,
35                                        CodeGenFileType FileType,
36                                        bool Fast) {
37   // Standard LLVM-Level Passes.
38   
39   // Run loop strength reduction before anything else.
40   if (!Fast) {
41     PM.add(createLoopStrengthReducePass(getTargetLowering()));
42     if (PrintLSR)
43       PM.add(new PrintFunctionPass("\n\n*** Code after LSR *** \n", &cerr));
44   }
45   
46   // FIXME: Implement efficient support for garbage collection intrinsics.
47   PM.add(createLowerGCPass());
48
49   if (!ExceptionHandling)
50     PM.add(createLowerInvokePass(getTargetLowering()));
51
52   // Make sure that no unreachable blocks are instruction selected.
53   PM.add(createUnreachableBlockEliminationPass());
54
55   if (!Fast)
56     PM.add(createCodeGenPreparePass(getTargetLowering()));
57
58   if (PrintISelInput)
59     PM.add(new PrintFunctionPass("\n\n*** Final LLVM Code input to ISel *** \n",
60                                  &cerr));
61   
62   // Ask the target for an isel.
63   if (addInstSelector(PM, Fast))
64     return FileModel::Error;
65
66   // Print the instruction selected machine code...
67   if (PrintMachineCode)
68     PM.add(createMachineFunctionPrinterPass(cerr));
69   
70   // Perform register allocation to convert to a concrete x86 representation
71   PM.add(createRegisterAllocator());
72   
73   if (PrintMachineCode)
74     PM.add(createMachineFunctionPrinterPass(cerr));
75
76   // Run post-ra passes.
77   if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
78     PM.add(createMachineFunctionPrinterPass(cerr));
79
80   // Insert prolog/epilog code.  Eliminate abstract frame index references...
81   PM.add(createPrologEpilogCodeInserter());
82   
83   // Second pass scheduler.
84   if (!Fast)
85     PM.add(createPostRAScheduler());
86
87   // Branch folding must be run after regalloc and prolog/epilog insertion.
88   if (!Fast)
89     PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
90     
91   // Fold redundant debug labels.
92   PM.add(createDebugLabelFoldingPass());
93   
94   if (PrintMachineCode)  // Print the register-allocated code
95     PM.add(createMachineFunctionPrinterPass(cerr));
96
97   if (addPreEmitPass(PM, Fast) && PrintMachineCode)
98     PM.add(createMachineFunctionPrinterPass(cerr));
99
100   switch (FileType) {
101   default:
102     break;
103   case TargetMachine::AssemblyFile:
104     if (addAssemblyEmitter(PM, Fast, Out))
105       return FileModel::Error;
106     return FileModel::AsmFile;
107   case TargetMachine::ObjectFile:
108     if (getMachOWriterInfo())
109       return FileModel::MachOFile;
110     else if (getELFWriterInfo())
111       return FileModel::ElfFile;
112   }
113
114   return FileModel::Error;
115 }
116  
117 /// addPassesToEmitFileFinish - If the passes to emit the specified file had to
118 /// be split up (e.g., to add an object writer pass), this method can be used to
119 /// finish up adding passes to emit the file, if necessary.
120 bool LLVMTargetMachine::addPassesToEmitFileFinish(FunctionPassManager &PM,
121                                                   MachineCodeEmitter *MCE,
122                                                   bool Fast) {
123   if (MCE)
124     addSimpleCodeEmitter(PM, Fast, PrintEmittedAsm, *MCE);
125
126   // Delete machine code for this function
127   PM.add(createMachineCodeDeleter());
128
129   return false; // success!
130 }
131
132 /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
133 /// get machine code emitted.  This uses a MachineCodeEmitter object to handle
134 /// actually outputting the machine code and resolving things like the address
135 /// of functions.  This method should returns true if machine code emission is
136 /// not supported.
137 ///
138 bool LLVMTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
139                                                    MachineCodeEmitter &MCE,
140                                                    bool Fast) {
141   // Standard LLVM-Level Passes.
142   
143   // Run loop strength reduction before anything else.
144   if (!Fast) {
145     PM.add(createLoopStrengthReducePass(getTargetLowering()));
146     if (PrintLSR)
147       PM.add(new PrintFunctionPass("\n\n*** Code after LSR *** \n", &cerr));
148   }
149   
150   // FIXME: Implement efficient support for garbage collection intrinsics.
151   PM.add(createLowerGCPass());
152   
153   // FIXME: Implement the invoke/unwind instructions!
154   PM.add(createLowerInvokePass(getTargetLowering()));
155   
156   // Make sure that no unreachable blocks are instruction selected.
157   PM.add(createUnreachableBlockEliminationPass());
158
159   if (!Fast)
160     PM.add(createCodeGenPreparePass(getTargetLowering()));
161
162   if (PrintISelInput)
163     PM.add(new PrintFunctionPass("\n\n*** Final LLVM Code input to ISel *** \n",
164                                  &cerr));
165
166   // Ask the target for an isel.
167   if (addInstSelector(PM, Fast))
168     return true;
169
170   // Print the instruction selected machine code...
171   if (PrintMachineCode)
172     PM.add(createMachineFunctionPrinterPass(cerr));
173   
174   // Perform register allocation to convert to a concrete x86 representation
175   PM.add(createRegisterAllocator());
176   
177   if (PrintMachineCode)
178     PM.add(createMachineFunctionPrinterPass(cerr));
179
180   // Run post-ra passes.
181   if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
182     PM.add(createMachineFunctionPrinterPass(cerr));
183
184   // Insert prolog/epilog code.  Eliminate abstract frame index references...
185   PM.add(createPrologEpilogCodeInserter());
186   
187   if (PrintMachineCode)  // Print the register-allocated code
188     PM.add(createMachineFunctionPrinterPass(cerr));
189   
190   // Second pass scheduler.
191   if (!Fast)
192     PM.add(createPostRAScheduler());
193
194   // Branch folding must be run after regalloc and prolog/epilog insertion.
195   if (!Fast)
196     PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
197   
198   if (addPreEmitPass(PM, Fast) && PrintMachineCode)
199     PM.add(createMachineFunctionPrinterPass(cerr));
200
201   addCodeEmitter(PM, Fast, PrintEmittedAsm, MCE);
202   
203   // Delete machine code for this function
204   PM.add(createMachineCodeDeleter());
205   
206   return false; // success!
207 }