Add a really quick hack at a machine code sinking pass, enabled with --enable-sinking.
[oota-llvm.git] / lib / CodeGen / LLVMTargetMachine.cpp
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/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 // Hidden options to help debugging
33 static cl::opt<bool>
34 EnableSinking("enable-sinking", cl::init(false), cl::Hidden,
35               cl::desc("Perform sinking on machine code"));
36
37
38 FileModel::Model
39 LLVMTargetMachine::addPassesToEmitFile(FunctionPassManager &PM,
40                                        std::ostream &Out,
41                                        CodeGenFileType FileType,
42                                        bool Fast) {
43   // Standard LLVM-Level Passes.
44   
45   // Run loop strength reduction before anything else.
46   if (!Fast) {
47     PM.add(createLoopStrengthReducePass(getTargetLowering()));
48     if (PrintLSR)
49       PM.add(new PrintFunctionPass("\n\n*** Code after LSR *** \n", &cerr));
50   }
51   
52   // FIXME: Implement efficient support for garbage collection intrinsics.
53   PM.add(createLowerGCPass());
54
55   if (!ExceptionHandling)
56     PM.add(createLowerInvokePass(getTargetLowering()));
57
58   // Make sure that no unreachable blocks are instruction selected.
59   PM.add(createUnreachableBlockEliminationPass());
60
61   if (!Fast)
62     PM.add(createCodeGenPreparePass(getTargetLowering()));
63
64   if (PrintISelInput)
65     PM.add(new PrintFunctionPass("\n\n*** Final LLVM Code input to ISel *** \n",
66                                  &cerr));
67   
68   // Ask the target for an isel.
69   if (addInstSelector(PM, Fast))
70     return FileModel::Error;
71
72   // Print the instruction selected machine code...
73   if (PrintMachineCode)
74     PM.add(createMachineFunctionPrinterPass(cerr));
75
76   PM.add(createMachineLICMPass());
77   
78   if (EnableSinking)
79     PM.add(createMachineSinkingPass());
80
81   // Perform register allocation to convert to a concrete x86 representation
82   PM.add(createRegisterAllocator());
83   
84   if (PrintMachineCode)
85     PM.add(createMachineFunctionPrinterPass(cerr));
86     
87   PM.add(createLowerSubregsPass());
88   
89   if (PrintMachineCode)  // Print the subreg lowered code
90     PM.add(createMachineFunctionPrinterPass(cerr));
91
92   // Run post-ra passes.
93   if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
94     PM.add(createMachineFunctionPrinterPass(cerr));
95
96   // Insert prolog/epilog code.  Eliminate abstract frame index references...
97   PM.add(createPrologEpilogCodeInserter());
98   
99   // Second pass scheduler.
100   if (!Fast)
101     PM.add(createPostRAScheduler());
102
103   // Branch folding must be run after regalloc and prolog/epilog insertion.
104   if (!Fast)
105     PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
106
107   // Fold redundant debug labels.
108   PM.add(createDebugLabelFoldingPass());
109   
110   if (PrintMachineCode)  // Print the register-allocated code
111     PM.add(createMachineFunctionPrinterPass(cerr));
112
113   if (addPreEmitPass(PM, Fast) && PrintMachineCode)
114     PM.add(createMachineFunctionPrinterPass(cerr));
115
116   switch (FileType) {
117   default:
118     break;
119   case TargetMachine::AssemblyFile:
120     if (addAssemblyEmitter(PM, Fast, Out))
121       return FileModel::Error;
122     return FileModel::AsmFile;
123   case TargetMachine::ObjectFile:
124     if (getMachOWriterInfo())
125       return FileModel::MachOFile;
126     else if (getELFWriterInfo())
127       return FileModel::ElfFile;
128   }
129
130   return FileModel::Error;
131 }
132  
133 /// addPassesToEmitFileFinish - If the passes to emit the specified file had to
134 /// be split up (e.g., to add an object writer pass), this method can be used to
135 /// finish up adding passes to emit the file, if necessary.
136 bool LLVMTargetMachine::addPassesToEmitFileFinish(FunctionPassManager &PM,
137                                                   MachineCodeEmitter *MCE,
138                                                   bool Fast) {
139   if (MCE)
140     addSimpleCodeEmitter(PM, Fast, PrintEmittedAsm, *MCE);
141
142   // Delete machine code for this function
143   PM.add(createMachineCodeDeleter());
144
145   return false; // success!
146 }
147
148 /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
149 /// get machine code emitted.  This uses a MachineCodeEmitter object to handle
150 /// actually outputting the machine code and resolving things like the address
151 /// of functions.  This method should returns true if machine code emission is
152 /// not supported.
153 ///
154 bool LLVMTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
155                                                    MachineCodeEmitter &MCE,
156                                                    bool Fast) {
157   // Standard LLVM-Level Passes.
158   
159   // Run loop strength reduction before anything else.
160   if (!Fast) {
161     PM.add(createLoopStrengthReducePass(getTargetLowering()));
162     if (PrintLSR)
163       PM.add(new PrintFunctionPass("\n\n*** Code after LSR *** \n", &cerr));
164   }
165   
166   // FIXME: Implement efficient support for garbage collection intrinsics.
167   PM.add(createLowerGCPass());
168   
169   // FIXME: Implement the invoke/unwind instructions!
170   PM.add(createLowerInvokePass(getTargetLowering()));
171   
172   // Make sure that no unreachable blocks are instruction selected.
173   PM.add(createUnreachableBlockEliminationPass());
174
175   if (!Fast)
176     PM.add(createCodeGenPreparePass(getTargetLowering()));
177
178   if (PrintISelInput)
179     PM.add(new PrintFunctionPass("\n\n*** Final LLVM Code input to ISel *** \n",
180                                  &cerr));
181
182   // Ask the target for an isel.
183   if (addInstSelector(PM, Fast))
184     return true;
185
186   // Print the instruction selected machine code...
187   if (PrintMachineCode)
188     PM.add(createMachineFunctionPrinterPass(cerr));
189
190   PM.add(createMachineLICMPass());
191
192   // Perform register allocation to convert to a concrete x86 representation
193   PM.add(createRegisterAllocator());
194   
195   if (PrintMachineCode)
196     PM.add(createMachineFunctionPrinterPass(cerr));
197     
198   PM.add(createLowerSubregsPass());
199   
200   if (PrintMachineCode)  // Print the subreg lowered code
201     PM.add(createMachineFunctionPrinterPass(cerr));
202
203   // Run post-ra passes.
204   if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
205     PM.add(createMachineFunctionPrinterPass(cerr));
206
207   // Insert prolog/epilog code.  Eliminate abstract frame index references...
208   PM.add(createPrologEpilogCodeInserter());
209   
210   if (PrintMachineCode)  // Print the register-allocated code
211     PM.add(createMachineFunctionPrinterPass(cerr));
212   
213   // Second pass scheduler.
214   if (!Fast)
215     PM.add(createPostRAScheduler());
216
217   // Branch folding must be run after regalloc and prolog/epilog insertion.
218   if (!Fast)
219     PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
220
221   if (addPreEmitPass(PM, Fast) && PrintMachineCode)
222     PM.add(createMachineFunctionPrinterPass(cerr));
223
224   addCodeEmitter(PM, Fast, PrintEmittedAsm, MCE);
225   
226   // Delete machine code for this function
227   PM.add(createMachineCodeDeleter());
228   
229   return false; // success!
230 }