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