MachineFunction.cpp revision 3927af8d70c0809c6286b3d14b350a2f04bd024b
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/MachineFunctionPass.h" 17#include "llvm/CodeGen/MachineInstr.h" 18#include "llvm/CodeGen/SSARegMap.h" 19#include "llvm/CodeGen/MachineFunctionInfo.h" 20#include "llvm/CodeGen/MachineFrameInfo.h" 21#include "llvm/CodeGen/MachineConstantPool.h" 22#include "llvm/CodeGen/Passes.h" 23#include "llvm/Target/TargetMachine.h" 24#include "llvm/Target/TargetFrameInfo.h" 25#include "llvm/Function.h" 26#include "llvm/Instructions.h" 27#include "llvm/Type.h" 28#include "Support/LeakDetector.h" 29#include "Support/GraphWriter.h" 30#include <fstream> 31#include <iostream> 32#include <sstream> 33 34using namespace llvm; 35 36static AnnotationID MF_AID( 37 AnnotationManager::getID("CodeGen::MachineCodeForFunction")); 38 39 40namespace { 41 struct Printer : public MachineFunctionPass { 42 std::ostream *OS; 43 const std::string Banner; 44 45 Printer (std::ostream *_OS, const std::string &_Banner) : 46 OS (_OS), Banner (_Banner) { } 47 48 const char *getPassName() const { return "MachineFunction Printer"; } 49 50 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 51 AU.setPreservesAll(); 52 } 53 54 bool runOnMachineFunction(MachineFunction &MF) { 55 (*OS) << Banner; 56 MF.print (*OS); 57 return false; 58 } 59 }; 60} 61 62/// Returns a newly-created MachineFunction Printer pass. The default output 63/// stream is std::cerr; the default banner is empty. 64/// 65FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS, 66 const std::string &Banner) { 67 return new Printer(OS, Banner); 68} 69 70namespace { 71 struct Deleter : public MachineFunctionPass { 72 const char *getPassName() const { return "Machine Code Deleter"; } 73 74 bool runOnMachineFunction(MachineFunction &MF) { 75 // Delete the annotation from the function now. 76 MachineFunction::destruct(MF.getFunction()); 77 return true; 78 } 79 }; 80} 81 82/// MachineCodeDeletion Pass - This pass deletes all of the machine code for 83/// the current function, which should happen after the function has been 84/// emitted to a .s file or to memory. 85FunctionPass *llvm::createMachineCodeDeleter() { 86 return new Deleter(); 87} 88 89 90 91//===---------------------------------------------------------------------===// 92// MachineFunction implementation 93//===---------------------------------------------------------------------===// 94MachineBasicBlock* ilist_traits<MachineBasicBlock>::createNode() 95{ 96 MachineBasicBlock* dummy = new MachineBasicBlock(); 97 LeakDetector::removeGarbageObject(dummy); 98 return dummy; 99} 100 101void ilist_traits<MachineBasicBlock>::transferNodesFromList( 102 iplist<MachineBasicBlock, ilist_traits<MachineBasicBlock> >& toList, 103 ilist_iterator<MachineBasicBlock> first, 104 ilist_iterator<MachineBasicBlock> last) 105{ 106 if (Parent != toList.Parent) 107 for (; first != last; ++first) 108 first->Parent = toList.Parent; 109} 110 111MachineFunction::MachineFunction(const Function *F, 112 const TargetMachine &TM) 113 : Annotation(MF_AID), Fn(F), Target(TM) { 114 SSARegMapping = new SSARegMap(); 115 MFInfo = new MachineFunctionInfo(*this); 116 FrameInfo = new MachineFrameInfo(); 117 ConstantPool = new MachineConstantPool(); 118 BasicBlocks.Parent = this; 119} 120 121MachineFunction::~MachineFunction() { 122 BasicBlocks.clear(); 123 delete SSARegMapping; 124 delete MFInfo; 125 delete FrameInfo; 126 delete ConstantPool; 127} 128 129void MachineFunction::dump() const { print(std::cerr); } 130 131void MachineFunction::print(std::ostream &OS) const { 132 OS << "# Machine code for " << Fn->getName () << "():\n"; 133 134 // Print Frame Information 135 getFrameInfo()->print(*this, OS); 136 137 // Print Constant Pool 138 getConstantPool()->print(OS); 139 140 for (const_iterator BB = begin(); BB != end(); ++BB) 141 BB->print(OS); 142 143 OS << "\n# End machine code for " << Fn->getName () << "().\n\n"; 144} 145 146/// CFGOnly flag - This is used to control whether or not the CFG graph printer 147/// prints out the contents of basic blocks or not. This is acceptable because 148/// this code is only really used for debugging purposes. 149/// 150static bool CFGOnly = false; 151 152namespace llvm { 153template<> 154struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits { 155 static std::string getGraphName(const MachineFunction *F) { 156 return "CFG for '" + F->getFunction()->getName() + "' function"; 157 } 158 159 static std::string getNodeLabel(const MachineBasicBlock *Node, 160 const MachineFunction *Graph) { 161 if (CFGOnly && Node->getBasicBlock() && 162 !Node->getBasicBlock()->getName().empty()) 163 return Node->getBasicBlock()->getName() + ":"; 164 165 std::ostringstream Out; 166 if (CFGOnly) { 167 Out << Node->getNumber() << ':'; 168 return Out.str(); 169 } 170 171 Node->print(Out); 172 173 std::string OutStr = Out.str(); 174 if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 175 176 // Process string output to make it nicer... 177 for (unsigned i = 0; i != OutStr.length(); ++i) 178 if (OutStr[i] == '\n') { // Left justify 179 OutStr[i] = '\\'; 180 OutStr.insert(OutStr.begin()+i+1, 'l'); 181 } 182 return OutStr; 183 } 184}; 185} 186 187void MachineFunction::viewCFG() const 188{ 189 std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot"; 190 std::cerr << "Writing '" << Filename << "'... "; 191 std::ofstream F(Filename.c_str()); 192 193 if (!F) { 194 std::cerr << " error opening file for writing!\n"; 195 return; 196 } 197 198 WriteGraph(F, this); 199 F.close(); 200 std::cerr << "\n"; 201 202 std::cerr << "Running 'dot' program... " << std::flush; 203 if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename 204 + " > /tmp/cfg.tempgraph.ps").c_str())) { 205 std::cerr << "Error running dot: 'dot' not in path?\n"; 206 } else { 207 std::cerr << "\n"; 208 system("gv /tmp/cfg.tempgraph.ps"); 209 } 210 system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str()); 211} 212 213void MachineFunction::viewCFGOnly() const 214{ 215 CFGOnly = true; 216 viewCFG(); 217 CFGOnly = false; 218} 219 220// The next two methods are used to construct and to retrieve 221// the MachineCodeForFunction object for the given function. 222// construct() -- Allocates and initializes for a given function and target 223// get() -- Returns a handle to the object. 224// This should not be called before "construct()" 225// for a given Function. 226// 227MachineFunction& 228MachineFunction::construct(const Function *Fn, const TargetMachine &Tar) 229{ 230 assert(Fn->getAnnotation(MF_AID) == 0 && 231 "Object already exists for this function!"); 232 MachineFunction* mcInfo = new MachineFunction(Fn, Tar); 233 Fn->addAnnotation(mcInfo); 234 return *mcInfo; 235} 236 237void MachineFunction::destruct(const Function *Fn) { 238 bool Deleted = Fn->deleteAnnotation(MF_AID); 239 assert(Deleted && "Machine code did not exist for function!"); 240} 241 242MachineFunction& MachineFunction::get(const Function *F) 243{ 244 MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID); 245 assert(mc && "Call construct() method first to allocate the object"); 246 return *mc; 247} 248 249void MachineFunction::clearSSARegMap() { 250 delete SSARegMapping; 251 SSARegMapping = 0; 252} 253 254//===----------------------------------------------------------------------===// 255// MachineFrameInfo implementation 256//===----------------------------------------------------------------------===// 257 258/// CreateStackObject - Create a stack object for a value of the specified type. 259/// 260int MachineFrameInfo::CreateStackObject(const Type *Ty, const TargetData &TD) { 261 return CreateStackObject(TD.getTypeSize(Ty), TD.getTypeAlignment(Ty)); 262} 263 264int MachineFrameInfo::CreateStackObject(const TargetRegisterClass *RC) { 265 return CreateStackObject(RC->getSize(), RC->getAlignment()); 266} 267 268 269void MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{ 270 int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea(); 271 272 for (unsigned i = 0, e = Objects.size(); i != e; ++i) { 273 const StackObject &SO = Objects[i]; 274 OS << " <fi #" << (int)(i-NumFixedObjects) << "> is "; 275 if (SO.Size == 0) 276 OS << "variable sized"; 277 else 278 OS << SO.Size << " byte" << (SO.Size != 1 ? "s" : " "); 279 280 if (i < NumFixedObjects) 281 OS << " fixed"; 282 if (i < NumFixedObjects || SO.SPOffset != -1) { 283 int Off = SO.SPOffset - ValOffset; 284 OS << " at location [SP"; 285 if (Off > 0) 286 OS << "+" << Off; 287 else if (Off < 0) 288 OS << Off; 289 OS << "]"; 290 } 291 OS << "\n"; 292 } 293 294 if (HasVarSizedObjects) 295 OS << " Stack frame contains variable sized objects\n"; 296} 297 298void MachineFrameInfo::dump(const MachineFunction &MF) const { 299 print(MF, std::cerr); 300} 301 302 303//===----------------------------------------------------------------------===// 304// MachineConstantPool implementation 305//===----------------------------------------------------------------------===// 306 307void MachineConstantPool::print(std::ostream &OS) const { 308 for (unsigned i = 0, e = Constants.size(); i != e; ++i) 309 OS << " <cp #" << i << "> is" << *(Value*)Constants[i] << "\n"; 310} 311 312void MachineConstantPool::dump() const { print(std::cerr); } 313 314//===----------------------------------------------------------------------===// 315// MachineFunctionInfo implementation 316//===----------------------------------------------------------------------===// 317 318static unsigned 319ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F, 320 unsigned &maxOptionalNumArgs) 321{ 322 const TargetFrameInfo &frameInfo = *target.getFrameInfo(); 323 324 unsigned maxSize = 0; 325 326 for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB) 327 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) 328 if (const CallInst *callInst = dyn_cast<CallInst>(I)) 329 { 330 unsigned numOperands = callInst->getNumOperands() - 1; 331 int numExtra = (int)numOperands-frameInfo.getNumFixedOutgoingArgs(); 332 if (numExtra <= 0) 333 continue; 334 335 unsigned sizeForThisCall = numExtra * 8; 336 337 if (maxSize < sizeForThisCall) 338 maxSize = sizeForThisCall; 339 340 if ((int)maxOptionalNumArgs < numExtra) 341 maxOptionalNumArgs = (unsigned) numExtra; 342 } 343 344 return maxSize; 345} 346 347// Align data larger than one L1 cache line on L1 cache line boundaries. 348// Align all smaller data on the next higher 2^x boundary (4, 8, ...), 349// but not higher than the alignment of the largest type we support 350// (currently a double word). -- see class TargetData). 351// 352// This function is similar to the corresponding function in EmitAssembly.cpp 353// but they are unrelated. This one does not align at more than a 354// double-word boundary whereas that one might. 355// 356inline unsigned 357SizeToAlignment(unsigned size, const TargetMachine& target) 358{ 359 const unsigned short cacheLineSize = 16; 360 if (size > (unsigned) cacheLineSize / 2) 361 return cacheLineSize; 362 else 363 for (unsigned sz=1; /*no condition*/; sz *= 2) 364 if (sz >= size || sz >= target.getTargetData().getDoubleAlignment()) 365 return sz; 366} 367 368 369void MachineFunctionInfo::CalculateArgSize() { 370 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(), 371 MF.getFunction(), 372 maxOptionalNumArgs); 373 staticStackSize = maxOptionalArgsSize 374 + MF.getTarget().getFrameInfo()->getMinStackFrameSize(); 375} 376 377int 378MachineFunctionInfo::computeOffsetforLocalVar(const Value* val, 379 unsigned &getPaddedSize, 380 unsigned sizeToUse) 381{ 382 if (sizeToUse == 0) { 383 // All integer types smaller than ints promote to 4 byte integers. 384 if (val->getType()->isIntegral() && val->getType()->getPrimitiveSize() < 4) 385 sizeToUse = 4; 386 else 387 sizeToUse = MF.getTarget().getTargetData().getTypeSize(val->getType()); 388 } 389 unsigned align = SizeToAlignment(sizeToUse, MF.getTarget()); 390 391 bool growUp; 392 int firstOffset = MF.getTarget().getFrameInfo()->getFirstAutomaticVarOffset(MF, 393 growUp); 394 int offset = growUp? firstOffset + getAutomaticVarsSize() 395 : firstOffset - (getAutomaticVarsSize() + sizeToUse); 396 397 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align); 398 getPaddedSize = sizeToUse + abs(aligned - offset); 399 400 return aligned; 401} 402 403 404int MachineFunctionInfo::allocateLocalVar(const Value* val, 405 unsigned sizeToUse) { 406 assert(! automaticVarsAreaFrozen && 407 "Size of auto vars area has been used to compute an offset so " 408 "no more automatic vars should be allocated!"); 409 410 // Check if we've allocated a stack slot for this value already 411 // 412 hash_map<const Value*, int>::const_iterator pair = offsets.find(val); 413 if (pair != offsets.end()) 414 return pair->second; 415 416 unsigned getPaddedSize; 417 unsigned offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse); 418 offsets[val] = offset; 419 incrementAutomaticVarsSize(getPaddedSize); 420 return offset; 421} 422 423int 424MachineFunctionInfo::allocateSpilledValue(const Type* type) 425{ 426 assert(! spillsAreaFrozen && 427 "Size of reg spills area has been used to compute an offset so " 428 "no more register spill slots should be allocated!"); 429 430 unsigned size = MF.getTarget().getTargetData().getTypeSize(type); 431 unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type); 432 433 bool growUp; 434 int firstOffset = MF.getTarget().getFrameInfo()->getRegSpillAreaOffset(MF, growUp); 435 436 int offset = growUp? firstOffset + getRegSpillsSize() 437 : firstOffset - (getRegSpillsSize() + size); 438 439 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align); 440 size += abs(aligned - offset); // include alignment padding in size 441 442 incrementRegSpillsSize(size); // update size of reg. spills area 443 444 return aligned; 445} 446 447int 448MachineFunctionInfo::pushTempValue(unsigned size) 449{ 450 unsigned align = SizeToAlignment(size, MF.getTarget()); 451 452 bool growUp; 453 int firstOffset = MF.getTarget().getFrameInfo()->getTmpAreaOffset(MF, growUp); 454 455 int offset = growUp? firstOffset + currentTmpValuesSize 456 : firstOffset - (currentTmpValuesSize + size); 457 458 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, 459 align); 460 size += abs(aligned - offset); // include alignment padding in size 461 462 incrementTmpAreaSize(size); // update "current" size of tmp area 463 464 return aligned; 465} 466 467void MachineFunctionInfo::popAllTempValues() { 468 resetTmpAreaSize(); // clear tmp area to reuse 469} 470