blob: 8d9a832d2816bc08de3f88f1caea6bdca762402d [file] [log] [blame]
Chris Lattnerb26bcc52001-09-14 05:34:53 +00001//===-- TargetMachine.cpp - General Target Information ---------------------==//
2//
3// This file describes the general parts of a Target machine.
Vikram S. Adve4a48c332001-11-09 02:20:18 +00004// This file also implements MachineInstrInfo and MachineCacheInfo.
Chris Lattnerb26bcc52001-09-14 05:34:53 +00005//
6//===----------------------------------------------------------------------===//
Vikram S. Advedaae6992001-07-21 12:42:08 +00007
Vikram S. Adve4a48c332001-11-09 02:20:18 +00008#include "llvm/Target/TargetMachine.h"
Vikram S. Adve0799fc42001-09-18 12:58:33 +00009#include "llvm/Target/MachineInstrInfo.h"
Vikram S. Adve4a48c332001-11-09 02:20:18 +000010#include "llvm/Target/MachineCacheInfo.h"
Vikram S. Advee1f72802002-09-16 15:39:26 +000011#include "llvm/CodeGen/PreSelection.h"
12#include "llvm/CodeGen/InstrSelection.h"
13#include "llvm/CodeGen/InstrScheduling.h"
14#include "llvm/CodeGen/RegisterAllocation.h"
Vikram S. Advee5b25652002-09-20 00:52:43 +000015#include "llvm/CodeGen/PeepholeOpts.h"
Vikram S. Advee1f72802002-09-16 15:39:26 +000016#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"
Chris Lattner68498ce2001-07-21 23:24:48 +000024#include "llvm/DerivedTypes.h"
Vikram S. Advedaae6992001-07-21 12:42:08 +000025
Vikram S. Advedaae6992001-07-21 12:42:08 +000026//---------------------------------------------------------------------------
Vikram S. Advee1f72802002-09-16 15:39:26 +000027// Command line options to control choice of code generation passes.
28//---------------------------------------------------------------------------
29
30static cl::opt<bool> DisablePreSelect("nopreselect",
31 cl::desc("Disable preselection pass"));
32
33static cl::opt<bool> DisableSched("nosched",
34 cl::desc("Disable local scheduling pass"));
35
Vikram S. Advee5b25652002-09-20 00:52:43 +000036static cl::opt<bool> DisablePeephole("nopeephole",
37 cl::desc("Disable peephole optimization pass"));
38
Vikram S. Advee1f72802002-09-16 15:39:26 +000039//---------------------------------------------------------------------------
Vikram S. Adve44a853c2001-07-28 04:09:37 +000040// class TargetMachine
Vikram S. Advedaae6992001-07-21 12:42:08 +000041//
42// Purpose:
Vikram S. Adve44a853c2001-07-28 04:09:37 +000043// Machine description.
44//
Vikram S. Advedaae6992001-07-21 12:42:08 +000045//---------------------------------------------------------------------------
46
Vikram S. Adve0799fc42001-09-18 12:58:33 +000047
Vikram S. Adve44a853c2001-07-28 04:09:37 +000048// function TargetMachine::findOptimalStorageSize
49//
50// Purpose:
Vikram S. Adve44a853c2001-07-28 04:09:37 +000051// 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//
Vikram S. Adve0799fc42001-09-18 12:58:33 +000055unsigned int
56TargetMachine::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;
Vikram S. Advedaae6992001-07-21 12:42:08 +000066
Vikram S. Adve0799fc42001-09-18 12:58:33 +000067 default:
68 return DataLayout.getTypeSize(ty);
69 }
Vikram S. Advedaae6992001-07-21 12:42:08 +000070}
71
Vikram S. Adve44a853c2001-07-28 04:09:37 +000072
Vikram S. Advee1f72802002-09-16 15:39:26 +000073//===---------------------------------------------------------------------===//
74// Default code generation passes.
75//
76// Native code generation for a specified target.
77//===---------------------------------------------------------------------===//
78
79class ConstructMachineCodeForFunction : public FunctionPass {
80 TargetMachine &Target;
81public:
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
94struct 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//
116void
117TargetMachine::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
Vikram S. Advee1f72802002-09-16 15:39:26 +0000139 PM.add(getPrologEpilogInsertionPass());
140
Vikram S. Advee5b25652002-09-20 00:52:43 +0000141 if (!DisablePeephole)
142 PM.add(createPeepholeOptsPass(*this));
143
Vikram S. Advee1f72802002-09-16 15:39:26 +0000144 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
Vikram S. Adve44a853c2001-07-28 04:09:37 +0000164//---------------------------------------------------------------------------
165// class MachineInstructionInfo
166// Interface to description of machine instructions
167//---------------------------------------------------------------------------
168
169
170/*ctor*/
Vikram S. Adve7a2f1e72001-11-08 05:15:08 +0000171MachineInstrInfo::MachineInstrInfo(const TargetMachine& tgt,
172 const MachineInstrDescriptor* _desc,
Vikram S. Advebf242332001-08-28 23:09:36 +0000173 unsigned int _descSize,
174 unsigned int _numRealOpCodes)
Vikram S. Adve7a2f1e72001-11-08 05:15:08 +0000175 : target(tgt),
176 desc(_desc), descSize(_descSize), numRealOpCodes(_numRealOpCodes)
Vikram S. Adve44a853c2001-07-28 04:09:37 +0000177{
Chris Lattner78a81a22001-09-14 16:08:12 +0000178 // FIXME: TargetInstrDescriptors should not be global
Vikram S. Adve44a853c2001-07-28 04:09:37 +0000179 assert(TargetInstrDescriptors == NULL && desc != NULL);
180 TargetInstrDescriptors = desc; // initialize global variable
181}
182
183
Vikram S. Adve0799fc42001-09-18 12:58:33 +0000184MachineInstrInfo::~MachineInstrInfo()
185{
Vikram S. Adve44a853c2001-07-28 04:09:37 +0000186 TargetInstrDescriptors = NULL; // reset global variable
187}
188
189
190bool
191MachineInstrInfo::constantFitsInImmedField(MachineOpCode opCode,
192 int64_t intValue) const
193{
194 // First, check if opCode has an immed field.
195 bool isSignExtended;
Chris Lattnerc7634612001-09-14 15:43:58 +0000196 uint64_t maxImmedValue = maxImmedConstant(opCode, isSignExtended);
Vikram S. Adve0799fc42001-09-18 12:58:33 +0000197 if (maxImmedValue != 0)
198 {
Vikram S. Advee1f72802002-09-16 15:39:26 +0000199 // 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
Vikram S. Adve0799fc42001-09-18 12:58:33 +0000203 // Now check if the constant fits
204 if (intValue <= (int64_t) maxImmedValue &&
205 intValue >= -((int64_t) maxImmedValue+1))
206 return true;
207 }
Vikram S. Adve44a853c2001-07-28 04:09:37 +0000208
209 return false;
210}
Vikram S. Adve4a48c332001-11-09 02:20:18 +0000211
212
213//---------------------------------------------------------------------------
214// class MachineCacheInfo
215//
216// Purpose:
217// Describes properties of the target cache architecture.
218//---------------------------------------------------------------------------
219
220/*ctor*/
221MachineCacheInfo::MachineCacheInfo(const TargetMachine& tgt)
222 : target(tgt)
223{
224 Initialize();
225}
226
227void
228MachineCacheInfo::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}