blob: eb66aa00ec28ec9e1de14cb00a56eb294907d634 [file] [log] [blame]
Chris Lattner2d19f782004-08-16 22:36:54 +00001//===-- MachineFunctionInfo.cpp -------------------------------------------===//
2//
3// 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//
10// This implements the SparcV9 specific MachineFunctionInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MachineFunctionInfo.h"
15#include "llvm/Instructions.h"
16#include "llvm/Function.h"
17#include "llvm/Type.h"
18#include "llvm/CodeGen/MachineFunction.h"
19#include "llvm/Target/TargetMachine.h"
20#include "llvm/Target/TargetFrameInfo.h"
21using namespace llvm;
22
23MachineFunctionInfo *MachineFunction::getInfo() const {
24 if (!MFInfo) {
25 MFInfo = new MachineFunctionInfo(*const_cast<MachineFunction*>(this));
26 }
27 return static_cast<MachineFunctionInfo*>(MFInfo);
28}
29
30
31
32static unsigned
33ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
34 unsigned &maxOptionalNumArgs)
35{
36 unsigned maxSize = 0;
37
38 for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB)
39 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
40 if (const CallInst *callInst = dyn_cast<CallInst>(I))
41 {
42 unsigned numOperands = callInst->getNumOperands() - 1;
43 int numExtra = numOperands-6;
44 if (numExtra <= 0)
45 continue;
46
47 unsigned sizeForThisCall = numExtra * 8;
48
49 if (maxSize < sizeForThisCall)
50 maxSize = sizeForThisCall;
51
52 if ((int)maxOptionalNumArgs < numExtra)
53 maxOptionalNumArgs = (unsigned) numExtra;
54 }
55
56 return maxSize;
57}
58
59// Align data larger than one L1 cache line on L1 cache line boundaries.
60// Align all smaller data on the next higher 2^x boundary (4, 8, ...),
61// but not higher than the alignment of the largest type we support
62// (currently a double word). -- see class TargetData).
63//
64// This function is similar to the corresponding function in EmitAssembly.cpp
65// but they are unrelated. This one does not align at more than a
66// double-word boundary whereas that one might.
67//
68inline unsigned
69SizeToAlignment(unsigned size, const TargetMachine& target)
70{
71 const unsigned short cacheLineSize = 16;
72 if (size > (unsigned) cacheLineSize / 2)
73 return cacheLineSize;
74 else
75 for (unsigned sz=1; /*no condition*/; sz *= 2)
76 if (sz >= size || sz >= target.getTargetData().getDoubleAlignment())
77 return sz;
78}
79
80
81void MachineFunctionInfo::CalculateArgSize() {
82 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
83 MF.getFunction(),
84 maxOptionalNumArgs);
85 staticStackSize = maxOptionalArgsSize + 176;
86}
87
88int
89MachineFunctionInfo::computeOffsetforLocalVar(const Value* val,
90 unsigned &getPaddedSize,
91 unsigned sizeToUse)
92{
93 if (sizeToUse == 0) {
94 // All integer types smaller than ints promote to 4 byte integers.
95 if (val->getType()->isIntegral() && val->getType()->getPrimitiveSize() < 4)
96 sizeToUse = 4;
97 else
98 sizeToUse = MF.getTarget().getTargetData().getTypeSize(val->getType());
99 }
100 unsigned align = SizeToAlignment(sizeToUse, MF.getTarget());
101
102 bool growUp;
103 int firstOffset = MF.getTarget().getFrameInfo()->getFirstAutomaticVarOffset(MF,
104 growUp);
105 int offset = growUp? firstOffset + getAutomaticVarsSize()
106 : firstOffset - (getAutomaticVarsSize() + sizeToUse);
107
108 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
109 getPaddedSize = sizeToUse + abs(aligned - offset);
110
111 return aligned;
112}
113
114
115int MachineFunctionInfo::allocateLocalVar(const Value* val,
116 unsigned sizeToUse) {
117 assert(! automaticVarsAreaFrozen &&
118 "Size of auto vars area has been used to compute an offset so "
119 "no more automatic vars should be allocated!");
120
121 // Check if we've allocated a stack slot for this value already
122 //
123 hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
124 if (pair != offsets.end())
125 return pair->second;
126
127 unsigned getPaddedSize;
128 unsigned offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse);
129 offsets[val] = offset;
130 incrementAutomaticVarsSize(getPaddedSize);
131 return offset;
132}
133
134int
135MachineFunctionInfo::allocateSpilledValue(const Type* type)
136{
137 assert(! spillsAreaFrozen &&
138 "Size of reg spills area has been used to compute an offset so "
139 "no more register spill slots should be allocated!");
140
141 unsigned size = MF.getTarget().getTargetData().getTypeSize(type);
142 unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type);
143
144 bool growUp;
145 int firstOffset = MF.getTarget().getFrameInfo()->getRegSpillAreaOffset(MF, growUp);
146
147 int offset = growUp? firstOffset + getRegSpillsSize()
148 : firstOffset - (getRegSpillsSize() + size);
149
150 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
151 size += abs(aligned - offset); // include alignment padding in size
152
153 incrementRegSpillsSize(size); // update size of reg. spills area
154
155 return aligned;
156}
157
158int
159MachineFunctionInfo::pushTempValue(unsigned size)
160{
161 unsigned align = SizeToAlignment(size, MF.getTarget());
162
163 bool growUp;
164 int firstOffset = MF.getTarget().getFrameInfo()->getTmpAreaOffset(MF, growUp);
165
166 int offset = growUp? firstOffset + currentTmpValuesSize
167 : firstOffset - (currentTmpValuesSize + size);
168
169 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp,
170 align);
171 size += abs(aligned - offset); // include alignment padding in size
172
173 incrementTmpAreaSize(size); // update "current" size of tmp area
174
175 return aligned;
176}
177
178void MachineFunctionInfo::popAllTempValues() {
179 resetTmpAreaSize(); // clear tmp area to reuse
180}