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