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