eb66aa00ec28ec9e1de14cb00a56eb294907d634
[oota-llvm.git] / lib / Target / SparcV9 / MachineFunctionInfo.cpp
1 //===-- 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"
21 using namespace llvm;
22
23 MachineFunctionInfo *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
32 static unsigned
33 ComputeMaxOptionalArgsSize(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 // 
68 inline unsigned
69 SizeToAlignment(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
81 void MachineFunctionInfo::CalculateArgSize() {
82   maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
83                                                    MF.getFunction(),
84                                                    maxOptionalNumArgs);
85   staticStackSize = maxOptionalArgsSize + 176;
86 }
87
88 int
89 MachineFunctionInfo::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
115 int 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
134 int
135 MachineFunctionInfo::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
158 int
159 MachineFunctionInfo::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
178 void MachineFunctionInfo::popAllTempValues() {
179   resetTmpAreaSize();            // clear tmp area to reuse
180 }