MachineFunction.cpp revision 221d688a5ef21a22c2368c9fff0e92d7966c95e5
1//===-- MachineCodeForMethod.cpp --------------------------------------------=// 2// 3// Purpose: 4// Collect native machine code information for a method. 5// This allows target-specific information about the generated code 6// to be stored with each method. 7//===----------------------------------------------------------------------===// 8 9#include "llvm/CodeGen/MachineCodeForMethod.h" 10#include "llvm/CodeGen/MachineInstr.h" // For debug output 11#include "llvm/Target/TargetMachine.h" 12#include "llvm/Target/MachineFrameInfo.h" 13#include "llvm/Target/MachineCacheInfo.h" 14#include "llvm/Method.h" 15#include "llvm/BasicBlock.h" 16#include "llvm/iOther.h" 17#include <limits.h> 18 19const int INVALID_FRAME_OFFSET = INT_MAX; // std::numeric_limits<int>::max(); 20 21static AnnotationID MCFM_AID( 22 AnnotationManager::getID("CodeGen::MachineCodeForMethod")); 23 24// The next two methods are used to construct and to retrieve 25// the MachineCodeForMethod object for the given method. 26// construct() -- Allocates and initializes for a given method and target 27// get() -- Returns a handle to the object. 28// This should not be called before "construct()" 29// for a given Method. 30// 31MachineCodeForMethod &MachineCodeForMethod::construct(const Method *M, 32 const TargetMachine &Tar){ 33 assert(M->getAnnotation(MCFM_AID) == 0 && 34 "Object already exists for this method!"); 35 MachineCodeForMethod* mcInfo = new MachineCodeForMethod(M, Tar); 36 M->addAnnotation(mcInfo); 37 return *mcInfo; 38} 39 40void MachineCodeForMethod::destruct(const Method *M) { 41 bool Deleted = M->deleteAnnotation(MCFM_AID); 42 assert(Deleted && "Machine code did not exist for method!"); 43} 44 45 46MachineCodeForMethod &MachineCodeForMethod::get(const Method* method) { 47 MachineCodeForMethod* mc = (MachineCodeForMethod*) 48 method->getAnnotation(MCFM_AID); 49 assert(mc && "Call construct() method first to allocate the object"); 50 return *mc; 51} 52 53static unsigned 54ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method) 55{ 56 const MachineFrameInfo& frameInfo = target.getFrameInfo(); 57 58 unsigned int maxSize = 0; 59 60 for (Method::const_iterator MI=method->begin(), ME=method->end(); 61 MI != ME; ++MI) { 62 const BasicBlock *BB = *MI; 63 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) 64 if (CallInst *callInst = dyn_cast<CallInst>(*I)) { 65 unsigned int numOperands = callInst->getNumOperands() - 1; 66 int numExtra = (int) numOperands - frameInfo.getNumFixedOutgoingArgs(); 67 if (numExtra <= 0) 68 continue; 69 70 unsigned int sizeForThisCall; 71 if (frameInfo.argsOnStackHaveFixedSize()) 72 { 73 int argSize = frameInfo.getSizeOfEachArgOnStack(); 74 sizeForThisCall = numExtra * (unsigned) argSize; 75 } 76 else 77 { 78 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize"); 79 sizeForThisCall = 0; 80 for (unsigned i=0; i < numOperands; ++i) 81 sizeForThisCall += target.findOptimalStorageSize(callInst-> 82 getOperand(i)->getType()); 83 } 84 85 if (maxSize < sizeForThisCall) 86 maxSize = sizeForThisCall; 87 } 88 } 89 return maxSize; 90} 91 92// Align data larger than one L1 cache line on L1 cache line boundaries. 93// Align all smaller data on the next higher 2^x boundary (4, 8, ...). 94// 95// THIS FUNCTION HAS BEEN COPIED FROM EMITASSEMBLY.CPP AND 96// SHOULD BE USED DIRECTLY THERE 97// 98inline unsigned int 99SizeToAlignment(unsigned int size, const TargetMachine& target) 100{ 101 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 102 if (size > (unsigned) cacheLineSize / 2) 103 return cacheLineSize; 104 else 105 for (unsigned sz=1; /*no condition*/; sz *= 2) 106 if (sz >= size) 107 return sz; 108} 109 110 111 112/*ctor*/ 113MachineCodeForMethod::MachineCodeForMethod(const Method* _M, 114 const TargetMachine& target) 115 : Annotation(MCFM_AID), 116 method(_M), compiledAsLeaf(false), staticStackSize(0), 117 automaticVarsSize(0), regSpillsSize(0), 118 currentOptionalArgsSize(0), maxOptionalArgsSize(0), 119 currentTmpValuesSize(0) 120{ 121 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method); 122 staticStackSize = maxOptionalArgsSize + 123 target.getFrameInfo().getMinStackFrameSize(); 124} 125 126int 127MachineCodeForMethod::allocateLocalVar(const TargetMachine& target, 128 const Value* val, 129 unsigned int size) 130{ 131 // Check if we've allocated a stack slot for this value already 132 // 133 int offset = getOffset(val); 134 if (offset == INVALID_FRAME_OFFSET) 135 { 136 bool growUp; 137 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this, 138 growUp); 139 unsigned char align; 140 if (size == 0) 141 { 142 size = target.findOptimalStorageSize(val->getType()); 143 // align = target.DataLayout.getTypeAlignment(val->getType()); 144 } 145 146 align = SizeToAlignment(size, target); 147 148 offset = getAutomaticVarsSize(); 149 if (! growUp) 150 offset += size; 151 152 if (unsigned int mod = offset % align) 153 { 154 offset += align - mod; 155 size += align - mod; 156 } 157 158 offset = growUp? firstOffset + offset 159 : firstOffset - offset; 160 161 offsets[val] = offset; 162 163 incrementAutomaticVarsSize(size); 164 } 165 return offset; 166} 167 168int 169MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target, 170 const Type* type) 171{ 172 unsigned int size = target.findOptimalStorageSize(type); 173 unsigned char align = target.DataLayout.getTypeAlignment(type); 174 175 bool growUp; 176 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp); 177 178 int offset = getRegSpillsSize(); 179 if (! growUp) 180 offset += size; 181 182 if (unsigned int mod = offset % align) 183 { 184 offset += align - mod; 185 size += align - mod; 186 } 187 188 offset = growUp? firstOffset + offset 189 : firstOffset - offset; 190 191 incrementRegSpillsSize(size); 192 193 return offset; 194} 195 196int 197MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target, 198 const Type* type) 199{ 200 const MachineFrameInfo& frameInfo = target.getFrameInfo(); 201 202 int size = INT_MAX; 203 if (frameInfo.argsOnStackHaveFixedSize()) 204 size = frameInfo.getSizeOfEachArgOnStack(); 205 else 206 { 207 size = target.findOptimalStorageSize(type); 208 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets"); 209 } 210 unsigned char align = target.DataLayout.getTypeAlignment(type); 211 212 bool growUp; 213 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp); 214 215 int offset = getCurrentOptionalArgsSize(); 216 if (! growUp) 217 offset += size; 218 219 if (unsigned int mod = offset % align) 220 { 221 offset += align - mod; 222 size += align - mod; 223 } 224 225 offset = growUp? firstOffset + offset 226 : firstOffset - offset; 227 228 incrementCurrentOptionalArgsSize(size); 229 230 return offset; 231} 232 233void 234MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target) 235{ 236 currentOptionalArgsSize = 0; 237} 238 239int 240MachineCodeForMethod::pushTempValue(const TargetMachine& target, 241 unsigned int size) 242{ 243 // Compute a power-of-2 alignment according to the possible sizes, 244 // but not greater than the alignment of the largest type we support 245 // (currently a double word -- see class TargetData). 246 unsigned char align = 1; 247 for (; align < size && align < target.DataLayout.getDoubleAlignment(); 248 align = 2*align) 249 ; 250 251 bool growUp; 252 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp); 253 254 int offset = currentTmpValuesSize; 255 if (! growUp) 256 offset += size; 257 258 if (unsigned int mod = offset % align) 259 { 260 offset += align - mod; 261 size += align - mod; 262 } 263 264 offset = growUp ? firstTmpOffset + offset : firstTmpOffset - offset; 265 266 currentTmpValuesSize += size; 267 return offset; 268} 269 270void 271MachineCodeForMethod::popAllTempValues(const TargetMachine& target) 272{ 273 currentTmpValuesSize = 0; 274} 275 276int 277MachineCodeForMethod::getOffset(const Value* val) const 278{ 279 std::hash_map<const Value*, int>::const_iterator pair = offsets.find(val); 280 return (pair == offsets.end())? INVALID_FRAME_OFFSET : pair->second; 281} 282 283void 284MachineCodeForMethod::dump() const 285{ 286 cerr << "\n" << method->getReturnType() 287 << " \"" << method->getName() << "\"\n"; 288 289 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI) 290 { 291 BasicBlock* bb = *BI; 292 cerr << "\n" 293 << (bb->hasName()? bb->getName() : "Label") 294 << " (" << bb << ")" << ":\n"; 295 296 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); 297 for (unsigned i=0; i < mvec.size(); i++) 298 cerr << "\t" << *mvec[i]; 299 } 300 cerr << "\nEnd method \"" << method->getName() << "\"\n\n"; 301} 302