MachineFunction.cpp revision 88726188fe9a3e30ec9bdd9f2449905c0d8cedcf
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 MF_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).CalculateArgSize(); 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//===---------------------------------------------------------------------===// 76// MachineFunction implementation 77//===---------------------------------------------------------------------===// 78 79// The next two methods are used to construct and to retrieve 80// the MachineCodeForFunction object for the given function. 81// construct() -- Allocates and initializes for a given function and target 82// get() -- Returns a handle to the object. 83// This should not be called before "construct()" 84// for a given Function. 85// 86MachineFunction& 87MachineFunction::construct(const Function *Fn, const TargetMachine &Tar) 88{ 89 assert(Fn->getAnnotation(MF_AID) == 0 && 90 "Object already exists for this function!"); 91 MachineFunction* mcInfo = new MachineFunction(Fn, Tar); 92 Fn->addAnnotation(mcInfo); 93 return *mcInfo; 94} 95 96void 97MachineFunction::destruct(const Function *Fn) 98{ 99 bool Deleted = Fn->deleteAnnotation(MF_AID); 100 assert(Deleted && "Machine code did not exist for function!"); 101} 102 103MachineFunction& MachineFunction::get(const Function *F) 104{ 105 MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID); 106 assert(mc && "Call construct() method first to allocate the object"); 107 return *mc; 108} 109 110static unsigned 111ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F, 112 unsigned &maxOptionalNumArgs) 113{ 114 const MachineFrameInfo& frameInfo = target.getFrameInfo(); 115 116 unsigned maxSize = 0; 117 118 for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB) 119 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) 120 if (const CallInst *callInst = dyn_cast<CallInst>(&*I)) 121 { 122 unsigned numOperands = callInst->getNumOperands() - 1; 123 int numExtra = (int)numOperands-frameInfo.getNumFixedOutgoingArgs(); 124 if (numExtra <= 0) 125 continue; 126 127 unsigned int sizeForThisCall; 128 if (frameInfo.argsOnStackHaveFixedSize()) 129 { 130 int argSize = frameInfo.getSizeOfEachArgOnStack(); 131 sizeForThisCall = numExtra * (unsigned) argSize; 132 } 133 else 134 { 135 assert(0 && "UNTESTED CODE: Size per stack argument is not " 136 "fixed on this architecture: use actual arg sizes to " 137 "compute MaxOptionalArgsSize"); 138 sizeForThisCall = 0; 139 for (unsigned i = 0; i < numOperands; ++i) 140 sizeForThisCall += target.DataLayout.getTypeSize(callInst-> 141 getOperand(i)->getType()); 142 } 143 144 if (maxSize < sizeForThisCall) 145 maxSize = sizeForThisCall; 146 147 if ((int)maxOptionalNumArgs < numExtra) 148 maxOptionalNumArgs = (unsigned) numExtra; 149 } 150 151 return maxSize; 152} 153 154// Align data larger than one L1 cache line on L1 cache line boundaries. 155// Align all smaller data on the next higher 2^x boundary (4, 8, ...), 156// but not higher than the alignment of the largest type we support 157// (currently a double word). -- see class TargetData). 158// 159// This function is similar to the corresponding function in EmitAssembly.cpp 160// but they are unrelated. This one does not align at more than a 161// double-word boundary whereas that one might. 162// 163inline unsigned int 164SizeToAlignment(unsigned int size, const TargetMachine& target) 165{ 166 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 167 if (size > (unsigned) cacheLineSize / 2) 168 return cacheLineSize; 169 else 170 for (unsigned sz=1; /*no condition*/; sz *= 2) 171 if (sz >= size || sz >= target.DataLayout.getDoubleAlignment()) 172 return sz; 173} 174 175 176MachineFunction::MachineFunction(const Function *F, 177 const TargetMachine& target) 178 : Annotation(MF_AID), 179 Fn(F), Target(target), staticStackSize(0), 180 automaticVarsSize(0), regSpillsSize(0), 181 maxOptionalArgsSize(0), maxOptionalNumArgs(0), 182 currentTmpValuesSize(0), maxTmpValuesSize(0), compiledAsLeaf(false), 183 spillsAreaFrozen(false), automaticVarsAreaFrozen(false) 184{ 185} 186 187void MachineFunction::CalculateArgSize() { 188 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(Target, Fn, 189 maxOptionalNumArgs); 190 staticStackSize = maxOptionalArgsSize 191 + Target.getFrameInfo().getMinStackFrameSize(); 192} 193 194int 195MachineFunction::computeOffsetforLocalVar(const TargetMachine& target, 196 const Value* val, 197 unsigned int& getPaddedSize, 198 unsigned int sizeToUse) 199{ 200 if (sizeToUse == 0) 201 sizeToUse = target.findOptimalStorageSize(val->getType()); 202 unsigned int align = SizeToAlignment(sizeToUse, target); 203 204 bool growUp; 205 int firstOffset = target.getFrameInfo().getFirstAutomaticVarOffset(*this, 206 growUp); 207 int offset = growUp? firstOffset + getAutomaticVarsSize() 208 : firstOffset - (getAutomaticVarsSize() + sizeToUse); 209 210 int aligned = target.getFrameInfo().adjustAlignment(offset, growUp, align); 211 getPaddedSize = sizeToUse + abs(aligned - offset); 212 213 return aligned; 214} 215 216int 217MachineFunction::allocateLocalVar(const TargetMachine& target, 218 const Value* val, 219 unsigned int sizeToUse) 220{ 221 assert(! automaticVarsAreaFrozen && 222 "Size of auto vars area has been used to compute an offset so " 223 "no more automatic vars should be allocated!"); 224 225 // Check if we've allocated a stack slot for this value already 226 // 227 int offset = getOffset(val); 228 if (offset == INVALID_FRAME_OFFSET) 229 { 230 unsigned int getPaddedSize; 231 offset = computeOffsetforLocalVar(target, val, getPaddedSize, sizeToUse); 232 offsets[val] = offset; 233 incrementAutomaticVarsSize(getPaddedSize); 234 } 235 return offset; 236} 237 238int 239MachineFunction::allocateSpilledValue(const TargetMachine& target, 240 const Type* type) 241{ 242 assert(! spillsAreaFrozen && 243 "Size of reg spills area has been used to compute an offset so " 244 "no more register spill slots should be allocated!"); 245 246 unsigned int size = target.DataLayout.getTypeSize(type); 247 unsigned char align = target.DataLayout.getTypeAlignment(type); 248 249 bool growUp; 250 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp); 251 252 int offset = growUp? firstOffset + getRegSpillsSize() 253 : firstOffset - (getRegSpillsSize() + size); 254 255 int aligned = target.getFrameInfo().adjustAlignment(offset, growUp, align); 256 size += abs(aligned - offset); // include alignment padding in size 257 258 incrementRegSpillsSize(size); // update size of reg. spills area 259 260 return aligned; 261} 262 263int 264MachineFunction::pushTempValue(const TargetMachine& target, 265 unsigned int size) 266{ 267 unsigned int align = SizeToAlignment(size, target); 268 269 bool growUp; 270 int firstOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp); 271 272 int offset = growUp? firstOffset + currentTmpValuesSize 273 : firstOffset - (currentTmpValuesSize + size); 274 275 int aligned = target.getFrameInfo().adjustAlignment(offset, growUp, align); 276 size += abs(aligned - offset); // include alignment padding in size 277 278 incrementTmpAreaSize(size); // update "current" size of tmp area 279 280 return aligned; 281} 282 283void 284MachineFunction::popAllTempValues(const TargetMachine& target) 285{ 286 resetTmpAreaSize(); // clear tmp area to reuse 287} 288 289int 290MachineFunction::getOffset(const Value* val) const 291{ 292 hash_map<const Value*, int>::const_iterator pair = offsets.find(val); 293 return (pair == offsets.end()) ? INVALID_FRAME_OFFSET : pair->second; 294} 295 296void 297MachineFunction::dump() const 298{ 299 std::cerr << "\n" << Fn->getReturnType() 300 << " \"" << Fn->getName() << "\"\n"; 301 302 for (const_iterator BB = begin(); BB != end(); ++BB) { 303 std::cerr << "\n" << BB->getBasicBlock()->getName() << " (" 304 << (const void*)BB->getBasicBlock() << ")" << ":" << "\n"; 305 for (MachineBasicBlock::const_iterator I = BB->begin(); I != BB->end(); ++I) 306 std::cerr << "\t" << *I; 307 } 308 std::cerr << "\nEnd function \"" << Fn->getName() << "\"\n\n"; 309} 310