MachineFunction.cpp revision 3029f920519e0871a5aad5d7c592281093953733
16b9445389a226b4ac97ceb89a34ee1a5bf921714Chris Lattner//===-- MachineFunction.cpp -----------------------------------------------===// 276d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 5b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// This file was developed by the LLVM research group and is distributed under 6b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 976d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos// 106b9445389a226b4ac97ceb89a34ee1a5bf921714Chris Lattner// Collect native machine code information for a function. This allows 116b9445389a226b4ac97ceb89a34ee1a5bf921714Chris Lattner// target-specific information about the generated code to be stored with each 126b9445389a226b4ac97ceb89a34ee1a5bf921714Chris Lattner// function. 136b9445389a226b4ac97ceb89a34ee1a5bf921714Chris Lattner// 146b9445389a226b4ac97ceb89a34ee1a5bf921714Chris Lattner//===----------------------------------------------------------------------===// 15f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner 1616c45e9de896ea37d48d093dbe02fc9a4c1b9f8fChris Lattner#include "llvm/CodeGen/MachineFunctionPass.h" 17831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner#include "llvm/CodeGen/MachineInstr.h" 18831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner#include "llvm/CodeGen/SSARegMap.h" 19eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner#include "llvm/CodeGen/MachineFrameInfo.h" 204d149cdae1553426f49623fdae215d481d56d955Chris Lattner#include "llvm/CodeGen/MachineConstantPool.h" 2116c45e9de896ea37d48d093dbe02fc9a4c1b9f8fChris Lattner#include "llvm/CodeGen/Passes.h" 22f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner#include "llvm/Target/TargetMachine.h" 238bd66e690779c838db51f55cf0b31d7206b3b659Chris Lattner#include "llvm/Target/TargetFrameInfo.h" 242fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner#include "llvm/Function.h" 2547b14a4a6a455c7be169cfd312fcbe796f0ad426Misha Brukman#include "llvm/Instructions.h" 26551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/LeakDetector.h" 27551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/GraphWriter.h" 28851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#include "llvm/Config/config.h" 2971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos#include <fstream> 30954da37bb492b519f5c31dc360f2a142567e08b4Reid Spencer#include <iostream> 3171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos#include <sstream> 32792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattner 3307f32d48f1e16bcdc621985549548a5849215238Chris Lattnerusing namespace llvm; 34f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner 35e316efc0e74442cffdda4889d30dca4fffcad749Chris Lattnerstatic AnnotationID MF_AID( 3676d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos AnnotationManager::getID("CodeGen::MachineCodeForFunction")); 37f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner 38227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner 39227c3d355b017393963a690f9f27d1de7fa359bcChris Lattnernamespace { 4016c45e9de896ea37d48d093dbe02fc9a4c1b9f8fChris Lattner struct Printer : public MachineFunctionPass { 4109caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke std::ostream *OS; 42d4baf0f74ca54dcbb61d199f4b184d6012d7179fChris Lattner const std::string Banner; 4309caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke 4409caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke Printer (std::ostream *_OS, const std::string &_Banner) : 4509caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke OS (_OS), Banner (_Banner) { } 4609caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke 471049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner const char *getPassName() const { return "MachineFunction Printer"; } 481049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner 491049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner virtual void getAnalysisUsage(AnalysisUsage &AU) const { 501049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner AU.setPreservesAll(); 511049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner } 521049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner 5316c45e9de896ea37d48d093dbe02fc9a4c1b9f8fChris Lattner bool runOnMachineFunction(MachineFunction &MF) { 5409caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke (*OS) << Banner; 5509caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke MF.print (*OS); 561049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner return false; 571049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner } 581049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner }; 59227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner} 60227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner 6109caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke/// Returns a newly-created MachineFunction Printer pass. The default output 6209caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke/// stream is std::cerr; the default banner is empty. 6309caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke/// 6409caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian GaekeFunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS, 65ce9c41e77a2ec75d48a173b9baf0f4a3bf49fac7Chris Lattner const std::string &Banner){ 6609caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke return new Printer(OS, Banner); 671049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner} 681049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner 69c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenosnamespace { 70c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos struct Deleter : public MachineFunctionPass { 71c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos const char *getPassName() const { return "Machine Code Deleter"; } 72c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos 73c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos bool runOnMachineFunction(MachineFunction &MF) { 74c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos // Delete the annotation from the function now. 75c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos MachineFunction::destruct(MF.getFunction()); 76c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos return true; 77c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos } 78c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos }; 79c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos} 80c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos 81c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos/// MachineCodeDeletion Pass - This pass deletes all of the machine code for 82c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos/// the current function, which should happen after the function has been 83c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos/// emitted to a .s file or to memory. 84c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis EvlogimenosFunctionPass *llvm::createMachineCodeDeleter() { 85c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos return new Deleter(); 86c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos} 87c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos 88c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos 89c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos 90227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner//===---------------------------------------------------------------------===// 91227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner// MachineFunction implementation 92227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner//===---------------------------------------------------------------------===// 939d5d7598db72c00a0fb89dc77198e4f6ebc5294dChris Lattner 94bca81448ac8e19c588c9a4ad16fc70732b76327cChris LattnerMachineBasicBlock* ilist_traits<MachineBasicBlock>::createSentinel() { 9576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos MachineBasicBlock* dummy = new MachineBasicBlock(); 9676d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos LeakDetector::removeGarbageObject(dummy); 9776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos return dummy; 98792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattner} 99792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattner 100792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattnervoid ilist_traits<MachineBasicBlock>::transferNodesFromList( 10176d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos iplist<MachineBasicBlock, ilist_traits<MachineBasicBlock> >& toList, 10276d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos ilist_iterator<MachineBasicBlock> first, 1039d5d7598db72c00a0fb89dc77198e4f6ebc5294dChris Lattner ilist_iterator<MachineBasicBlock> last) { 10476d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos if (Parent != toList.Parent) 10576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos for (; first != last; ++first) 10676d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos first->Parent = toList.Parent; 107792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattner} 108227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner 1091049164aa6b06d91d9b3b557a9a213eaf3f6319aChris LattnerMachineFunction::MachineFunction(const Function *F, 110955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner const TargetMachine &TM) 111f99c232506f134107f9ae02c118fe31685e6b06cJim Laskey : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0) { 112b7825bc72534573c444e646dd1c3999ff787bbadMisha Brukman SSARegMapping = new SSARegMap(); 113ad8281607f066c2cce5c3625009d8ee0761dbf35Chris Lattner MFInfo = 0; 114eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner FrameInfo = new MachineFrameInfo(); 1153029f920519e0871a5aad5d7c592281093953733Chris Lattner ConstantPool = new MachineConstantPool(TM.getTargetData()); 11617fb34bf8cd10a798c9206eeef3bff151b4d3688Tanya Lattner BasicBlocks.Parent = this; 117831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner} 118831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner 11976d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis EvlogimenosMachineFunction::~MachineFunction() { 1204b9a4006748b8d72a04504a5fc1f5daa73bf69f9Chris Lattner BasicBlocks.clear(); 121831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner delete SSARegMapping; 122955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner delete MFInfo; 123955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner delete FrameInfo; 1244d149cdae1553426f49623fdae215d481d56d955Chris Lattner delete ConstantPool; 125ce9c41e77a2ec75d48a173b9baf0f4a3bf49fac7Chris Lattner delete[] UsedPhysRegs; 1261049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner} 1271049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner 1281049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattnervoid MachineFunction::dump() const { print(std::cerr); } 1291049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner 1301049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattnervoid MachineFunction::print(std::ostream &OS) const { 13147b716483ef2d057c8a0015af20685755e606d0dBrian Gaeke OS << "# Machine code for " << Fn->getName () << "():\n"; 132955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner 133955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner // Print Frame Information 1349085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner getFrameInfo()->print(*this, OS); 1354d149cdae1553426f49623fdae215d481d56d955Chris Lattner 1364d149cdae1553426f49623fdae215d481d56d955Chris Lattner // Print Constant Pool 1374d149cdae1553426f49623fdae215d481d56d955Chris Lattner getConstantPool()->print(OS); 138a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner 139a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner const MRegisterInfo *MRI = getTarget().getRegisterInfo(); 140a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner 141a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner if (livein_begin() != livein_end()) { 142a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner OS << "Live Ins:"; 143a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) { 144a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner if (MRI) 145a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner OS << " " << MRI->getName(I->first); 146a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner else 147a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner OS << " Reg #" << I->first; 148a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner } 149a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner OS << "\n"; 150a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner } 151a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner if (liveout_begin() != liveout_end()) { 152a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner OS << "Live Outs:"; 153a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I) 154a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner if (MRI) 155a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner OS << " " << MRI->getName(*I); 156a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner else 157a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner OS << " Reg #" << *I; 158a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner OS << "\n"; 159a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner } 160a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner 16190421cd8f982b4fe38d8f5992423e4f63074869fBrian Gaeke for (const_iterator BB = begin(); BB != end(); ++BB) 16290421cd8f982b4fe38d8f5992423e4f63074869fBrian Gaeke BB->print(OS); 16347b716483ef2d057c8a0015af20685755e606d0dBrian Gaeke 16447b716483ef2d057c8a0015af20685755e606d0dBrian Gaeke OS << "\n# End machine code for " << Fn->getName () << "().\n\n"; 1651049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner} 1661049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner 16771bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos/// CFGOnly flag - This is used to control whether or not the CFG graph printer 16871bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos/// prints out the contents of basic blocks or not. This is acceptable because 16971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos/// this code is only really used for debugging purposes. 17071bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos/// 17171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenosstatic bool CFGOnly = false; 17271bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 17371bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenosnamespace llvm { 17476d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos template<> 17576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits { 17676d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos static std::string getGraphName(const MachineFunction *F) { 17776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos return "CFG for '" + F->getFunction()->getName() + "' function"; 17876d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos } 17971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 18076d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos static std::string getNodeLabel(const MachineBasicBlock *Node, 18176d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos const MachineFunction *Graph) { 18276d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos if (CFGOnly && Node->getBasicBlock() && 18376d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos !Node->getBasicBlock()->getName().empty()) 18476d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos return Node->getBasicBlock()->getName() + ":"; 18571bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 18676d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos std::ostringstream Out; 18776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos if (CFGOnly) { 18876d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos Out << Node->getNumber() << ':'; 18976d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos return Out.str(); 19076d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos } 19171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 19276d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos Node->print(Out); 19371bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 19476d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos std::string OutStr = Out.str(); 19576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 19671bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 19776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos // Process string output to make it nicer... 19876d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos for (unsigned i = 0; i != OutStr.length(); ++i) 19976d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos if (OutStr[i] == '\n') { // Left justify 20076d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos OutStr[i] = '\\'; 20176d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos OutStr.insert(OutStr.begin()+i+1, 'l'); 20276d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos } 20376d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos return OutStr; 20476d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos } 20576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos }; 20671bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos} 20771bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 20871bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenosvoid MachineFunction::viewCFG() const 20971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos{ 210851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#ifndef NDEBUG 21171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot"; 21271bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos std::cerr << "Writing '" << Filename << "'... "; 21371bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos std::ofstream F(Filename.c_str()); 21476d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos 21571bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos if (!F) { 21671bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos std::cerr << " error opening file for writing!\n"; 21771bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos return; 21871bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos } 21971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 22071bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos WriteGraph(F, this); 22171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos F.close(); 22271bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos std::cerr << "\n"; 22371bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 224851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#ifdef HAVE_GRAPHVIZ 225851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey std::cerr << "Running 'Graphviz' program... " << std::flush; 226851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey if (system((LLVM_PATH_GRAPHVIZ " " + Filename).c_str())) { 227851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey std::cerr << "Error viewing graph: 'Graphviz' not in path?\n"; 228851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey } else { 229851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey system(("rm " + Filename).c_str()); 230851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey return; 231851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey } 232851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#endif // HAVE_GRAPHVIZ 233851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey 234851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#ifdef HAVE_GV 23571bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos std::cerr << "Running 'dot' program... " << std::flush; 23671bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename 23771bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos + " > /tmp/cfg.tempgraph.ps").c_str())) { 23871bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos std::cerr << "Error running dot: 'dot' not in path?\n"; 23971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos } else { 24071bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos std::cerr << "\n"; 24171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos system("gv /tmp/cfg.tempgraph.ps"); 24271bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos } 24371bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str()); 244851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey return; 245851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#endif // HAVE_GV 246851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#endif // NDEBUG 247851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey std::cerr << "MachineFunction::viewCFG is only available in debug builds on " 248851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey << "systems with Graphviz or gv!\n"; 249851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey 250851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#ifndef NDEBUG 251851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey system(("rm " + Filename).c_str()); 252851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#endif 25371bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos} 25471bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 25571bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenosvoid MachineFunction::viewCFGOnly() const 25671bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos{ 25771bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos CFGOnly = true; 25871bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos viewCFG(); 25971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos CFGOnly = false; 26071bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos} 26171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos 262f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner// The next two methods are used to construct and to retrieve 2632fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// the MachineCodeForFunction object for the given function. 2642fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// construct() -- Allocates and initializes for a given function and target 265f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner// get() -- Returns a handle to the object. 266f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner// This should not be called before "construct()" 2672fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// for a given Function. 26876d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos// 269fce1143bcfa73f61845002fa50473d1a01384202Misha BrukmanMachineFunction& 270335d5c399b52c2507ad11048310edc51462f4811Chris LattnerMachineFunction::construct(const Function *Fn, const TargetMachine &Tar) 27189e2da034a02cd33b306b59dbbf607650cca1c4cVikram S. Adve{ 272e316efc0e74442cffdda4889d30dca4fffcad749Chris Lattner assert(Fn->getAnnotation(MF_AID) == 0 && 2732fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner "Object already exists for this function!"); 274335d5c399b52c2507ad11048310edc51462f4811Chris Lattner MachineFunction* mcInfo = new MachineFunction(Fn, Tar); 275335d5c399b52c2507ad11048310edc51462f4811Chris Lattner Fn->addAnnotation(mcInfo); 276f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner return *mcInfo; 277f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner} 278f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner 27916c45e9de896ea37d48d093dbe02fc9a4c1b9f8fChris Lattnervoid MachineFunction::destruct(const Function *Fn) { 280e316efc0e74442cffdda4889d30dca4fffcad749Chris Lattner bool Deleted = Fn->deleteAnnotation(MF_AID); 2812fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner assert(Deleted && "Machine code did not exist for function!"); 282f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner} 283f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner 284335d5c399b52c2507ad11048310edc51462f4811Chris LattnerMachineFunction& MachineFunction::get(const Function *F) 28589e2da034a02cd33b306b59dbbf607650cca1c4cVikram S. Adve{ 286e316efc0e74442cffdda4889d30dca4fffcad749Chris Lattner MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID); 287f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner assert(mc && "Call construct() method first to allocate the object"); 288f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner return *mc; 289f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner} 290f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner 291831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattnervoid MachineFunction::clearSSARegMap() { 292831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner delete SSARegMapping; 293831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner SSARegMapping = 0; 294831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner} 295831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner 296955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner//===----------------------------------------------------------------------===// 297eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner// MachineFrameInfo implementation 298955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner//===----------------------------------------------------------------------===// 299955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner 3004d149cdae1553426f49623fdae215d481d56d955Chris Lattner/// CreateStackObject - Create a stack object for a value of the specified type. 3014d149cdae1553426f49623fdae215d481d56d955Chris Lattner/// 3024d149cdae1553426f49623fdae215d481d56d955Chris Lattnerint MachineFrameInfo::CreateStackObject(const Type *Ty, const TargetData &TD) { 303edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman return CreateStackObject((unsigned)TD.getTypeSize(Ty), 30428696bee024805a6b191cfe12e1a24784dae8aa7Chris Lattner TD.getTypeAlignment(Ty)); 3054d149cdae1553426f49623fdae215d481d56d955Chris Lattner} 3064d149cdae1553426f49623fdae215d481d56d955Chris Lattner 3074d149cdae1553426f49623fdae215d481d56d955Chris Lattner 3089085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattnervoid MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{ 30962d6ad2cee0e6b7fa653c8903a951f8497b6da3aChris Lattner int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea(); 3109085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner 311955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner for (unsigned i = 0, e = Objects.size(); i != e; ++i) { 312955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner const StackObject &SO = Objects[i]; 3130db07092a7aaeeaa0722799d9f533be3b782d362Chris Lattner OS << " <fi #" << (int)(i-NumFixedObjects) << ">: "; 314955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner if (SO.Size == 0) 315955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner OS << "variable sized"; 316955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner else 3170db07092a7aaeeaa0722799d9f533be3b782d362Chris Lattner OS << "size is " << SO.Size << " byte" << (SO.Size != 1 ? "s," : ","); 3180db07092a7aaeeaa0722799d9f533be3b782d362Chris Lattner OS << " alignment is " << SO.Alignment << " byte" 3190db07092a7aaeeaa0722799d9f533be3b782d362Chris Lattner << (SO.Alignment != 1 ? "s," : ","); 32076d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos 321955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner if (i < NumFixedObjects) 322955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner OS << " fixed"; 323955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner if (i < NumFixedObjects || SO.SPOffset != -1) { 3247f7bbc2fdb833485ac3d865a405fd948e58e8ddbChris Lattner int Off = SO.SPOffset - ValOffset; 325955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner OS << " at location [SP"; 3269085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner if (Off > 0) 32776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos OS << "+" << Off; 3289085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner else if (Off < 0) 32976d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos OS << Off; 330955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner OS << "]"; 331955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner } 332955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner OS << "\n"; 333955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner } 334955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner 335955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner if (HasVarSizedObjects) 336955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner OS << " Stack frame contains variable sized objects\n"; 337955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner} 338955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner 3399085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattnervoid MachineFrameInfo::dump(const MachineFunction &MF) const { 3409085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner print(MF, std::cerr); 3419085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner} 342955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner 343955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner 344955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner//===----------------------------------------------------------------------===// 3454d149cdae1553426f49623fdae215d481d56d955Chris Lattner// MachineConstantPool implementation 3464d149cdae1553426f49623fdae215d481d56d955Chris Lattner//===----------------------------------------------------------------------===// 3474d149cdae1553426f49623fdae215d481d56d955Chris Lattner 3483029f920519e0871a5aad5d7c592281093953733Chris Lattner/// getConstantPoolIndex - Create a new entry in the constant pool or return 3493029f920519e0871a5aad5d7c592281093953733Chris Lattner/// an existing one. User must specify an alignment in bytes for the object. 3503029f920519e0871a5aad5d7c592281093953733Chris Lattner/// 3513029f920519e0871a5aad5d7c592281093953733Chris Lattnerunsigned MachineConstantPool::getConstantPoolIndex(Constant *C, 3523029f920519e0871a5aad5d7c592281093953733Chris Lattner unsigned Alignment) { 3533029f920519e0871a5aad5d7c592281093953733Chris Lattner assert(Alignment && "Alignment must be specified!"); 3543029f920519e0871a5aad5d7c592281093953733Chris Lattner if (Alignment > PoolAlignment) PoolAlignment = Alignment; 3553029f920519e0871a5aad5d7c592281093953733Chris Lattner 3563029f920519e0871a5aad5d7c592281093953733Chris Lattner // Check to see if we already have this constant. 3573029f920519e0871a5aad5d7c592281093953733Chris Lattner // 3583029f920519e0871a5aad5d7c592281093953733Chris Lattner // FIXME, this could be made much more efficient for large constant pools. 3593029f920519e0871a5aad5d7c592281093953733Chris Lattner unsigned AlignMask = (1 << Alignment)-1; 3603029f920519e0871a5aad5d7c592281093953733Chris Lattner for (unsigned i = 0, e = Constants.size(); i != e; ++i) 3613029f920519e0871a5aad5d7c592281093953733Chris Lattner if (Constants[i].Val == C && (Constants[i].Offset & AlignMask) == 0) 3623029f920519e0871a5aad5d7c592281093953733Chris Lattner return i; 3633029f920519e0871a5aad5d7c592281093953733Chris Lattner 3643029f920519e0871a5aad5d7c592281093953733Chris Lattner unsigned Offset = 0; 3653029f920519e0871a5aad5d7c592281093953733Chris Lattner if (!Constants.empty()) { 3663029f920519e0871a5aad5d7c592281093953733Chris Lattner Offset = Constants.back().Offset; 3673029f920519e0871a5aad5d7c592281093953733Chris Lattner Offset += TD.getTypeSize(Constants.back().Val->getType()); 3683029f920519e0871a5aad5d7c592281093953733Chris Lattner Offset = (Offset+AlignMask)&~AlignMask; 3693029f920519e0871a5aad5d7c592281093953733Chris Lattner } 3703029f920519e0871a5aad5d7c592281093953733Chris Lattner 3713029f920519e0871a5aad5d7c592281093953733Chris Lattner Constants.push_back(MachineConstantPoolEntry(C, Offset)); 3723029f920519e0871a5aad5d7c592281093953733Chris Lattner return Constants.size()-1; 3733029f920519e0871a5aad5d7c592281093953733Chris Lattner} 3743029f920519e0871a5aad5d7c592281093953733Chris Lattner 3753029f920519e0871a5aad5d7c592281093953733Chris Lattner 3764d149cdae1553426f49623fdae215d481d56d955Chris Lattnervoid MachineConstantPool::print(std::ostream &OS) const { 377b8973bd8f50d7321635e1e07b81a880a0828d185Evan Cheng for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 378fa77d43ba1d91ed39f46e11caeb28dcabae9e193Chris Lattner OS << " <cp #" << i << "> is" << *(Value*)Constants[i].Val; 3793029f920519e0871a5aad5d7c592281093953733Chris Lattner OS << " , offset=" << Constants[i].Offset; 380b8973bd8f50d7321635e1e07b81a880a0828d185Evan Cheng OS << "\n"; 381b8973bd8f50d7321635e1e07b81a880a0828d185Evan Cheng } 3824d149cdae1553426f49623fdae215d481d56d955Chris Lattner} 3834d149cdae1553426f49623fdae215d481d56d955Chris Lattner 3844d149cdae1553426f49623fdae215d481d56d955Chris Lattnervoid MachineConstantPool::dump() const { print(std::cerr); } 385