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