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