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