1 //===-- SparcV9FunctionInfo.cpp -------------------------------------------===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This implements the SparcV9 specific MachineFunctionInfo class.
12 //===----------------------------------------------------------------------===//
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"
24 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
25 unsigned &maxOptionalNumArgs)
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))
33 unsigned numOperands = callInst->getNumOperands() - 1;
34 int numExtra = numOperands-6;
38 unsigned sizeForThisCall = numExtra * 8;
40 if (maxSize < sizeForThisCall)
41 maxSize = sizeForThisCall;
43 if ((int)maxOptionalNumArgs < numExtra)
44 maxOptionalNumArgs = (unsigned) numExtra;
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).
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.
60 SizeToAlignment(unsigned size, const TargetMachine& target)
62 const unsigned short cacheLineSize = 16;
63 if (size > (unsigned) cacheLineSize / 2)
66 for (unsigned sz=1; /*no condition*/; sz *= 2)
67 if (sz >= size || sz >= target.getTargetData().getDoubleAlignment())
72 void SparcV9FunctionInfo::CalculateArgSize() {
73 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
76 staticStackSize = maxOptionalArgsSize + 176;
80 SparcV9FunctionInfo::computeOffsetforLocalVar(const Value* val,
81 unsigned &getPaddedSize,
85 // All integer types smaller than ints promote to 4 byte integers.
86 if (val->getType()->isIntegral() && val->getType()->getPrimitiveSize() < 4)
89 sizeToUse = MF.getTarget().getTargetData().getTypeSize(val->getType());
91 unsigned align = SizeToAlignment(sizeToUse, MF.getTarget());
94 int firstOffset = MF.getTarget().getFrameInfo()->getFirstAutomaticVarOffset(MF,
96 int offset = growUp? firstOffset + getAutomaticVarsSize()
97 : firstOffset - (getAutomaticVarsSize() + sizeToUse);
99 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
100 getPaddedSize = sizeToUse + abs(aligned - offset);
106 int SparcV9FunctionInfo::allocateLocalVar(const Value* val,
107 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!");
112 // Check if we've allocated a stack slot for this value already
114 hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
115 if (pair != offsets.end())
118 unsigned getPaddedSize;
119 unsigned offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse);
120 offsets[val] = offset;
121 incrementAutomaticVarsSize(getPaddedSize);
126 SparcV9FunctionInfo::allocateSpilledValue(const Type* type)
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!");
132 unsigned size = MF.getTarget().getTargetData().getTypeSize(type);
133 unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type);
136 int firstOffset = MF.getTarget().getFrameInfo()->getRegSpillAreaOffset(MF, growUp);
138 int offset = growUp? firstOffset + getRegSpillsSize()
139 : firstOffset - (getRegSpillsSize() + size);
141 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
142 size += abs(aligned - offset); // include alignment padding in size
144 incrementRegSpillsSize(size); // update size of reg. spills area
150 SparcV9FunctionInfo::pushTempValue(unsigned size)
152 unsigned align = SizeToAlignment(size, MF.getTarget());
155 int firstOffset = MF.getTarget().getFrameInfo()->getTmpAreaOffset(MF, growUp);
157 int offset = growUp? firstOffset + currentTmpValuesSize
158 : firstOffset - (currentTmpValuesSize + size);
160 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp,
162 size += abs(aligned - offset); // include alignment padding in size
164 incrementTmpAreaSize(size); // update "current" size of tmp area
169 void SparcV9FunctionInfo::popAllTempValues() {
170 resetTmpAreaSize(); // clear tmp area to reuse