Add peephole optimization pass at the end of code generation.
[oota-llvm.git] / lib / Target / TargetMachine.cpp
1 //===-- TargetMachine.cpp - General Target Information ---------------------==//
2 //
3 // This file describes the general parts of a Target machine.
4 // This file also implements MachineInstrInfo and MachineCacheInfo.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/Target/TargetMachine.h"
9 #include "llvm/Target/MachineInstrInfo.h"
10 #include "llvm/Target/MachineCacheInfo.h"
11 #include "llvm/CodeGen/PreSelection.h"
12 #include "llvm/CodeGen/InstrSelection.h"
13 #include "llvm/CodeGen/InstrScheduling.h"
14 #include "llvm/CodeGen/RegisterAllocation.h"
15 #include "llvm/CodeGen/PeepholeOpts.h"
16 #include "llvm/CodeGen/MachineCodeForMethod.h"
17 #include "llvm/CodeGen/MachineCodeForInstruction.h"
18 #include "llvm/Reoptimizer/Mapping/MappingInfo.h" 
19 #include "llvm/Reoptimizer/Mapping/FInfo.h" 
20 #include "llvm/Transforms/Scalar.h"
21 #include "Support/CommandLine.h"
22 #include "llvm/PassManager.h"
23 #include "llvm/Function.h"
24 #include "llvm/DerivedTypes.h"
25
26 //---------------------------------------------------------------------------
27 // Command line options to control choice of code generation passes.
28 //---------------------------------------------------------------------------
29
30 static cl::opt<bool> DisablePreSelect("nopreselect",
31                                       cl::desc("Disable preselection pass"));
32
33 static cl::opt<bool> DisableSched("nosched",
34                                   cl::desc("Disable local scheduling pass"));
35
36 static cl::opt<bool> DisablePeephole("nopeephole",
37                                      cl::desc("Disable peephole optimization pass"));
38
39 //---------------------------------------------------------------------------
40 // class TargetMachine
41 // 
42 // Purpose:
43 //   Machine description.
44 // 
45 //---------------------------------------------------------------------------
46
47
48 // function TargetMachine::findOptimalStorageSize 
49 // 
50 // Purpose:
51 //   This default implementation assumes that all sub-word data items use
52 //   space equal to optSizeForSubWordData, and all other primitive data
53 //   items use space according to the type.
54 //   
55 unsigned int
56 TargetMachine::findOptimalStorageSize(const Type* ty) const
57 {
58   switch(ty->getPrimitiveID())
59     {
60     case Type::BoolTyID:
61     case Type::UByteTyID:
62     case Type::SByteTyID:     
63     case Type::UShortTyID:
64     case Type::ShortTyID:     
65       return optSizeForSubWordData;
66     
67     default:
68       return DataLayout.getTypeSize(ty);
69     }
70 }
71
72
73 //===---------------------------------------------------------------------===//
74 // Default code generation passes.
75 // 
76 // Native code generation for a specified target.
77 //===---------------------------------------------------------------------===//
78
79 class ConstructMachineCodeForFunction : public FunctionPass {
80   TargetMachine &Target;
81 public:
82   inline ConstructMachineCodeForFunction(TargetMachine &T) : Target(T) {}
83
84   const char *getPassName() const {
85     return "ConstructMachineCodeForFunction";
86   }
87
88   bool runOnFunction(Function &F) {
89     MachineCodeForMethod::construct(&F, Target);
90     return false;
91   }
92 };
93
94 struct FreeMachineCodeForFunction : public FunctionPass {
95   const char *getPassName() const { return "FreeMachineCodeForFunction"; }
96
97   static void freeMachineCode(Instruction &I) {
98     MachineCodeForInstruction::destroy(&I);
99   }
100   
101   bool runOnFunction(Function &F) {
102     for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
103       for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I)
104         MachineCodeForInstruction::get(I).dropAllReferences();
105     
106     for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
107       for_each(FI->begin(), FI->end(), freeMachineCode);
108     
109     return false;
110   }
111 };
112
113 // addPassesToEmitAssembly - This method controls the entire code generation
114 // process for the ultra sparc.
115 //
116 void
117 TargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out)
118 {
119   // Construct and initialize the MachineCodeForMethod object for this fn.
120   PM.add(new ConstructMachineCodeForFunction(*this));
121
122   // Specialize LLVM code for this target machine and then
123   // run basic dataflow optimizations on LLVM code.
124   if (!DisablePreSelect)
125     {
126       PM.add(createPreSelectionPass(*this));
127       PM.add(createReassociatePass());
128       PM.add(createGCSEPass());
129       PM.add(createLICMPass());
130     }
131
132   PM.add(createInstructionSelectionPass(*this));
133
134   if (!DisableSched)
135     PM.add(createInstructionSchedulingWithSSAPass(*this));
136
137   PM.add(getRegisterAllocator(*this));
138
139   PM.add(getPrologEpilogInsertionPass());
140
141   if (!DisablePeephole)
142     PM.add(createPeepholeOptsPass(*this));
143
144   PM.add(MappingInfoForFunction(Out));  
145
146   // Output assembly language to the .s file.  Assembly emission is split into
147   // two parts: Function output and Global value output.  This is because
148   // function output is pipelined with all of the rest of code generation stuff,
149   // allowing machine code representations for functions to be free'd after the
150   // function has been emitted.
151   //
152   PM.add(getFunctionAsmPrinterPass(Out));
153   PM.add(new FreeMachineCodeForFunction());  // Free stuff no longer needed
154
155   // Emit Module level assembly after all of the functions have been processed.
156   PM.add(getModuleAsmPrinterPass(Out));
157
158   // Emit bytecode to the assembly file into its special section next
159   PM.add(getEmitBytecodeToAsmPass(Out));
160   PM.add(getFunctionInfo(Out)); 
161 }
162
163
164 //---------------------------------------------------------------------------
165 // class MachineInstructionInfo
166 //      Interface to description of machine instructions
167 //---------------------------------------------------------------------------
168
169
170 /*ctor*/
171 MachineInstrInfo::MachineInstrInfo(const TargetMachine& tgt,
172                                    const MachineInstrDescriptor* _desc,
173                                    unsigned int _descSize,
174                                    unsigned int _numRealOpCodes)
175   : target(tgt),
176     desc(_desc), descSize(_descSize), numRealOpCodes(_numRealOpCodes)
177 {
178   // FIXME: TargetInstrDescriptors should not be global
179   assert(TargetInstrDescriptors == NULL && desc != NULL);
180   TargetInstrDescriptors = desc;        // initialize global variable
181 }  
182
183
184 MachineInstrInfo::~MachineInstrInfo()
185 {
186   TargetInstrDescriptors = NULL;        // reset global variable
187 }
188
189
190 bool
191 MachineInstrInfo::constantFitsInImmedField(MachineOpCode opCode,
192                                            int64_t intValue) const
193 {
194   // First, check if opCode has an immed field.
195   bool isSignExtended;
196   uint64_t maxImmedValue = maxImmedConstant(opCode, isSignExtended);
197   if (maxImmedValue != 0)
198     {
199       // NEED TO HANDLE UNSIGNED VALUES SINCE THEY MAY BECOME MUCH
200       // SMALLER AFTER CASTING TO SIGN-EXTENDED int, short, or char.
201       // See CreateUIntSetInstruction in SparcInstrInfo.cpp.
202       
203       // Now check if the constant fits
204       if (intValue <= (int64_t) maxImmedValue &&
205           intValue >= -((int64_t) maxImmedValue+1))
206         return true;
207     }
208   
209   return false;
210 }
211
212
213 //---------------------------------------------------------------------------
214 // class MachineCacheInfo 
215 // 
216 // Purpose:
217 //   Describes properties of the target cache architecture.
218 //---------------------------------------------------------------------------
219
220 /*ctor*/
221 MachineCacheInfo::MachineCacheInfo(const TargetMachine& tgt)
222   : target(tgt)
223 {
224   Initialize();
225 }
226
227 void
228 MachineCacheInfo::Initialize()
229 {
230   numLevels = 2;
231   cacheLineSizes.push_back(16);  cacheLineSizes.push_back(32); 
232   cacheSizes.push_back(1 << 15); cacheSizes.push_back(1 << 20);
233   cacheAssoc.push_back(1);       cacheAssoc.push_back(4);
234 }