Chris Lattner | a1e51ff | 2004-08-18 18:13:37 +0000 | [diff] [blame] | 1 | //===-- SparcV9FunctionInfo.cpp -------------------------------------------===// |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 2 | // |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 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. |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 7 | // |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 9 | // |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 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 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 23 | static unsigned |
| 24 | ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F, |
| 25 | unsigned &maxOptionalNumArgs) |
| 26 | { |
| 27 | unsigned maxSize = 0; |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 28 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 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; |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 37 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 38 | unsigned sizeForThisCall = numExtra * 8; |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 39 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 40 | if (maxSize < sizeForThisCall) |
| 41 | maxSize = sizeForThisCall; |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 42 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 43 | if ((int)maxOptionalNumArgs < numExtra) |
| 44 | maxOptionalNumArgs = (unsigned) numExtra; |
| 45 | } |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 46 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 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. |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 58 | // |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 59 | inline unsigned |
| 60 | SizeToAlignment(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 Lattner | a1e51ff | 2004-08-18 18:13:37 +0000 | [diff] [blame] | 72 | void SparcV9FunctionInfo::CalculateArgSize() { |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 73 | maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(), |
| 74 | MF.getFunction(), |
| 75 | maxOptionalNumArgs); |
| 76 | staticStackSize = maxOptionalArgsSize + 176; |
| 77 | } |
| 78 | |
| 79 | int |
Chris Lattner | a1e51ff | 2004-08-18 18:13:37 +0000 | [diff] [blame] | 80 | SparcV9FunctionInfo::computeOffsetforLocalVar(const Value* val, |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 81 | 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 Lattner | a1e51ff | 2004-08-18 18:13:37 +0000 | [diff] [blame] | 106 | int SparcV9FunctionInfo::allocateLocalVar(const Value* val, |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 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!"); |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 111 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 112 | // Check if we've allocated a stack slot for this value already |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 113 | // |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 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 | |
| 125 | int |
Chris Lattner | a1e51ff | 2004-08-18 18:13:37 +0000 | [diff] [blame] | 126 | SparcV9FunctionInfo::allocateSpilledValue(const Type* type) |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 127 | { |
| 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!"); |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 131 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 132 | unsigned size = MF.getTarget().getTargetData().getTypeSize(type); |
| 133 | unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type); |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 134 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 135 | bool growUp; |
| 136 | int firstOffset = MF.getTarget().getFrameInfo()->getRegSpillAreaOffset(MF, growUp); |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 137 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 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 |
Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame^] | 143 | |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 144 | incrementRegSpillsSize(size); // update size of reg. spills area |
| 145 | |
| 146 | return aligned; |
| 147 | } |
| 148 | |
| 149 | int |
Chris Lattner | a1e51ff | 2004-08-18 18:13:37 +0000 | [diff] [blame] | 150 | SparcV9FunctionInfo::pushTempValue(unsigned size) |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 151 | { |
| 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 Lattner | a1e51ff | 2004-08-18 18:13:37 +0000 | [diff] [blame] | 169 | void SparcV9FunctionInfo::popAllTempValues() { |
Chris Lattner | 2d19f78 | 2004-08-16 22:36:54 +0000 | [diff] [blame] | 170 | resetTmpAreaSize(); // clear tmp area to reuse |
| 171 | } |