1 //===-- MachineFunction.cpp -----------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file was developed by the LLVM research group and is distributed under 6 // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Collect native machine code information for a function. This allows 11 // target-specific information about the generated code to be stored with each 12 // function. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/CodeGen/MachineFunction.h" 17 #include "llvm/CodeGen/MachineInstr.h" 18 #include "llvm/CodeGen/MachineCodeForInstruction.h" 19 #include "llvm/CodeGen/SSARegMap.h" 20 #include "llvm/CodeGen/MachineFunctionInfo.h" 21 #include "llvm/CodeGen/MachineFrameInfo.h" 22 #include "llvm/CodeGen/MachineConstantPool.h" 23 #include "llvm/Target/TargetMachine.h" 24 #include "llvm/Target/TargetFrameInfo.h" 25 #include "llvm/Target/TargetCacheInfo.h" 26 #include "llvm/Function.h" 27 #include "llvm/iOther.h" 28 #include "llvm/Pass.h" 29 #include "Config/limits.h" 30 31 namespace llvm { 32 33 const int INVALID_FRAME_OFFSET = INT_MAX; // std::numeric_limits<int>::max(); 34 35 static AnnotationID MF_AID( 36 AnnotationManager::getID("CodeGen::MachineCodeForFunction")); 37 38 39 //===---------------------------------------------------------------------===// 40 // Code generation/destruction passes 41 //===---------------------------------------------------------------------===// 42 43 namespace { 44 class ConstructMachineFunction : public FunctionPass { 45 TargetMachine &Target; 46 public: 47 ConstructMachineFunction(TargetMachine &T) : Target(T) {} 48 49 const char *getPassName() const { 50 return "ConstructMachineFunction"; 51 } 52 53 bool runOnFunction(Function &F) { 54 MachineFunction::construct(&F, Target).getInfo()->CalculateArgSize(); 55 return false; 56 } 57 }; 58 59 struct DestroyMachineFunction : public FunctionPass { 60 const char *getPassName() const { return "FreeMachineFunction"; } 61 62 static void freeMachineCode(Instruction &I) { 63 MachineCodeForInstruction::destroy(&I); 64 } 65 66 bool runOnFunction(Function &F) { 67 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) 68 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I) 69 MachineCodeForInstruction::get(I).dropAllReferences(); 70 71 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) 72 for_each(FI->begin(), FI->end(), freeMachineCode); 73 74 return false; 75 } 76 }; 77 78 struct Printer : public FunctionPass { 79 const char *getPassName() const { return "MachineFunction Printer"; } 80 81 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 82 AU.setPreservesAll(); 83 } 84 85 bool runOnFunction(Function &F) { 86 MachineFunction::get(&F).dump(); 87 return false; 88 } 89 }; 90 } 91 92 FunctionPass *createMachineCodeConstructionPass(TargetMachine &Target) { 93 return new ConstructMachineFunction(Target); 94 } 95 96 FunctionPass *createMachineCodeDestructionPass() { 97 return new DestroyMachineFunction(); 98 } 99 100 FunctionPass *createMachineFunctionPrinterPass() { 101 return new Printer(); 102 } 103 104 105 //===---------------------------------------------------------------------===// 106 // MachineFunction implementation 107 //===---------------------------------------------------------------------===// 108 109 MachineFunction::MachineFunction(const Function *F, 110 const TargetMachine &TM) 111 : Annotation(MF_AID), Fn(F), Target(TM) { 112 SSARegMapping = new SSARegMap(); 113 MFInfo = new MachineFunctionInfo(*this); 114 FrameInfo = new MachineFrameInfo(); 115 ConstantPool = new MachineConstantPool(); 116 } 117 118 MachineFunction::~MachineFunction() { 119 delete SSARegMapping; 120 delete MFInfo; 121 delete FrameInfo; 122 delete ConstantPool; 123 } 124 125 void MachineFunction::dump() const { print(std::cerr); } 126 127 void MachineFunction::print(std::ostream &OS) const { 128 OS << "\n" << *(Value*)Fn->getFunctionType() << " \"" << Fn->getName() 129 << "\"\n"; 130 131 // Print Frame Information 132 getFrameInfo()->print(*this, OS); 133 134 // Print Constant Pool 135 getConstantPool()->print(OS); 136 137 for (const_iterator BB = begin(); BB != end(); ++BB) { 138 const BasicBlock *LBB = BB->getBasicBlock(); 139 OS << "\n" << LBB->getName() << " (" << (const void*)LBB << "):\n"; 140 for (MachineBasicBlock::const_iterator I = BB->begin(); I != BB->end();++I){ 141 OS << "\t"; 142 (*I)->print(OS, Target); 143 } 144 } 145 OS << "\nEnd function \"" << Fn->getName() << "\"\n\n"; 146 } 147 148 149 // The next two methods are used to construct and to retrieve 150 // the MachineCodeForFunction object for the given function. 151 // construct() -- Allocates and initializes for a given function and target 152 // get() -- Returns a handle to the object. 153 // This should not be called before "construct()" 154 // for a given Function. 155 // 156 MachineFunction& 157 MachineFunction::construct(const Function *Fn, const TargetMachine &Tar) 158 { 159 assert(Fn->getAnnotation(MF_AID) == 0 && 160 "Object already exists for this function!"); 161 MachineFunction* mcInfo = new MachineFunction(Fn, Tar); 162 Fn->addAnnotation(mcInfo); 163 return *mcInfo; 164 } 165 166 void 167 MachineFunction::destruct(const Function *Fn) 168 { 169 bool Deleted = Fn->deleteAnnotation(MF_AID); 170 assert(Deleted && "Machine code did not exist for function!"); 171 } 172 173 MachineFunction& MachineFunction::get(const Function *F) 174 { 175 MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID); 176 assert(mc && "Call construct() method first to allocate the object"); 177 return *mc; 178 } 179 180 void MachineFunction::clearSSARegMap() { 181 delete SSARegMapping; 182 SSARegMapping = 0; 183 } 184 185 //===----------------------------------------------------------------------===// 186 // MachineFrameInfo implementation 187 //===----------------------------------------------------------------------===// 188 189 /// CreateStackObject - Create a stack object for a value of the specified type. 190 /// 191 int MachineFrameInfo::CreateStackObject(const Type *Ty, const TargetData &TD) { 192 return CreateStackObject(TD.getTypeSize(Ty), TD.getTypeAlignment(Ty)); 193 } 194 195 int MachineFrameInfo::CreateStackObject(const TargetRegisterClass *RC) { 196 return CreateStackObject(RC->getSize(), RC->getAlignment()); 197 } 198 199 200 void MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{ 201 int ValOffset = MF.getTarget().getFrameInfo().getOffsetOfLocalArea(); 202 203 for (unsigned i = 0, e = Objects.size(); i != e; ++i) { 204 const StackObject &SO = Objects[i]; 205 OS << " <fi #" << (int)(i-NumFixedObjects) << "> is "; 206 if (SO.Size == 0) 207 OS << "variable sized"; 208 else 209 OS << SO.Size << " byte" << (SO.Size != 1 ? "s" : " "); 210 211 if (i < NumFixedObjects) 212 OS << " fixed"; 213 if (i < NumFixedObjects || SO.SPOffset != -1) { 214 int Off = SO.SPOffset + ValOffset; 215 OS << " at location [SP"; 216 if (Off > 0) 217 OS << "+" << Off; 218 else if (Off < 0) 219 OS << Off; 220 OS << "]"; 221 } 222 OS << "\n"; 223 } 224 225 if (HasVarSizedObjects) 226 OS << " Stack frame contains variable sized objects\n"; 227 } 228 229 void MachineFrameInfo::dump(const MachineFunction &MF) const { 230 print(MF, std::cerr); 231 } 232 233 234 //===----------------------------------------------------------------------===// 235 // MachineConstantPool implementation 236 //===----------------------------------------------------------------------===// 237 238 void MachineConstantPool::print(std::ostream &OS) const { 239 for (unsigned i = 0, e = Constants.size(); i != e; ++i) 240 OS << " <cp #" << i << "> is" << *(Value*)Constants[i] << "\n"; 241 } 242 243 void MachineConstantPool::dump() const { print(std::cerr); } 244 245 //===----------------------------------------------------------------------===// 246 // MachineFunctionInfo implementation 247 //===----------------------------------------------------------------------===// 248 249 static unsigned 250 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F, 251 unsigned &maxOptionalNumArgs) 252 { 253 const TargetFrameInfo &frameInfo = target.getFrameInfo(); 254 255 unsigned maxSize = 0; 256 257 for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB) 258 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) 259 if (const CallInst *callInst = dyn_cast<CallInst>(I)) 260 { 261 unsigned numOperands = callInst->getNumOperands() - 1; 262 int numExtra = (int)numOperands-frameInfo.getNumFixedOutgoingArgs(); 263 if (numExtra <= 0) 264 continue; 265 266 unsigned sizeForThisCall; 267 if (frameInfo.argsOnStackHaveFixedSize()) 268 { 269 int argSize = frameInfo.getSizeOfEachArgOnStack(); 270 sizeForThisCall = numExtra * (unsigned) argSize; 271 } 272 else 273 { 274 assert(0 && "UNTESTED CODE: Size per stack argument is not " 275 "fixed on this architecture: use actual arg sizes to " 276 "compute MaxOptionalArgsSize"); 277 sizeForThisCall = 0; 278 for (unsigned i = 0; i < numOperands; ++i) 279 sizeForThisCall += target.getTargetData().getTypeSize(callInst-> 280 getOperand(i)->getType()); 281 } 282 283 if (maxSize < sizeForThisCall) 284 maxSize = sizeForThisCall; 285 286 if ((int)maxOptionalNumArgs < numExtra) 287 maxOptionalNumArgs = (unsigned) numExtra; 288 } 289 290 return maxSize; 291 } 292 293 // Align data larger than one L1 cache line on L1 cache line boundaries. 294 // Align all smaller data on the next higher 2^x boundary (4, 8, ...), 295 // but not higher than the alignment of the largest type we support 296 // (currently a double word). -- see class TargetData). 297 // 298 // This function is similar to the corresponding function in EmitAssembly.cpp 299 // but they are unrelated. This one does not align at more than a 300 // double-word boundary whereas that one might. 301 // 302 inline unsigned 303 SizeToAlignment(unsigned size, const TargetMachine& target) 304 { 305 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 306 if (size > (unsigned) cacheLineSize / 2) 307 return cacheLineSize; 308 else 309 for (unsigned sz=1; /*no condition*/; sz *= 2) 310 if (sz >= size || sz >= target.getTargetData().getDoubleAlignment()) 311 return sz; 312 } 313 314 315 void MachineFunctionInfo::CalculateArgSize() { 316 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(), 317 MF.getFunction(), 318 maxOptionalNumArgs); 319 staticStackSize = maxOptionalArgsSize 320 + MF.getTarget().getFrameInfo().getMinStackFrameSize(); 321 } 322 323 int 324 MachineFunctionInfo::computeOffsetforLocalVar(const Value* val, 325 unsigned &getPaddedSize, 326 unsigned sizeToUse) 327 { 328 if (sizeToUse == 0) 329 sizeToUse = MF.getTarget().findOptimalStorageSize(val->getType()); 330 unsigned align = SizeToAlignment(sizeToUse, MF.getTarget()); 331 332 bool growUp; 333 int firstOffset = MF.getTarget().getFrameInfo().getFirstAutomaticVarOffset(MF, 334 growUp); 335 int offset = growUp? firstOffset + getAutomaticVarsSize() 336 : firstOffset - (getAutomaticVarsSize() + sizeToUse); 337 338 int aligned = MF.getTarget().getFrameInfo().adjustAlignment(offset, growUp, align); 339 getPaddedSize = sizeToUse + abs(aligned - offset); 340 341 return aligned; 342 } 343 344 int 345 MachineFunctionInfo::allocateLocalVar(const Value* val, 346 unsigned sizeToUse) 347 { 348 assert(! automaticVarsAreaFrozen && 349 "Size of auto vars area has been used to compute an offset so " 350 "no more automatic vars should be allocated!"); 351 352 // Check if we've allocated a stack slot for this value already 353 // 354 int offset = getOffset(val); 355 if (offset == INVALID_FRAME_OFFSET) 356 { 357 unsigned getPaddedSize; 358 offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse); 359 offsets[val] = offset; 360 incrementAutomaticVarsSize(getPaddedSize); 361 } 362 return offset; 363 } 364 365 int 366 MachineFunctionInfo::allocateSpilledValue(const Type* type) 367 { 368 assert(! spillsAreaFrozen && 369 "Size of reg spills area has been used to compute an offset so " 370 "no more register spill slots should be allocated!"); 371 372 unsigned size = MF.getTarget().getTargetData().getTypeSize(type); 373 unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type); 374 375 bool growUp; 376 int firstOffset = MF.getTarget().getFrameInfo().getRegSpillAreaOffset(MF, growUp); 377 378 int offset = growUp? firstOffset + getRegSpillsSize() 379 : firstOffset - (getRegSpillsSize() + size); 380 381 int aligned = MF.getTarget().getFrameInfo().adjustAlignment(offset, growUp, align); 382 size += abs(aligned - offset); // include alignment padding in size 383 384 incrementRegSpillsSize(size); // update size of reg. spills area 385 386 return aligned; 387 } 388 389 int 390 MachineFunctionInfo::pushTempValue(unsigned size) 391 { 392 unsigned align = SizeToAlignment(size, MF.getTarget()); 393 394 bool growUp; 395 int firstOffset = MF.getTarget().getFrameInfo().getTmpAreaOffset(MF, growUp); 396 397 int offset = growUp? firstOffset + currentTmpValuesSize 398 : firstOffset - (currentTmpValuesSize + size); 399 400 int aligned = MF.getTarget().getFrameInfo().adjustAlignment(offset, growUp, 401 align); 402 size += abs(aligned - offset); // include alignment padding in size 403 404 incrementTmpAreaSize(size); // update "current" size of tmp area 405 406 return aligned; 407 } 408 409 void MachineFunctionInfo::popAllTempValues() { 410 resetTmpAreaSize(); // clear tmp area to reuse 411 } 412 413 int 414 MachineFunctionInfo::getOffset(const Value* val) const 415 { 416 hash_map<const Value*, int>::const_iterator pair = offsets.find(val); 417 return (pair == offsets.end()) ? INVALID_FRAME_OFFSET : pair->second; 418 } 419 420 } // End llvm namespace 421