MachineFunction.cpp revision d0aa0cdbc6fee00f2b2019633a9b9d00d301ac68
1//===-- MachineFunction.cpp -----------------------------------------------===// 2// 3// Collect native machine code information for a function. This allows 4// target-specific information about the generated code to be stored with each 5// function. 6// 7//===----------------------------------------------------------------------===// 8 9#include "llvm/CodeGen/MachineInstr.h" // For debug output 10#include "llvm/CodeGen/MachineFunction.h" 11#include "llvm/CodeGen/MachineCodeForInstruction.h" 12#include "llvm/Target/TargetMachine.h" 13#include "llvm/Target/MachineFrameInfo.h" 14#include "llvm/Target/MachineCacheInfo.h" 15#include "llvm/Function.h" 16#include "llvm/iOther.h" 17#include "llvm/Pass.h" 18#include <limits.h> 19 20const int INVALID_FRAME_OFFSET = INT_MAX; // std::numeric_limits<int>::max(); 21 22static AnnotationID MCFM_AID( 23 AnnotationManager::getID("CodeGen::MachineCodeForFunction")); 24 25 26//===---------------------------------------------------------------------===// 27// Code generation/destruction passes 28//===---------------------------------------------------------------------===// 29 30namespace { 31 class ConstructMachineFunction : public FunctionPass { 32 TargetMachine &Target; 33 public: 34 ConstructMachineFunction(TargetMachine &T) : Target(T) {} 35 36 const char *getPassName() const { 37 return "ConstructMachineFunction"; 38 } 39 40 bool runOnFunction(Function &F) { 41 MachineFunction::construct(&F, Target); 42 return false; 43 } 44 }; 45 46 struct DestroyMachineFunction : public FunctionPass { 47 const char *getPassName() const { return "FreeMachineFunction"; } 48 49 static void freeMachineCode(Instruction &I) { 50 MachineCodeForInstruction::destroy(&I); 51 } 52 53 bool runOnFunction(Function &F) { 54 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) 55 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I) 56 MachineCodeForInstruction::get(I).dropAllReferences(); 57 58 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) 59 for_each(FI->begin(), FI->end(), freeMachineCode); 60 61 return false; 62 } 63 }; 64} 65 66Pass *createMachineCodeConstructionPass(TargetMachine &Target) { 67 return new ConstructMachineFunction(Target); 68} 69 70Pass *createMachineCodeDestructionPass() { 71 return new DestroyMachineFunction(); 72} 73 74 75// get - This deprecated static method returns the MachineBasicBlock object 76// for the specified BasicBlock. 77// 78MachineBasicBlock& MachineBasicBlock::get(const BasicBlock *BB) { 79 const Function *F = BB->getParent(); 80 MachineFunction &MF = MachineFunction::get(F); 81 82 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) 83 if (I->getBasicBlock() == BB) 84 return *I; 85 assert(0 && "MachineBasicBlock object not found for specified block!"); 86 return get(BB); 87} 88 89 90//===---------------------------------------------------------------------===// 91// MachineFunction implementation 92//===---------------------------------------------------------------------===// 93 94// The next two methods are used to construct and to retrieve 95// the MachineCodeForFunction object for the given function. 96// construct() -- Allocates and initializes for a given function and target 97// get() -- Returns a handle to the object. 98// This should not be called before "construct()" 99// for a given Function. 100// 101MachineFunction& 102MachineFunction::construct(const Function *M, const TargetMachine &Tar) 103{ 104 assert(M->getAnnotation(MCFM_AID) == 0 && 105 "Object already exists for this function!"); 106 MachineFunction* mcInfo = new MachineFunction(M, Tar); 107 M->addAnnotation(mcInfo); 108 return *mcInfo; 109} 110 111void 112MachineFunction::destruct(const Function *M) 113{ 114 bool Deleted = M->deleteAnnotation(MCFM_AID); 115 assert(Deleted && "Machine code did not exist for function!"); 116} 117 118MachineFunction& 119MachineFunction::get(const Function *F) 120{ 121 MachineFunction *mc = (MachineFunction*)F->getAnnotation(MCFM_AID); 122 assert(mc && "Call construct() method first to allocate the object"); 123 return *mc; 124} 125 126static unsigned 127ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F, 128 unsigned &maxOptionalNumArgs) 129{ 130 const MachineFrameInfo& frameInfo = target.getFrameInfo(); 131 132 unsigned maxSize = 0; 133 134 for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB) 135 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) 136 if (const CallInst *callInst = dyn_cast<CallInst>(&*I)) 137 { 138 unsigned numOperands = callInst->getNumOperands() - 1; 139 int numExtra = (int)numOperands-frameInfo.getNumFixedOutgoingArgs(); 140 if (numExtra <= 0) 141 continue; 142 143 unsigned int sizeForThisCall; 144 if (frameInfo.argsOnStackHaveFixedSize()) 145 { 146 int argSize = frameInfo.getSizeOfEachArgOnStack(); 147 sizeForThisCall = numExtra * (unsigned) argSize; 148 } 149 else 150 { 151 assert(0 && "UNTESTED CODE: Size per stack argument is not " 152 "fixed on this architecture: use actual arg sizes to " 153 "compute MaxOptionalArgsSize"); 154 sizeForThisCall = 0; 155 for (unsigned i = 0; i < numOperands; ++i) 156 sizeForThisCall += target.DataLayout.getTypeSize(callInst-> 157 getOperand(i)->getType()); 158 } 159 160 if (maxSize < sizeForThisCall) 161 maxSize = sizeForThisCall; 162 163 if ((int)maxOptionalNumArgs < numExtra) 164 maxOptionalNumArgs = (unsigned) numExtra; 165 } 166 167 return maxSize; 168} 169 170// Align data larger than one L1 cache line on L1 cache line boundaries. 171// Align all smaller data on the next higher 2^x boundary (4, 8, ...), 172// but not higher than the alignment of the largest type we support 173// (currently a double word). -- see class TargetData). 174// 175// This function is similar to the corresponding function in EmitAssembly.cpp 176// but they are unrelated. This one does not align at more than a 177// double-word boundary whereas that one might. 178// 179inline unsigned int 180SizeToAlignment(unsigned int size, const TargetMachine& target) 181{ 182 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 183 if (size > (unsigned) cacheLineSize / 2) 184 return cacheLineSize; 185 else 186 for (unsigned sz=1; /*no condition*/; sz *= 2) 187 if (sz >= size || sz >= target.DataLayout.getDoubleAlignment()) 188 return sz; 189} 190 191 192/*ctor*/ 193MachineFunction::MachineFunction(const Function *F, 194 const TargetMachine& target) 195 : Annotation(MCFM_AID), 196 method(F), staticStackSize(0), 197 automaticVarsSize(0), regSpillsSize(0), 198 maxOptionalArgsSize(0), maxOptionalNumArgs(0), 199 currentTmpValuesSize(0), maxTmpValuesSize(0), compiledAsLeaf(false), 200 spillsAreaFrozen(false), automaticVarsAreaFrozen(false) 201{ 202 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method, 203 maxOptionalNumArgs); 204 staticStackSize = maxOptionalArgsSize 205 + target.getFrameInfo().getMinStackFrameSize(); 206} 207 208int 209MachineFunction::computeOffsetforLocalVar(const TargetMachine& target, 210 const Value* val, 211 unsigned int& getPaddedSize, 212 unsigned int sizeToUse) 213{ 214 if (sizeToUse == 0) 215 sizeToUse = target.findOptimalStorageSize(val->getType()); 216 unsigned int align = SizeToAlignment(sizeToUse, target); 217 218 bool growUp; 219 int firstOffset = target.getFrameInfo().getFirstAutomaticVarOffset(*this, 220 growUp); 221 int offset = growUp? firstOffset + getAutomaticVarsSize() 222 : firstOffset - (getAutomaticVarsSize() + sizeToUse); 223 224 int aligned = target.getFrameInfo().adjustAlignment(offset, growUp, align); 225 getPaddedSize = sizeToUse + abs(aligned - offset); 226 227 return aligned; 228} 229 230int 231MachineFunction::allocateLocalVar(const TargetMachine& target, 232 const Value* val, 233 unsigned int sizeToUse) 234{ 235 assert(! automaticVarsAreaFrozen && 236 "Size of auto vars area has been used to compute an offset so " 237 "no more automatic vars should be allocated!"); 238 239 // Check if we've allocated a stack slot for this value already 240 // 241 int offset = getOffset(val); 242 if (offset == INVALID_FRAME_OFFSET) 243 { 244 unsigned int getPaddedSize; 245 offset = computeOffsetforLocalVar(target, val, getPaddedSize, sizeToUse); 246 offsets[val] = offset; 247 incrementAutomaticVarsSize(getPaddedSize); 248 } 249 return offset; 250} 251 252int 253MachineFunction::allocateSpilledValue(const TargetMachine& target, 254 const Type* type) 255{ 256 assert(! spillsAreaFrozen && 257 "Size of reg spills area has been used to compute an offset so " 258 "no more register spill slots should be allocated!"); 259 260 unsigned int size = target.DataLayout.getTypeSize(type); 261 unsigned char align = target.DataLayout.getTypeAlignment(type); 262 263 bool growUp; 264 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp); 265 266 int offset = growUp? firstOffset + getRegSpillsSize() 267 : firstOffset - (getRegSpillsSize() + size); 268 269 int aligned = target.getFrameInfo().adjustAlignment(offset, growUp, align); 270 size += abs(aligned - offset); // include alignment padding in size 271 272 incrementRegSpillsSize(size); // update size of reg. spills area 273 274 return aligned; 275} 276 277int 278MachineFunction::pushTempValue(const TargetMachine& target, 279 unsigned int size) 280{ 281 unsigned int align = SizeToAlignment(size, target); 282 283 bool growUp; 284 int firstOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp); 285 286 int offset = growUp? firstOffset + currentTmpValuesSize 287 : firstOffset - (currentTmpValuesSize + size); 288 289 int aligned = target.getFrameInfo().adjustAlignment(offset, growUp, align); 290 size += abs(aligned - offset); // include alignment padding in size 291 292 incrementTmpAreaSize(size); // update "current" size of tmp area 293 294 return aligned; 295} 296 297void 298MachineFunction::popAllTempValues(const TargetMachine& target) 299{ 300 resetTmpAreaSize(); // clear tmp area to reuse 301} 302 303int 304MachineFunction::getOffset(const Value* val) const 305{ 306 hash_map<const Value*, int>::const_iterator pair = offsets.find(val); 307 return (pair == offsets.end()) ? INVALID_FRAME_OFFSET : pair->second; 308} 309 310void 311MachineFunction::dump() const 312{ 313 std::cerr << "\n" << method->getReturnType() 314 << " \"" << method->getName() << "\"\n"; 315 316 for (Function::const_iterator BB = method->begin(); BB != method->end(); ++BB) 317 { 318 std::cerr << "\n" << BB->getName() << " (" << (const void*)BB 319 << ")" << ":" << "\n"; 320 MachineBasicBlock& mvec = MachineBasicBlock::get(BB); 321 for (unsigned i=0; i < mvec.size(); i++) 322 std::cerr << "\t" << *mvec[i]; 323 } 324 std::cerr << "\nEnd function \"" << method->getName() << "\"\n\n"; 325} 326