blob: 79886176ccc31510bb0d3d508a38b815425ff14e [file] [log] [blame]
Chris Lattner6b944532002-10-28 01:16:38 +00001//===-- MachineFunction.cpp -----------------------------------------------===//
Chris Lattnerf2868ce2002-02-03 07:54:50 +00002//
Chris Lattner6b944532002-10-28 01:16:38 +00003// Collect native machine code information for a function. This allows
4// target-specific information about the generated code to be stored with each
5// function.
6//
7//===----------------------------------------------------------------------===//
Chris Lattnerf2868ce2002-02-03 07:54:50 +00008
Chris Lattner6b944532002-10-28 01:16:38 +00009#include "llvm/CodeGen/MachineFunction.h"
Chris Lattner831fdcf2002-12-25 05:03:22 +000010#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner227c3d32002-10-28 01:12:41 +000011#include "llvm/CodeGen/MachineCodeForInstruction.h"
Chris Lattner831fdcf2002-12-25 05:03:22 +000012#include "llvm/CodeGen/SSARegMap.h"
Chris Lattner955fad12002-12-28 20:37:16 +000013#include "llvm/CodeGen/MachineFunctionInfo.h"
Chris Lattnereb24db92002-12-28 21:08:26 +000014#include "llvm/CodeGen/MachineFrameInfo.h"
Chris Lattnerf2868ce2002-02-03 07:54:50 +000015#include "llvm/Target/TargetMachine.h"
Chris Lattner8bd66e62002-12-28 21:00:25 +000016#include "llvm/Target/TargetFrameInfo.h"
Chris Lattnerf2868ce2002-02-03 07:54:50 +000017#include "llvm/Target/MachineCacheInfo.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000018#include "llvm/Function.h"
Chris Lattnerf2868ce2002-02-03 07:54:50 +000019#include "llvm/iOther.h"
Chris Lattner227c3d32002-10-28 01:12:41 +000020#include "llvm/Pass.h"
Chris Lattnerf2868ce2002-02-03 07:54:50 +000021#include <limits.h>
22
23const int INVALID_FRAME_OFFSET = INT_MAX; // std::numeric_limits<int>::max();
24
Chris Lattnere316efc2002-10-29 23:18:43 +000025static AnnotationID MF_AID(
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000026 AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
Chris Lattnerf2868ce2002-02-03 07:54:50 +000027
Chris Lattner227c3d32002-10-28 01:12:41 +000028
29//===---------------------------------------------------------------------===//
30// Code generation/destruction passes
31//===---------------------------------------------------------------------===//
32
33namespace {
34 class ConstructMachineFunction : public FunctionPass {
35 TargetMachine &Target;
36 public:
37 ConstructMachineFunction(TargetMachine &T) : Target(T) {}
38
39 const char *getPassName() const {
40 return "ConstructMachineFunction";
41 }
42
43 bool runOnFunction(Function &F) {
Chris Lattner955fad12002-12-28 20:37:16 +000044 MachineFunction::construct(&F, Target).getInfo()->CalculateArgSize();
Chris Lattner227c3d32002-10-28 01:12:41 +000045 return false;
46 }
47 };
48
49 struct DestroyMachineFunction : public FunctionPass {
50 const char *getPassName() const { return "FreeMachineFunction"; }
51
52 static void freeMachineCode(Instruction &I) {
53 MachineCodeForInstruction::destroy(&I);
54 }
55
56 bool runOnFunction(Function &F) {
57 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
58 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I)
59 MachineCodeForInstruction::get(I).dropAllReferences();
60
61 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
62 for_each(FI->begin(), FI->end(), freeMachineCode);
63
64 return false;
65 }
66 };
Chris Lattner10491642002-10-30 00:48:05 +000067
68 struct Printer : public FunctionPass {
69 const char *getPassName() const { return "MachineFunction Printer"; }
70
71 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
72 AU.setPreservesAll();
73 }
74
75 bool runOnFunction(Function &F) {
76 MachineFunction::get(&F).dump();
77 return false;
78 }
79 };
Chris Lattner227c3d32002-10-28 01:12:41 +000080}
81
82Pass *createMachineCodeConstructionPass(TargetMachine &Target) {
83 return new ConstructMachineFunction(Target);
84}
85
86Pass *createMachineCodeDestructionPass() {
87 return new DestroyMachineFunction();
88}
89
Chris Lattner10491642002-10-30 00:48:05 +000090Pass *createMachineFunctionPrinterPass() {
91 return new Printer();
92}
93
Chris Lattner227c3d32002-10-28 01:12:41 +000094
95//===---------------------------------------------------------------------===//
96// MachineFunction implementation
97//===---------------------------------------------------------------------===//
98
Chris Lattner10491642002-10-30 00:48:05 +000099MachineFunction::MachineFunction(const Function *F,
Chris Lattner955fad12002-12-28 20:37:16 +0000100 const TargetMachine &TM)
101 : Annotation(MF_AID), Fn(F), Target(TM) {
Misha Brukmanb7825bc2002-11-20 18:55:27 +0000102 SSARegMapping = new SSARegMap();
Chris Lattner955fad12002-12-28 20:37:16 +0000103 MFInfo = new MachineFunctionInfo(*this);
Chris Lattnereb24db92002-12-28 21:08:26 +0000104 FrameInfo = new MachineFrameInfo();
Chris Lattner831fdcf2002-12-25 05:03:22 +0000105}
106
107MachineFunction::~MachineFunction() {
108 delete SSARegMapping;
Chris Lattner955fad12002-12-28 20:37:16 +0000109 delete MFInfo;
110 delete FrameInfo;
Chris Lattner10491642002-10-30 00:48:05 +0000111}
112
113void MachineFunction::dump() const { print(std::cerr); }
114
115void MachineFunction::print(std::ostream &OS) const {
Chris Lattner955fad12002-12-28 20:37:16 +0000116 OS << "\n" << *(Value*)Fn->getFunctionType() << " \"" << Fn->getName()
117 << "\"\n";
118
119 // Print Frame Information
120 getFrameInfo()->print(OS);
Chris Lattner10491642002-10-30 00:48:05 +0000121
122 for (const_iterator BB = begin(); BB != end(); ++BB) {
123 BasicBlock *LBB = BB->getBasicBlock();
Chris Lattner2109f502002-12-15 20:35:25 +0000124 OS << "\n" << LBB->getName() << " (" << (const void*)LBB << "):\n";
Chris Lattner10491642002-10-30 00:48:05 +0000125 for (MachineBasicBlock::const_iterator I = BB->begin(); I != BB->end();++I){
126 OS << "\t";
127 (*I)->print(OS, Target);
128 }
129 }
130 OS << "\nEnd function \"" << Fn->getName() << "\"\n\n";
131}
132
133
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000134// The next two methods are used to construct and to retrieve
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000135// the MachineCodeForFunction object for the given function.
136// construct() -- Allocates and initializes for a given function and target
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000137// get() -- Returns a handle to the object.
138// This should not be called before "construct()"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000139// for a given Function.
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000140//
Misha Brukmanfce11432002-10-28 00:28:31 +0000141MachineFunction&
Chris Lattner335d5c32002-10-28 05:58:46 +0000142MachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000143{
Chris Lattnere316efc2002-10-29 23:18:43 +0000144 assert(Fn->getAnnotation(MF_AID) == 0 &&
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000145 "Object already exists for this function!");
Chris Lattner335d5c32002-10-28 05:58:46 +0000146 MachineFunction* mcInfo = new MachineFunction(Fn, Tar);
147 Fn->addAnnotation(mcInfo);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000148 return *mcInfo;
149}
150
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000151void
Chris Lattner335d5c32002-10-28 05:58:46 +0000152MachineFunction::destruct(const Function *Fn)
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000153{
Chris Lattnere316efc2002-10-29 23:18:43 +0000154 bool Deleted = Fn->deleteAnnotation(MF_AID);
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000155 assert(Deleted && "Machine code did not exist for function!");
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000156}
157
Chris Lattner335d5c32002-10-28 05:58:46 +0000158MachineFunction& MachineFunction::get(const Function *F)
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000159{
Chris Lattnere316efc2002-10-29 23:18:43 +0000160 MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000161 assert(mc && "Call construct() method first to allocate the object");
162 return *mc;
163}
164
Chris Lattner831fdcf2002-12-25 05:03:22 +0000165void MachineFunction::clearSSARegMap() {
166 delete SSARegMapping;
167 SSARegMapping = 0;
168}
169
Chris Lattner955fad12002-12-28 20:37:16 +0000170//===----------------------------------------------------------------------===//
Chris Lattnereb24db92002-12-28 21:08:26 +0000171// MachineFrameInfo implementation
Chris Lattner955fad12002-12-28 20:37:16 +0000172//===----------------------------------------------------------------------===//
173
Chris Lattnereb24db92002-12-28 21:08:26 +0000174void MachineFrameInfo::print(std::ostream &OS) const {
Chris Lattner955fad12002-12-28 20:37:16 +0000175 for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
176 const StackObject &SO = Objects[i];
177 OS << " <fi# " << (int)(i-NumFixedObjects) << "> is ";
178 if (SO.Size == 0)
179 OS << "variable sized";
180 else
181 OS << SO.Size << " byte" << (SO.Size != 1 ? "s" : " ");
182
183 if (i < NumFixedObjects)
184 OS << " fixed";
185 if (i < NumFixedObjects || SO.SPOffset != -1) {
186 OS << " at location [SP";
187 if (SO.SPOffset > 0)
188 OS << "+" << SO.SPOffset;
189 else if (SO.SPOffset < 0)
190 OS << SO.SPOffset;
191 OS << "]";
192 }
193 OS << "\n";
194 }
195
196 if (HasVarSizedObjects)
197 OS << " Stack frame contains variable sized objects\n";
198}
199
Chris Lattnereb24db92002-12-28 21:08:26 +0000200void MachineFrameInfo::dump() const { print(std::cerr); }
Chris Lattner955fad12002-12-28 20:37:16 +0000201
202
203//===----------------------------------------------------------------------===//
204// MachineFunctionInfo implementation
205//===----------------------------------------------------------------------===//
Chris Lattner831fdcf2002-12-25 05:03:22 +0000206
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000207static unsigned
Vikram S. Adve03d33bd2002-04-25 04:30:43 +0000208ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
209 unsigned &maxOptionalNumArgs)
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000210{
Chris Lattner955fad12002-12-28 20:37:16 +0000211 const TargetFrameInfo &frameInfo = target.getFrameInfo();
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000212
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000213 unsigned maxSize = 0;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000214
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000215 for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB)
216 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
217 if (const CallInst *callInst = dyn_cast<CallInst>(&*I))
218 {
219 unsigned numOperands = callInst->getNumOperands() - 1;
220 int numExtra = (int)numOperands-frameInfo.getNumFixedOutgoingArgs();
221 if (numExtra <= 0)
222 continue;
223
Chris Lattner955fad12002-12-28 20:37:16 +0000224 unsigned sizeForThisCall;
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000225 if (frameInfo.argsOnStackHaveFixedSize())
226 {
227 int argSize = frameInfo.getSizeOfEachArgOnStack();
228 sizeForThisCall = numExtra * (unsigned) argSize;
229 }
230 else
231 {
232 assert(0 && "UNTESTED CODE: Size per stack argument is not "
233 "fixed on this architecture: use actual arg sizes to "
234 "compute MaxOptionalArgsSize");
235 sizeForThisCall = 0;
236 for (unsigned i = 0; i < numOperands; ++i)
Chris Lattner955fad12002-12-28 20:37:16 +0000237 sizeForThisCall += target.getTargetData().getTypeSize(callInst->
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000238 getOperand(i)->getType());
239 }
240
241 if (maxSize < sizeForThisCall)
242 maxSize = sizeForThisCall;
243
244 if ((int)maxOptionalNumArgs < numExtra)
245 maxOptionalNumArgs = (unsigned) numExtra;
246 }
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000247
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000248 return maxSize;
249}
250
251// Align data larger than one L1 cache line on L1 cache line boundaries.
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000252// Align all smaller data on the next higher 2^x boundary (4, 8, ...),
253// but not higher than the alignment of the largest type we support
254// (currently a double word). -- see class TargetData).
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000255//
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000256// This function is similar to the corresponding function in EmitAssembly.cpp
257// but they are unrelated. This one does not align at more than a
258// double-word boundary whereas that one might.
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000259//
Chris Lattner955fad12002-12-28 20:37:16 +0000260inline unsigned
261SizeToAlignment(unsigned size, const TargetMachine& target)
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000262{
263 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1);
264 if (size > (unsigned) cacheLineSize / 2)
265 return cacheLineSize;
266 else
267 for (unsigned sz=1; /*no condition*/; sz *= 2)
Chris Lattner955fad12002-12-28 20:37:16 +0000268 if (sz >= size || sz >= target.getTargetData().getDoubleAlignment())
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000269 return sz;
270}
271
272
Chris Lattner955fad12002-12-28 20:37:16 +0000273void MachineFunctionInfo::CalculateArgSize() {
274 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
275 MF.getFunction(),
Vikram S. Adve03d33bd2002-04-25 04:30:43 +0000276 maxOptionalNumArgs);
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000277 staticStackSize = maxOptionalArgsSize
Chris Lattner955fad12002-12-28 20:37:16 +0000278 + MF.getTarget().getFrameInfo().getMinStackFrameSize();
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000279}
280
281int
Chris Lattner955fad12002-12-28 20:37:16 +0000282MachineFunctionInfo::computeOffsetforLocalVar(const Value* val,
283 unsigned &getPaddedSize,
284 unsigned sizeToUse)
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000285{
Vikram S. Advee4e4d4e2002-03-24 03:39:26 +0000286 if (sizeToUse == 0)
Chris Lattner955fad12002-12-28 20:37:16 +0000287 sizeToUse = MF.getTarget().findOptimalStorageSize(val->getType());
288 unsigned align = SizeToAlignment(sizeToUse, MF.getTarget());
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000289
290 bool growUp;
Chris Lattner955fad12002-12-28 20:37:16 +0000291 int firstOffset = MF.getTarget().getFrameInfo().getFirstAutomaticVarOffset(MF,
292 growUp);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000293 int offset = growUp? firstOffset + getAutomaticVarsSize()
294 : firstOffset - (getAutomaticVarsSize() + sizeToUse);
295
Chris Lattner955fad12002-12-28 20:37:16 +0000296 int aligned = MF.getTarget().getFrameInfo().adjustAlignment(offset, growUp, align);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000297 getPaddedSize = sizeToUse + abs(aligned - offset);
298
299 return aligned;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000300}
301
302int
Chris Lattner955fad12002-12-28 20:37:16 +0000303MachineFunctionInfo::allocateLocalVar(const Value* val,
304 unsigned sizeToUse)
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000305{
Vikram S. Adve03d33bd2002-04-25 04:30:43 +0000306 assert(! automaticVarsAreaFrozen &&
307 "Size of auto vars area has been used to compute an offset so "
308 "no more automatic vars should be allocated!");
309
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000310 // Check if we've allocated a stack slot for this value already
311 //
312 int offset = getOffset(val);
313 if (offset == INVALID_FRAME_OFFSET)
314 {
Chris Lattner955fad12002-12-28 20:37:16 +0000315 unsigned getPaddedSize;
316 offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000317 offsets[val] = offset;
Vikram S. Advee4e4d4e2002-03-24 03:39:26 +0000318 incrementAutomaticVarsSize(getPaddedSize);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000319 }
320 return offset;
321}
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000322
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000323int
Chris Lattner955fad12002-12-28 20:37:16 +0000324MachineFunctionInfo::allocateSpilledValue(const Type* type)
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000325{
Vikram S. Adve03d33bd2002-04-25 04:30:43 +0000326 assert(! spillsAreaFrozen &&
327 "Size of reg spills area has been used to compute an offset so "
328 "no more register spill slots should be allocated!");
329
Chris Lattner955fad12002-12-28 20:37:16 +0000330 unsigned size = MF.getTarget().getTargetData().getTypeSize(type);
331 unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000332
333 bool growUp;
Chris Lattner955fad12002-12-28 20:37:16 +0000334 int firstOffset = MF.getTarget().getFrameInfo().getRegSpillAreaOffset(MF, growUp);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000335
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000336 int offset = growUp? firstOffset + getRegSpillsSize()
337 : firstOffset - (getRegSpillsSize() + size);
338
Chris Lattner955fad12002-12-28 20:37:16 +0000339 int aligned = MF.getTarget().getFrameInfo().adjustAlignment(offset, growUp, align);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000340 size += abs(aligned - offset); // include alignment padding in size
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000341
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000342 incrementRegSpillsSize(size); // update size of reg. spills area
343
344 return aligned;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000345}
346
347int
Chris Lattner955fad12002-12-28 20:37:16 +0000348MachineFunctionInfo::pushTempValue(unsigned size)
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000349{
Chris Lattner955fad12002-12-28 20:37:16 +0000350 unsigned align = SizeToAlignment(size, MF.getTarget());
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000351
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000352 bool growUp;
Chris Lattner955fad12002-12-28 20:37:16 +0000353 int firstOffset = MF.getTarget().getFrameInfo().getTmpAreaOffset(MF, growUp);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000354
355 int offset = growUp? firstOffset + currentTmpValuesSize
356 : firstOffset - (currentTmpValuesSize + size);
357
Chris Lattner955fad12002-12-28 20:37:16 +0000358 int aligned = MF.getTarget().getFrameInfo().adjustAlignment(offset, growUp,
359 align);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000360 size += abs(aligned - offset); // include alignment padding in size
361
362 incrementTmpAreaSize(size); // update "current" size of tmp area
363
364 return aligned;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000365}
366
Chris Lattner955fad12002-12-28 20:37:16 +0000367void MachineFunctionInfo::popAllTempValues() {
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000368 resetTmpAreaSize(); // clear tmp area to reuse
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000369}
370
371int
Chris Lattner955fad12002-12-28 20:37:16 +0000372MachineFunctionInfo::getOffset(const Value* val) const
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000373{
Chris Lattner09ff1122002-07-24 21:21:32 +0000374 hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
Chris Lattner6b944532002-10-28 01:16:38 +0000375 return (pair == offsets.end()) ? INVALID_FRAME_OFFSET : pair->second;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000376}