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