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/MachineFrameInfo.h" 20 #include "llvm/CodeGen/MachineConstantPool.h" 21 #include "llvm/CodeGen/Passes.h" 22 #include "llvm/Target/TargetMachine.h" 23 #include "llvm/Target/TargetFrameInfo.h" 24 #include "llvm/Function.h" 25 #include "llvm/Instructions.h" 26 #include "llvm/Support/LeakDetector.h" 27 #include "llvm/Support/GraphWriter.h" 28 #include <fstream> 29 #include <iostream> 30 #include <sstream> 31 32 using namespace llvm; 33 34 static AnnotationID MF_AID( 35 AnnotationManager::getID("CodeGen::MachineCodeForFunction")); 36 37 38 namespace { 39 struct Printer : public MachineFunctionPass { 40 std::ostream *OS; 41 const std::string Banner; 42 43 Printer (std::ostream *_OS, const std::string &_Banner) : 44 OS (_OS), Banner (_Banner) { } 45 46 const char *getPassName() const { return "MachineFunction Printer"; } 47 48 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 49 AU.setPreservesAll(); 50 } 51 52 bool runOnMachineFunction(MachineFunction &MF) { 53 (*OS) << Banner; 54 MF.print (*OS); 55 return false; 56 } 57 }; 58 } 59 60 /// Returns a newly-created MachineFunction Printer pass. The default output 61 /// stream is std::cerr; the default banner is empty. 62 /// 63 FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS, 64 const std::string &Banner){ 65 return new Printer(OS, Banner); 66 } 67 68 namespace { 69 struct Deleter : public MachineFunctionPass { 70 const char *getPassName() const { return "Machine Code Deleter"; } 71 72 bool runOnMachineFunction(MachineFunction &MF) { 73 // Delete the annotation from the function now. 74 MachineFunction::destruct(MF.getFunction()); 75 return true; 76 } 77 }; 78 } 79 80 /// MachineCodeDeletion Pass - This pass deletes all of the machine code for 81 /// the current function, which should happen after the function has been 82 /// emitted to a .s file or to memory. 83 FunctionPass *llvm::createMachineCodeDeleter() { 84 return new Deleter(); 85 } 86 87 88 89 //===---------------------------------------------------------------------===// 90 // MachineFunction implementation 91 //===---------------------------------------------------------------------===// 92 93 MachineBasicBlock* ilist_traits<MachineBasicBlock>::createSentinel() { 94 MachineBasicBlock* dummy = new MachineBasicBlock(); 95 LeakDetector::removeGarbageObject(dummy); 96 return dummy; 97 } 98 99 void ilist_traits<MachineBasicBlock>::transferNodesFromList( 100 iplist<MachineBasicBlock, ilist_traits<MachineBasicBlock> >& toList, 101 ilist_iterator<MachineBasicBlock> first, 102 ilist_iterator<MachineBasicBlock> last) { 103 if (Parent != toList.Parent) 104 for (; first != last; ++first) 105 first->Parent = toList.Parent; 106 } 107 108 MachineFunction::MachineFunction(const Function *F, 109 const TargetMachine &TM) 110 : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0) { 111 SSARegMapping = new SSARegMap(); 112 MFInfo = 0; 113 FrameInfo = new MachineFrameInfo(); 114 ConstantPool = new MachineConstantPool(); 115 BasicBlocks.Parent = this; 116 } 117 118 MachineFunction::~MachineFunction() { 119 BasicBlocks.clear(); 120 delete SSARegMapping; 121 delete MFInfo; 122 delete FrameInfo; 123 delete ConstantPool; 124 delete[] UsedPhysRegs; 125 } 126 127 void MachineFunction::dump() const { print(std::cerr); } 128 129 void MachineFunction::print(std::ostream &OS) const { 130 OS << "# Machine code for " << Fn->getName () << "():\n"; 131 132 // Print Frame Information 133 getFrameInfo()->print(*this, OS); 134 135 // Print Constant Pool 136 getConstantPool()->print(OS); 137 138 const MRegisterInfo *MRI = getTarget().getRegisterInfo(); 139 140 if (livein_begin() != livein_end()) { 141 OS << "Live Ins:"; 142 for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) { 143 if (MRI) 144 OS << " " << MRI->getName(I->first); 145 else 146 OS << " Reg #" << I->first; 147 } 148 OS << "\n"; 149 } 150 if (liveout_begin() != liveout_end()) { 151 OS << "Live Outs:"; 152 for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I) 153 if (MRI) 154 OS << " " << MRI->getName(*I); 155 else 156 OS << " Reg #" << *I; 157 OS << "\n"; 158 } 159 160 for (const_iterator BB = begin(); BB != end(); ++BB) 161 BB->print(OS); 162 163 OS << "\n# End machine code for " << Fn->getName () << "().\n\n"; 164 } 165 166 /// CFGOnly flag - This is used to control whether or not the CFG graph printer 167 /// prints out the contents of basic blocks or not. This is acceptable because 168 /// this code is only really used for debugging purposes. 169 /// 170 static bool CFGOnly = false; 171 172 namespace llvm { 173 template<> 174 struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits { 175 static std::string getGraphName(const MachineFunction *F) { 176 return "CFG for '" + F->getFunction()->getName() + "' function"; 177 } 178 179 static std::string getNodeLabel(const MachineBasicBlock *Node, 180 const MachineFunction *Graph) { 181 if (CFGOnly && Node->getBasicBlock() && 182 !Node->getBasicBlock()->getName().empty()) 183 return Node->getBasicBlock()->getName() + ":"; 184 185 std::ostringstream Out; 186 if (CFGOnly) { 187 Out << Node->getNumber() << ':'; 188 return Out.str(); 189 } 190 191 Node->print(Out); 192 193 std::string OutStr = Out.str(); 194 if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 195 196 // Process string output to make it nicer... 197 for (unsigned i = 0; i != OutStr.length(); ++i) 198 if (OutStr[i] == '\n') { // Left justify 199 OutStr[i] = '\\'; 200 OutStr.insert(OutStr.begin()+i+1, 'l'); 201 } 202 return OutStr; 203 } 204 }; 205 } 206 207 void MachineFunction::viewCFG() const 208 { 209 std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot"; 210 std::cerr << "Writing '" << Filename << "'... "; 211 std::ofstream F(Filename.c_str()); 212 213 if (!F) { 214 std::cerr << " error opening file for writing!\n"; 215 return; 216 } 217 218 WriteGraph(F, this); 219 F.close(); 220 std::cerr << "\n"; 221 222 std::cerr << "Running 'dot' program... " << std::flush; 223 if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename 224 + " > /tmp/cfg.tempgraph.ps").c_str())) { 225 std::cerr << "Error running dot: 'dot' not in path?\n"; 226 } else { 227 std::cerr << "\n"; 228 system("gv /tmp/cfg.tempgraph.ps"); 229 } 230 system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str()); 231 } 232 233 void MachineFunction::viewCFGOnly() const 234 { 235 CFGOnly = true; 236 viewCFG(); 237 CFGOnly = false; 238 } 239 240 // The next two methods are used to construct and to retrieve 241 // the MachineCodeForFunction object for the given function. 242 // construct() -- Allocates and initializes for a given function and target 243 // get() -- Returns a handle to the object. 244 // This should not be called before "construct()" 245 // for a given Function. 246 // 247 MachineFunction& 248 MachineFunction::construct(const Function *Fn, const TargetMachine &Tar) 249 { 250 assert(Fn->getAnnotation(MF_AID) == 0 && 251 "Object already exists for this function!"); 252 MachineFunction* mcInfo = new MachineFunction(Fn, Tar); 253 Fn->addAnnotation(mcInfo); 254 return *mcInfo; 255 } 256 257 void MachineFunction::destruct(const Function *Fn) { 258 bool Deleted = Fn->deleteAnnotation(MF_AID); 259 assert(Deleted && "Machine code did not exist for function!"); 260 } 261 262 MachineFunction& MachineFunction::get(const Function *F) 263 { 264 MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID); 265 assert(mc && "Call construct() method first to allocate the object"); 266 return *mc; 267 } 268 269 void MachineFunction::clearSSARegMap() { 270 delete SSARegMapping; 271 SSARegMapping = 0; 272 } 273 274 //===----------------------------------------------------------------------===// 275 // MachineFrameInfo implementation 276 //===----------------------------------------------------------------------===// 277 278 /// CreateStackObject - Create a stack object for a value of the specified type. 279 /// 280 int MachineFrameInfo::CreateStackObject(const Type *Ty, const TargetData &TD) { 281 return CreateStackObject((unsigned)TD.getTypeSize(Ty), 282 TD.getTypeAlignment(Ty)); 283 } 284 285 286 void MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{ 287 int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea(); 288 289 for (unsigned i = 0, e = Objects.size(); i != e; ++i) { 290 const StackObject &SO = Objects[i]; 291 OS << " <fi #" << (int)(i-NumFixedObjects) << ">: "; 292 if (SO.Size == 0) 293 OS << "variable sized"; 294 else 295 OS << "size is " << SO.Size << " byte" << (SO.Size != 1 ? "s," : ","); 296 OS << " alignment is " << SO.Alignment << " byte" 297 << (SO.Alignment != 1 ? "s," : ","); 298 299 if (i < NumFixedObjects) 300 OS << " fixed"; 301 if (i < NumFixedObjects || SO.SPOffset != -1) { 302 int Off = SO.SPOffset - ValOffset; 303 OS << " at location [SP"; 304 if (Off > 0) 305 OS << "+" << Off; 306 else if (Off < 0) 307 OS << Off; 308 OS << "]"; 309 } 310 OS << "\n"; 311 } 312 313 if (HasVarSizedObjects) 314 OS << " Stack frame contains variable sized objects\n"; 315 } 316 317 void MachineFrameInfo::dump(const MachineFunction &MF) const { 318 print(MF, std::cerr); 319 } 320 321 322 //===----------------------------------------------------------------------===// 323 // MachineConstantPool implementation 324 //===----------------------------------------------------------------------===// 325 326 void MachineConstantPool::print(std::ostream &OS) const { 327 for (unsigned i = 0, e = Constants.size(); i != e; ++i) 328 OS << " <cp #" << i << "> is" << *(Value*)Constants[i] << "\n"; 329 } 330 331 void MachineConstantPool::dump() const { print(std::cerr); } 332