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