blob: 63785a301b97018d1bc136e3bf1db242dc3ed457 [file] [log] [blame]
Chris Lattner6b944532002-10-28 01:16:38 +00001//===-- MachineFunction.cpp -----------------------------------------------===//
Chris Lattnerf2868ce2002-02-03 07:54:50 +00002//
John Criswellb576c942003-10-20 19:43:21 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Chris Lattner6b944532002-10-28 01:16:38 +000010// Collect native machine code information for a function. This allows
11// target-specific information about the generated code to be stored with each
12// function.
13//
14//===----------------------------------------------------------------------===//
Chris Lattnerf2868ce2002-02-03 07:54:50 +000015
Chris Lattner16c45e92003-12-20 10:20:58 +000016#include "llvm/CodeGen/MachineFunctionPass.h"
Chris Lattner831fdcf2002-12-25 05:03:22 +000017#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner831fdcf2002-12-25 05:03:22 +000018#include "llvm/CodeGen/SSARegMap.h"
Chris Lattner955fad12002-12-28 20:37:16 +000019#include "llvm/CodeGen/MachineFunctionInfo.h"
Chris Lattnereb24db92002-12-28 21:08:26 +000020#include "llvm/CodeGen/MachineFrameInfo.h"
Chris Lattner4d149cd2003-01-13 00:23:03 +000021#include "llvm/CodeGen/MachineConstantPool.h"
Chris Lattner16c45e92003-12-20 10:20:58 +000022#include "llvm/CodeGen/Passes.h"
Chris Lattnerf2868ce2002-02-03 07:54:50 +000023#include "llvm/Target/TargetMachine.h"
Chris Lattner8bd66e62002-12-28 21:00:25 +000024#include "llvm/Target/TargetFrameInfo.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000025#include "llvm/Function.h"
Chris Lattnerf2868ce2002-02-03 07:54:50 +000026#include "llvm/iOther.h"
Chris Lattner62d6ad22004-06-02 05:56:52 +000027#include "llvm/Type.h"
Tanya Lattner792699c2004-05-24 06:11:51 +000028#include "Support/LeakDetector.h"
Alkis Evlogimenos71bf4042004-07-08 00:47:58 +000029#include "Support/GraphWriter.h"
30#include <fstream>
Reid Spencer954da372004-07-04 12:19:56 +000031#include <iostream>
Alkis Evlogimenos71bf4042004-07-08 00:47:58 +000032#include <sstream>
Tanya Lattner792699c2004-05-24 06:11:51 +000033
Chris Lattner07f32d42003-12-20 09:17:07 +000034using namespace llvm;
Chris Lattnerf2868ce2002-02-03 07:54:50 +000035
Chris Lattnere316efc2002-10-29 23:18:43 +000036static AnnotationID MF_AID(
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000037 AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
Chris Lattnerf2868ce2002-02-03 07:54:50 +000038
Chris Lattner227c3d32002-10-28 01:12:41 +000039
Chris Lattner227c3d32002-10-28 01:12:41 +000040namespace {
Chris Lattner16c45e92003-12-20 10:20:58 +000041 struct Printer : public MachineFunctionPass {
Brian Gaeke09caa372004-01-30 21:53:46 +000042 std::ostream *OS;
Chris Lattnerd4baf0f2004-02-01 05:25:07 +000043 const std::string Banner;
Brian Gaeke09caa372004-01-30 21:53:46 +000044
45 Printer (std::ostream *_OS, const std::string &_Banner) :
46 OS (_OS), Banner (_Banner) { }
47
Chris Lattner10491642002-10-30 00:48:05 +000048 const char *getPassName() const { return "MachineFunction Printer"; }
49
50 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
51 AU.setPreservesAll();
52 }
53
Chris Lattner16c45e92003-12-20 10:20:58 +000054 bool runOnMachineFunction(MachineFunction &MF) {
Brian Gaeke09caa372004-01-30 21:53:46 +000055 (*OS) << Banner;
56 MF.print (*OS);
Chris Lattner10491642002-10-30 00:48:05 +000057 return false;
58 }
59 };
Chris Lattner227c3d32002-10-28 01:12:41 +000060}
61
Brian Gaeke09caa372004-01-30 21:53:46 +000062/// Returns a newly-created MachineFunction Printer pass. The default output
63/// stream is std::cerr; the default banner is empty.
64///
65FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS,
66 const std::string &Banner) {
67 return new Printer(OS, Banner);
Chris Lattner10491642002-10-30 00:48:05 +000068}
69
Alkis Evlogimenosc81efdc2004-02-15 00:03:15 +000070namespace {
71 struct Deleter : public MachineFunctionPass {
72 const char *getPassName() const { return "Machine Code Deleter"; }
73
74 bool runOnMachineFunction(MachineFunction &MF) {
75 // Delete the annotation from the function now.
76 MachineFunction::destruct(MF.getFunction());
77 return true;
78 }
79 };
80}
81
82/// MachineCodeDeletion Pass - This pass deletes all of the machine code for
83/// the current function, which should happen after the function has been
84/// emitted to a .s file or to memory.
85FunctionPass *llvm::createMachineCodeDeleter() {
86 return new Deleter();
87}
88
89
90
Chris Lattner227c3d32002-10-28 01:12:41 +000091//===---------------------------------------------------------------------===//
92// MachineFunction implementation
93//===---------------------------------------------------------------------===//
Tanya Lattner792699c2004-05-24 06:11:51 +000094MachineBasicBlock* ilist_traits<MachineBasicBlock>::createNode()
95{
96 MachineBasicBlock* dummy = new MachineBasicBlock();
97 LeakDetector::removeGarbageObject(dummy);
98 return dummy;
99}
100
101void ilist_traits<MachineBasicBlock>::transferNodesFromList(
102 iplist<MachineBasicBlock, ilist_traits<MachineBasicBlock> >& toList,
103 ilist_iterator<MachineBasicBlock> first,
104 ilist_iterator<MachineBasicBlock> last)
105{
Tanya Lattner17fb34b2004-05-24 07:14:35 +0000106 if (Parent != toList.Parent)
Tanya Lattner792699c2004-05-24 06:11:51 +0000107 for (; first != last; ++first)
Tanya Lattner17fb34b2004-05-24 07:14:35 +0000108 first->Parent = toList.Parent;
Tanya Lattner792699c2004-05-24 06:11:51 +0000109}
Chris Lattner227c3d32002-10-28 01:12:41 +0000110
Chris Lattner10491642002-10-30 00:48:05 +0000111MachineFunction::MachineFunction(const Function *F,
Chris Lattner955fad12002-12-28 20:37:16 +0000112 const TargetMachine &TM)
Chris Lattner51289aa2004-07-01 06:02:07 +0000113 : Annotation(MF_AID), Fn(F), Target(TM) {
Misha Brukmanb7825bc2002-11-20 18:55:27 +0000114 SSARegMapping = new SSARegMap();
Chris Lattner955fad12002-12-28 20:37:16 +0000115 MFInfo = new MachineFunctionInfo(*this);
Chris Lattnereb24db92002-12-28 21:08:26 +0000116 FrameInfo = new MachineFrameInfo();
Chris Lattner4d149cd2003-01-13 00:23:03 +0000117 ConstantPool = new MachineConstantPool();
Tanya Lattner17fb34b2004-05-24 07:14:35 +0000118 BasicBlocks.Parent = this;
Chris Lattner831fdcf2002-12-25 05:03:22 +0000119}
120
121MachineFunction::~MachineFunction() {
Chris Lattner4b9a4002004-07-01 06:29:07 +0000122 BasicBlocks.clear();
Chris Lattner831fdcf2002-12-25 05:03:22 +0000123 delete SSARegMapping;
Chris Lattner955fad12002-12-28 20:37:16 +0000124 delete MFInfo;
125 delete FrameInfo;
Chris Lattner4d149cd2003-01-13 00:23:03 +0000126 delete ConstantPool;
Chris Lattner10491642002-10-30 00:48:05 +0000127}
128
129void MachineFunction::dump() const { print(std::cerr); }
130
131void MachineFunction::print(std::ostream &OS) const {
Brian Gaeke47b71642004-03-29 21:58:31 +0000132 OS << "# Machine code for " << Fn->getName () << "():\n";
Chris Lattner955fad12002-12-28 20:37:16 +0000133
134 // Print Frame Information
Chris Lattner9085d8a2003-01-16 18:35:57 +0000135 getFrameInfo()->print(*this, OS);
Chris Lattner4d149cd2003-01-13 00:23:03 +0000136
137 // Print Constant Pool
138 getConstantPool()->print(OS);
Chris Lattner10491642002-10-30 00:48:05 +0000139
Brian Gaeke90421cd2004-02-13 04:39:55 +0000140 for (const_iterator BB = begin(); BB != end(); ++BB)
141 BB->print(OS);
Brian Gaeke47b71642004-03-29 21:58:31 +0000142
143 OS << "\n# End machine code for " << Fn->getName () << "().\n\n";
Chris Lattner10491642002-10-30 00:48:05 +0000144}
145
Alkis Evlogimenos71bf4042004-07-08 00:47:58 +0000146/// CFGOnly flag - This is used to control whether or not the CFG graph printer
147/// prints out the contents of basic blocks or not. This is acceptable because
148/// this code is only really used for debugging purposes.
149///
150static bool CFGOnly = false;
151
152namespace llvm {
153template<>
154struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
155 static std::string getGraphName(const MachineFunction *F) {
156 return "CFG for '" + F->getFunction()->getName() + "' function";
157 }
158
159 static std::string getNodeLabel(const MachineBasicBlock *Node,
160 const MachineFunction *Graph) {
161 if (CFGOnly && Node->getBasicBlock() &&
162 !Node->getBasicBlock()->getName().empty())
163 return Node->getBasicBlock()->getName() + ":";
164
165 std::ostringstream Out;
166 if (CFGOnly) {
167 Out << Node->getNumber() << ':';
168 return Out.str();
169 }
170
171 Node->print(Out);
172
173 std::string OutStr = Out.str();
174 if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
175
176 // Process string output to make it nicer...
177 for (unsigned i = 0; i != OutStr.length(); ++i)
178 if (OutStr[i] == '\n') { // Left justify
179 OutStr[i] = '\\';
180 OutStr.insert(OutStr.begin()+i+1, 'l');
181 }
182 return OutStr;
183 }
184};
185}
186
187void MachineFunction::viewCFG() const
188{
189 std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot";
190 std::cerr << "Writing '" << Filename << "'... ";
191 std::ofstream F(Filename.c_str());
192
193 if (!F) {
194 std::cerr << " error opening file for writing!\n";
195 return;
196 }
197
198 WriteGraph(F, this);
199 F.close();
200 std::cerr << "\n";
201
202 std::cerr << "Running 'dot' program... " << std::flush;
203 if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename
204 + " > /tmp/cfg.tempgraph.ps").c_str())) {
205 std::cerr << "Error running dot: 'dot' not in path?\n";
206 } else {
207 std::cerr << "\n";
208 system("gv /tmp/cfg.tempgraph.ps");
209 }
210 system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str());
211}
212
213void MachineFunction::viewCFGOnly() const
214{
215 CFGOnly = true;
216 viewCFG();
217 CFGOnly = false;
218}
219
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000220// The next two methods are used to construct and to retrieve
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000221// the MachineCodeForFunction object for the given function.
222// construct() -- Allocates and initializes for a given function and target
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000223// get() -- Returns a handle to the object.
224// This should not be called before "construct()"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000225// for a given Function.
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000226//
Misha Brukmanfce11432002-10-28 00:28:31 +0000227MachineFunction&
Chris Lattner335d5c32002-10-28 05:58:46 +0000228MachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000229{
Chris Lattnere316efc2002-10-29 23:18:43 +0000230 assert(Fn->getAnnotation(MF_AID) == 0 &&
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000231 "Object already exists for this function!");
Chris Lattner335d5c32002-10-28 05:58:46 +0000232 MachineFunction* mcInfo = new MachineFunction(Fn, Tar);
233 Fn->addAnnotation(mcInfo);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000234 return *mcInfo;
235}
236
Chris Lattner16c45e92003-12-20 10:20:58 +0000237void MachineFunction::destruct(const Function *Fn) {
Chris Lattnere316efc2002-10-29 23:18:43 +0000238 bool Deleted = Fn->deleteAnnotation(MF_AID);
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000239 assert(Deleted && "Machine code did not exist for function!");
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000240}
241
Chris Lattner335d5c32002-10-28 05:58:46 +0000242MachineFunction& MachineFunction::get(const Function *F)
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000243{
Chris Lattnere316efc2002-10-29 23:18:43 +0000244 MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000245 assert(mc && "Call construct() method first to allocate the object");
246 return *mc;
247}
248
Chris Lattner831fdcf2002-12-25 05:03:22 +0000249void MachineFunction::clearSSARegMap() {
250 delete SSARegMapping;
251 SSARegMapping = 0;
252}
253
Chris Lattner955fad12002-12-28 20:37:16 +0000254//===----------------------------------------------------------------------===//
Chris Lattnereb24db92002-12-28 21:08:26 +0000255// MachineFrameInfo implementation
Chris Lattner955fad12002-12-28 20:37:16 +0000256//===----------------------------------------------------------------------===//
257
Chris Lattner4d149cd2003-01-13 00:23:03 +0000258/// CreateStackObject - Create a stack object for a value of the specified type.
259///
260int MachineFrameInfo::CreateStackObject(const Type *Ty, const TargetData &TD) {
261 return CreateStackObject(TD.getTypeSize(Ty), TD.getTypeAlignment(Ty));
262}
263
264int MachineFrameInfo::CreateStackObject(const TargetRegisterClass *RC) {
265 return CreateStackObject(RC->getSize(), RC->getAlignment());
266}
267
268
Chris Lattner9085d8a2003-01-16 18:35:57 +0000269void MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{
Chris Lattner62d6ad22004-06-02 05:56:52 +0000270 int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea();
Chris Lattner9085d8a2003-01-16 18:35:57 +0000271
Chris Lattner955fad12002-12-28 20:37:16 +0000272 for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
273 const StackObject &SO = Objects[i];
Chris Lattner4d149cd2003-01-13 00:23:03 +0000274 OS << " <fi #" << (int)(i-NumFixedObjects) << "> is ";
Chris Lattner955fad12002-12-28 20:37:16 +0000275 if (SO.Size == 0)
276 OS << "variable sized";
277 else
278 OS << SO.Size << " byte" << (SO.Size != 1 ? "s" : " ");
279
280 if (i < NumFixedObjects)
281 OS << " fixed";
282 if (i < NumFixedObjects || SO.SPOffset != -1) {
Chris Lattner7f7bbc22004-06-11 06:37:11 +0000283 int Off = SO.SPOffset - ValOffset;
Chris Lattner955fad12002-12-28 20:37:16 +0000284 OS << " at location [SP";
Chris Lattner9085d8a2003-01-16 18:35:57 +0000285 if (Off > 0)
286 OS << "+" << Off;
287 else if (Off < 0)
288 OS << Off;
Chris Lattner955fad12002-12-28 20:37:16 +0000289 OS << "]";
290 }
291 OS << "\n";
292 }
293
294 if (HasVarSizedObjects)
295 OS << " Stack frame contains variable sized objects\n";
296}
297
Chris Lattner9085d8a2003-01-16 18:35:57 +0000298void MachineFrameInfo::dump(const MachineFunction &MF) const {
299 print(MF, std::cerr);
300}
Chris Lattner955fad12002-12-28 20:37:16 +0000301
302
303//===----------------------------------------------------------------------===//
Chris Lattner4d149cd2003-01-13 00:23:03 +0000304// MachineConstantPool implementation
305//===----------------------------------------------------------------------===//
306
307void MachineConstantPool::print(std::ostream &OS) const {
308 for (unsigned i = 0, e = Constants.size(); i != e; ++i)
309 OS << " <cp #" << i << "> is" << *(Value*)Constants[i] << "\n";
310}
311
312void MachineConstantPool::dump() const { print(std::cerr); }
313
314//===----------------------------------------------------------------------===//
Chris Lattner955fad12002-12-28 20:37:16 +0000315// MachineFunctionInfo implementation
316//===----------------------------------------------------------------------===//
Chris Lattner831fdcf2002-12-25 05:03:22 +0000317
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000318static unsigned
Vikram S. Adve03d33bd2002-04-25 04:30:43 +0000319ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
320 unsigned &maxOptionalNumArgs)
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000321{
Chris Lattner62d6ad22004-06-02 05:56:52 +0000322 const TargetFrameInfo &frameInfo = *target.getFrameInfo();
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000323
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000324 unsigned maxSize = 0;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000325
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000326 for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB)
327 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
Chris Lattner2ee82e02003-04-23 16:36:11 +0000328 if (const CallInst *callInst = dyn_cast<CallInst>(I))
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000329 {
330 unsigned numOperands = callInst->getNumOperands() - 1;
331 int numExtra = (int)numOperands-frameInfo.getNumFixedOutgoingArgs();
332 if (numExtra <= 0)
333 continue;
334
Chris Lattner955fad12002-12-28 20:37:16 +0000335 unsigned sizeForThisCall;
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000336 if (frameInfo.argsOnStackHaveFixedSize())
337 {
338 int argSize = frameInfo.getSizeOfEachArgOnStack();
339 sizeForThisCall = numExtra * (unsigned) argSize;
340 }
341 else
342 {
343 assert(0 && "UNTESTED CODE: Size per stack argument is not "
344 "fixed on this architecture: use actual arg sizes to "
345 "compute MaxOptionalArgsSize");
346 sizeForThisCall = 0;
347 for (unsigned i = 0; i < numOperands; ++i)
Chris Lattner955fad12002-12-28 20:37:16 +0000348 sizeForThisCall += target.getTargetData().getTypeSize(callInst->
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000349 getOperand(i)->getType());
350 }
351
352 if (maxSize < sizeForThisCall)
353 maxSize = sizeForThisCall;
354
355 if ((int)maxOptionalNumArgs < numExtra)
356 maxOptionalNumArgs = (unsigned) numExtra;
357 }
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000358
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000359 return maxSize;
360}
361
362// Align data larger than one L1 cache line on L1 cache line boundaries.
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000363// Align all smaller data on the next higher 2^x boundary (4, 8, ...),
364// but not higher than the alignment of the largest type we support
365// (currently a double word). -- see class TargetData).
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000366//
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000367// This function is similar to the corresponding function in EmitAssembly.cpp
368// but they are unrelated. This one does not align at more than a
369// double-word boundary whereas that one might.
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000370//
Chris Lattner955fad12002-12-28 20:37:16 +0000371inline unsigned
372SizeToAlignment(unsigned size, const TargetMachine& target)
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000373{
Brian Gaeke05b15fb2004-03-01 06:43:29 +0000374 const unsigned short cacheLineSize = 16;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000375 if (size > (unsigned) cacheLineSize / 2)
376 return cacheLineSize;
377 else
378 for (unsigned sz=1; /*no condition*/; sz *= 2)
Chris Lattner955fad12002-12-28 20:37:16 +0000379 if (sz >= size || sz >= target.getTargetData().getDoubleAlignment())
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000380 return sz;
381}
382
383
Chris Lattner955fad12002-12-28 20:37:16 +0000384void MachineFunctionInfo::CalculateArgSize() {
385 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
386 MF.getFunction(),
Vikram S. Adve03d33bd2002-04-25 04:30:43 +0000387 maxOptionalNumArgs);
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000388 staticStackSize = maxOptionalArgsSize
Chris Lattner62d6ad22004-06-02 05:56:52 +0000389 + MF.getTarget().getFrameInfo()->getMinStackFrameSize();
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000390}
391
392int
Chris Lattner955fad12002-12-28 20:37:16 +0000393MachineFunctionInfo::computeOffsetforLocalVar(const Value* val,
394 unsigned &getPaddedSize,
395 unsigned sizeToUse)
Vikram S. Adve89e2da02002-03-18 03:36:30 +0000396{
Chris Lattner62d6ad22004-06-02 05:56:52 +0000397 if (sizeToUse == 0) {
398 // All integer types smaller than ints promote to 4 byte integers.
399 if (val->getType()->isIntegral() && val->getType()->getPrimitiveSize() < 4)
400 sizeToUse = 4;
401 else
402 sizeToUse = MF.getTarget().getTargetData().getTypeSize(val->getType());
403 }
Chris Lattner955fad12002-12-28 20:37:16 +0000404 unsigned align = SizeToAlignment(sizeToUse, MF.getTarget());
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000405
406 bool growUp;
Chris Lattner62d6ad22004-06-02 05:56:52 +0000407 int firstOffset = MF.getTarget().getFrameInfo()->getFirstAutomaticVarOffset(MF,
408 growUp);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000409 int offset = growUp? firstOffset + getAutomaticVarsSize()
410 : firstOffset - (getAutomaticVarsSize() + sizeToUse);
411
Chris Lattner62d6ad22004-06-02 05:56:52 +0000412 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000413 getPaddedSize = sizeToUse + abs(aligned - offset);
414
415 return aligned;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000416}
417
Chris Lattner07f32d42003-12-20 09:17:07 +0000418
419int MachineFunctionInfo::allocateLocalVar(const Value* val,
420 unsigned sizeToUse) {
Vikram S. Adve03d33bd2002-04-25 04:30:43 +0000421 assert(! automaticVarsAreaFrozen &&
422 "Size of auto vars area has been used to compute an offset so "
423 "no more automatic vars should be allocated!");
424
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000425 // Check if we've allocated a stack slot for this value already
426 //
Chris Lattner07f32d42003-12-20 09:17:07 +0000427 hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
428 if (pair != offsets.end())
429 return pair->second;
430
431 unsigned getPaddedSize;
432 unsigned offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse);
433 offsets[val] = offset;
434 incrementAutomaticVarsSize(getPaddedSize);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000435 return offset;
436}
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000437
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000438int
Chris Lattner955fad12002-12-28 20:37:16 +0000439MachineFunctionInfo::allocateSpilledValue(const Type* type)
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000440{
Vikram S. Adve03d33bd2002-04-25 04:30:43 +0000441 assert(! spillsAreaFrozen &&
442 "Size of reg spills area has been used to compute an offset so "
443 "no more register spill slots should be allocated!");
444
Chris Lattner955fad12002-12-28 20:37:16 +0000445 unsigned size = MF.getTarget().getTargetData().getTypeSize(type);
446 unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000447
448 bool growUp;
Chris Lattner62d6ad22004-06-02 05:56:52 +0000449 int firstOffset = MF.getTarget().getFrameInfo()->getRegSpillAreaOffset(MF, growUp);
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000450
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000451 int offset = growUp? firstOffset + getRegSpillsSize()
452 : firstOffset - (getRegSpillsSize() + size);
453
Chris Lattner62d6ad22004-06-02 05:56:52 +0000454 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000455 size += abs(aligned - offset); // include alignment padding in size
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000456
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000457 incrementRegSpillsSize(size); // update size of reg. spills area
458
459 return aligned;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000460}
461
462int
Chris Lattner955fad12002-12-28 20:37:16 +0000463MachineFunctionInfo::pushTempValue(unsigned size)
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000464{
Chris Lattner955fad12002-12-28 20:37:16 +0000465 unsigned align = SizeToAlignment(size, MF.getTarget());
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000466
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000467 bool growUp;
Chris Lattner62d6ad22004-06-02 05:56:52 +0000468 int firstOffset = MF.getTarget().getFrameInfo()->getTmpAreaOffset(MF, growUp);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000469
470 int offset = growUp? firstOffset + currentTmpValuesSize
471 : firstOffset - (currentTmpValuesSize + size);
472
Chris Lattner62d6ad22004-06-02 05:56:52 +0000473 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp,
Chris Lattner955fad12002-12-28 20:37:16 +0000474 align);
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000475 size += abs(aligned - offset); // include alignment padding in size
476
477 incrementTmpAreaSize(size); // update "current" size of tmp area
478
479 return aligned;
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000480}
481
Chris Lattner955fad12002-12-28 20:37:16 +0000482void MachineFunctionInfo::popAllTempValues() {
Vikram S. Adve1318bed2002-09-16 15:18:16 +0000483 resetTmpAreaSize(); // clear tmp area to reuse
Chris Lattnerf2868ce2002-02-03 07:54:50 +0000484}