MachineFunction.cpp revision d6594ae54cfde4db4d30272192645c0a45fb9902
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"
2137efe6764568a3829fee26aba532283131d1a104Nate Begeman#include "llvm/CodeGen/MachineJumpTableInfo.h"
2216c45e9de896ea37d48d093dbe02fc9a4c1b9f8fChris Lattner#include "llvm/CodeGen/Passes.h"
2307000c6f01d8f57170f2d4c77a86d934bdc5c696Owen Anderson#include "llvm/Target/TargetData.h"
24f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner#include "llvm/Target/TargetMachine.h"
258bd66e690779c838db51f55cf0b31d7206b3b659Chris Lattner#include "llvm/Target/TargetFrameInfo.h"
262fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner#include "llvm/Function.h"
2747b14a4a6a455c7be169cfd312fcbe796f0ad426Misha Brukman#include "llvm/Instructions.h"
28551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/LeakDetector.h"
29551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/GraphWriter.h"
30a4f0b3a084d120cfc5b5bb06f64b222f5cb72740Chris Lattner#include "llvm/Support/Compiler.h"
31851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#include "llvm/Config/config.h"
3271bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos#include <fstream>
33954da37bb492b519f5c31dc360f2a142567e08b4Reid Spencer#include <iostream>
3471bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos#include <sstream>
35792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattner
3607f32d48f1e16bcdc621985549548a5849215238Chris Lattnerusing namespace llvm;
37f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner
38e316efc0e74442cffdda4889d30dca4fffcad749Chris Lattnerstatic AnnotationID MF_AID(
3976d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
40f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner
41efb9b813fa74d3134dd185df10f6577ceab72bcdChris Lattner// Out of line virtual function to home classes.
42efb9b813fa74d3134dd185df10f6577ceab72bcdChris Lattnervoid MachineFunctionPass::virtfn() {}
43227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner
44227c3d355b017393963a690f9f27d1de7fa359bcChris Lattnernamespace {
45f8c68f694c25b1ae8c0e5adb2a19432cb405d232Chris Lattner  struct VISIBILITY_HIDDEN Printer : public MachineFunctionPass {
4609caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke    std::ostream *OS;
47d4baf0f74ca54dcbb61d199f4b184d6012d7179fChris Lattner    const std::string Banner;
4809caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke
4909caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke    Printer (std::ostream *_OS, const std::string &_Banner) :
5009caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke      OS (_OS), Banner (_Banner) { }
5109caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke
521049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner    const char *getPassName() const { return "MachineFunction Printer"; }
531049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner
541049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
551049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner      AU.setPreservesAll();
561049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner    }
571049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner
5816c45e9de896ea37d48d093dbe02fc9a4c1b9f8fChris Lattner    bool runOnMachineFunction(MachineFunction &MF) {
5909caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke      (*OS) << Banner;
6009caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke      MF.print (*OS);
611049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner      return false;
621049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner    }
631049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner  };
64227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner}
65227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner
6609caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke/// Returns a newly-created MachineFunction Printer pass. The default output
6709caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke/// stream is std::cerr; the default banner is empty.
6809caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke///
6909caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian GaekeFunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS,
70ce9c41e77a2ec75d48a173b9baf0f4a3bf49fac7Chris Lattner                                                     const std::string &Banner){
7109caa3751f3c53a8c8a7a81c2a60d6c8ddf5a980Brian Gaeke  return new Printer(OS, Banner);
721049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner}
731049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner
74c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenosnamespace {
75f8c68f694c25b1ae8c0e5adb2a19432cb405d232Chris Lattner  struct VISIBILITY_HIDDEN Deleter : public MachineFunctionPass {
76c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos    const char *getPassName() const { return "Machine Code Deleter"; }
77c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos
78c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos    bool runOnMachineFunction(MachineFunction &MF) {
79c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos      // Delete the annotation from the function now.
80c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos      MachineFunction::destruct(MF.getFunction());
81c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos      return true;
82c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos    }
83c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos  };
84c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos}
85c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos
86c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos/// MachineCodeDeletion Pass - This pass deletes all of the machine code for
87c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos/// the current function, which should happen after the function has been
88c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos/// emitted to a .s file or to memory.
89c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis EvlogimenosFunctionPass *llvm::createMachineCodeDeleter() {
90c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos  return new Deleter();
91c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos}
92c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos
93c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos
94c81efdc59cd2ce5410cefd7ab5cb52cfd7ac3aadAlkis Evlogimenos
95227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner//===---------------------------------------------------------------------===//
96227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner// MachineFunction implementation
97227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner//===---------------------------------------------------------------------===//
989d5d7598db72c00a0fb89dc77198e4f6ebc5294dChris Lattner
99bca81448ac8e19c588c9a4ad16fc70732b76327cChris LattnerMachineBasicBlock* ilist_traits<MachineBasicBlock>::createSentinel() {
10076d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  MachineBasicBlock* dummy = new MachineBasicBlock();
10176d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  LeakDetector::removeGarbageObject(dummy);
10276d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  return dummy;
103792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattner}
104792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattner
105792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattnervoid ilist_traits<MachineBasicBlock>::transferNodesFromList(
10676d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  iplist<MachineBasicBlock, ilist_traits<MachineBasicBlock> >& toList,
10776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  ilist_iterator<MachineBasicBlock> first,
1089d5d7598db72c00a0fb89dc77198e4f6ebc5294dChris Lattner  ilist_iterator<MachineBasicBlock> last) {
10976d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  if (Parent != toList.Parent)
11076d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos    for (; first != last; ++first)
11176d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      first->Parent = toList.Parent;
112792699c46ef9bfc47dd459bbfa7e71bcb2cee29aTanya Lattner}
113227c3d355b017393963a690f9f27d1de7fa359bcChris Lattner
1141049164aa6b06d91d9b3b557a9a213eaf3f6319aChris LattnerMachineFunction::MachineFunction(const Function *F,
115955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner                                 const TargetMachine &TM)
116f99c232506f134107f9ae02c118fe31685e6b06cJim Laskey  : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0) {
117b7825bc72534573c444e646dd1c3999ff787bbadMisha Brukman  SSARegMapping = new SSARegMap();
118ad8281607f066c2cce5c3625009d8ee0761dbf35Chris Lattner  MFInfo = 0;
119eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner  FrameInfo = new MachineFrameInfo();
1203029f920519e0871a5aad5d7c592281093953733Chris Lattner  ConstantPool = new MachineConstantPool(TM.getTargetData());
12137efe6764568a3829fee26aba532283131d1a104Nate Begeman  JumpTableInfo = new MachineJumpTableInfo(TM.getTargetData());
12217fb34bf8cd10a798c9206eeef3bff151b4d3688Tanya Lattner  BasicBlocks.Parent = this;
123831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner}
124831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner
12576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis EvlogimenosMachineFunction::~MachineFunction() {
1264b9a4006748b8d72a04504a5fc1f5daa73bf69f9Chris Lattner  BasicBlocks.clear();
127831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner  delete SSARegMapping;
128955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner  delete MFInfo;
129955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner  delete FrameInfo;
1304d149cdae1553426f49623fdae215d481d56d955Chris Lattner  delete ConstantPool;
13137efe6764568a3829fee26aba532283131d1a104Nate Begeman  delete JumpTableInfo;
132ce9c41e77a2ec75d48a173b9baf0f4a3bf49fac7Chris Lattner  delete[] UsedPhysRegs;
1331049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner}
1341049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner
1351049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattnervoid MachineFunction::dump() const { print(std::cerr); }
1361049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner
1371049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattnervoid MachineFunction::print(std::ostream &OS) const {
13847b716483ef2d057c8a0015af20685755e606d0dBrian Gaeke  OS << "# Machine code for " << Fn->getName () << "():\n";
139955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner
140955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner  // Print Frame Information
1419085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner  getFrameInfo()->print(*this, OS);
14237efe6764568a3829fee26aba532283131d1a104Nate Begeman
14337efe6764568a3829fee26aba532283131d1a104Nate Begeman  // Print JumpTable Information
14437efe6764568a3829fee26aba532283131d1a104Nate Begeman  getJumpTableInfo()->print(OS);
1454d149cdae1553426f49623fdae215d481d56d955Chris Lattner
1464d149cdae1553426f49623fdae215d481d56d955Chris Lattner  // Print Constant Pool
1474d149cdae1553426f49623fdae215d481d56d955Chris Lattner  getConstantPool()->print(OS);
148a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner
149a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner  const MRegisterInfo *MRI = getTarget().getRegisterInfo();
150a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner
151a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner  if (livein_begin() != livein_end()) {
152a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner    OS << "Live Ins:";
153a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner    for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) {
154a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner      if (MRI)
155a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner        OS << " " << MRI->getName(I->first);
156a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner      else
157a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner        OS << " Reg #" << I->first;
1584e92027837136233db0fc1c1a4fa2bc456d74de3Chris Lattner
1594e92027837136233db0fc1c1a4fa2bc456d74de3Chris Lattner      if (I->second)
1604e92027837136233db0fc1c1a4fa2bc456d74de3Chris Lattner        OS << " in VR#" << I->second << " ";
161a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner    }
162a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner    OS << "\n";
163a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner  }
164a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner  if (liveout_begin() != liveout_end()) {
165a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner    OS << "Live Outs:";
166a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner    for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I)
167a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner      if (MRI)
168a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner        OS << " " << MRI->getName(*I);
169a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner      else
170a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner        OS << " Reg #" << *I;
171a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner    OS << "\n";
172a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner  }
173a1f68ca94e763945f9accc75768a55a84bae6cfbChris Lattner
17490421cd8f982b4fe38d8f5992423e4f63074869fBrian Gaeke  for (const_iterator BB = begin(); BB != end(); ++BB)
17590421cd8f982b4fe38d8f5992423e4f63074869fBrian Gaeke    BB->print(OS);
17647b716483ef2d057c8a0015af20685755e606d0dBrian Gaeke
17747b716483ef2d057c8a0015af20685755e606d0dBrian Gaeke  OS << "\n# End machine code for " << Fn->getName () << "().\n\n";
1781049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner}
1791049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner
18071bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos/// CFGOnly flag - This is used to control whether or not the CFG graph printer
18171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos/// prints out the contents of basic blocks or not.  This is acceptable because
18271bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos/// this code is only really used for debugging purposes.
18371bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos///
18471bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenosstatic bool CFGOnly = false;
18571bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos
18671bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenosnamespace llvm {
18776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  template<>
18876d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
18976d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos    static std::string getGraphName(const MachineFunction *F) {
19076d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      return "CFG for '" + F->getFunction()->getName() + "' function";
19176d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos    }
19271bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos
19376d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos    static std::string getNodeLabel(const MachineBasicBlock *Node,
19476d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos                                    const MachineFunction *Graph) {
19576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      if (CFGOnly && Node->getBasicBlock() &&
19676d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos          !Node->getBasicBlock()->getName().empty())
19776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos        return Node->getBasicBlock()->getName() + ":";
19871bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos
19976d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      std::ostringstream Out;
20076d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      if (CFGOnly) {
20176d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos        Out << Node->getNumber() << ':';
20276d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos        return Out.str();
20376d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      }
20471bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos
20576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      Node->print(Out);
20671bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos
20776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      std::string OutStr = Out.str();
20876d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
20971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos
21076d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      // Process string output to make it nicer...
21176d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      for (unsigned i = 0; i != OutStr.length(); ++i)
21276d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos        if (OutStr[i] == '\n') {                            // Left justify
21376d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos          OutStr[i] = '\\';
21476d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos          OutStr.insert(OutStr.begin()+i+1, 'l');
21576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos        }
21676d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos      return OutStr;
21776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos    }
21876d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos  };
21971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos}
22071bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos
22171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenosvoid MachineFunction::viewCFG() const
22271bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos{
223851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey#ifndef NDEBUG
2249d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  ViewGraph(this, "mf" + getFunction()->getName());
2259d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#else
2269d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  std::cerr << "SelectionDAG::viewGraph is only available in debug builds on "
227851a22db2bdbcab1768a87c4f02b5972e48db5edJim Laskey            << "systems with Graphviz or gv!\n";
2289d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif // NDEBUG
22971bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos}
23071bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos
23171bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenosvoid MachineFunction::viewCFGOnly() const
23271bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos{
23371bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos  CFGOnly = true;
23471bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos  viewCFG();
23571bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos  CFGOnly = false;
23671bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos}
23771bf404e9b69122c276ad7ce66f38bf1e57cafebAlkis Evlogimenos
238f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner// The next two methods are used to construct and to retrieve
2392fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// the MachineCodeForFunction object for the given function.
2402fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// construct() -- Allocates and initializes for a given function and target
241f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner// get()       -- Returns a handle to the object.
242f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner//                This should not be called before "construct()"
2432fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner//                for a given Function.
24476d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos//
245fce1143bcfa73f61845002fa50473d1a01384202Misha BrukmanMachineFunction&
246335d5c399b52c2507ad11048310edc51462f4811Chris LattnerMachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
24789e2da034a02cd33b306b59dbbf607650cca1c4cVikram S. Adve{
248e316efc0e74442cffdda4889d30dca4fffcad749Chris Lattner  assert(Fn->getAnnotation(MF_AID) == 0 &&
2492fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner         "Object already exists for this function!");
250335d5c399b52c2507ad11048310edc51462f4811Chris Lattner  MachineFunction* mcInfo = new MachineFunction(Fn, Tar);
251335d5c399b52c2507ad11048310edc51462f4811Chris Lattner  Fn->addAnnotation(mcInfo);
252f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner  return *mcInfo;
253f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner}
254f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner
25516c45e9de896ea37d48d093dbe02fc9a4c1b9f8fChris Lattnervoid MachineFunction::destruct(const Function *Fn) {
256e316efc0e74442cffdda4889d30dca4fffcad749Chris Lattner  bool Deleted = Fn->deleteAnnotation(MF_AID);
2572fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner  assert(Deleted && "Machine code did not exist for function!");
258f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner}
259f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner
260335d5c399b52c2507ad11048310edc51462f4811Chris LattnerMachineFunction& MachineFunction::get(const Function *F)
26189e2da034a02cd33b306b59dbbf607650cca1c4cVikram S. Adve{
262e316efc0e74442cffdda4889d30dca4fffcad749Chris Lattner  MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID);
263f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner  assert(mc && "Call construct() method first to allocate the object");
264f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner  return *mc;
265f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner}
266f2868ce228ca20f72d1c6fbe241de01975cfe609Chris Lattner
267831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattnervoid MachineFunction::clearSSARegMap() {
268831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner  delete SSARegMapping;
269831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner  SSARegMapping = 0;
270831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner}
271831fdcf0177a4eef66129cd6fb4138922c492bf0Chris Lattner
272955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner//===----------------------------------------------------------------------===//
273eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner//  MachineFrameInfo implementation
274955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner//===----------------------------------------------------------------------===//
275955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner
2769085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattnervoid MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{
27762d6ad2cee0e6b7fa653c8903a951f8497b6da3aChris Lattner  int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea();
2789085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner
279955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner  for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
280955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner    const StackObject &SO = Objects[i];
2810db07092a7aaeeaa0722799d9f533be3b782d362Chris Lattner    OS << "  <fi #" << (int)(i-NumFixedObjects) << ">: ";
282955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner    if (SO.Size == 0)
283955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner      OS << "variable sized";
284955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner    else
2850db07092a7aaeeaa0722799d9f533be3b782d362Chris Lattner      OS << "size is " << SO.Size << " byte" << (SO.Size != 1 ? "s," : ",");
2860db07092a7aaeeaa0722799d9f533be3b782d362Chris Lattner    OS << " alignment is " << SO.Alignment << " byte"
2870db07092a7aaeeaa0722799d9f533be3b782d362Chris Lattner       << (SO.Alignment != 1 ? "s," : ",");
28876d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos
289955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner    if (i < NumFixedObjects)
290955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner      OS << " fixed";
291955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner    if (i < NumFixedObjects || SO.SPOffset != -1) {
2927f7bbc2fdb833485ac3d865a405fd948e58e8ddbChris Lattner      int Off = SO.SPOffset - ValOffset;
293955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner      OS << " at location [SP";
2949085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner      if (Off > 0)
29576d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos        OS << "+" << Off;
2969085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner      else if (Off < 0)
29776d9daccebc589dbf0f9cbb23326c7d50a26f17dAlkis Evlogimenos        OS << Off;
298955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner      OS << "]";
299955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner    }
300955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner    OS << "\n";
301955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner  }
302955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner
303955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner  if (HasVarSizedObjects)
304955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner    OS << "  Stack frame contains variable sized objects\n";
305955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner}
306955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner
3079085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattnervoid MachineFrameInfo::dump(const MachineFunction &MF) const {
3089085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner  print(MF, std::cerr);
3099085d8a9a9000eeaa7cf337ccbdca41d528c99c2Chris Lattner}
310955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner
311955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner
312955fad1f99dd174023a1b2e6a1795958147b077dChris Lattner//===----------------------------------------------------------------------===//
31337efe6764568a3829fee26aba532283131d1a104Nate Begeman//  MachineJumpTableInfo implementation
31437efe6764568a3829fee26aba532283131d1a104Nate Begeman//===----------------------------------------------------------------------===//
31537efe6764568a3829fee26aba532283131d1a104Nate Begeman
31637efe6764568a3829fee26aba532283131d1a104Nate Begeman/// getJumpTableIndex - Create a new jump table entry in the jump table info
31737efe6764568a3829fee26aba532283131d1a104Nate Begeman/// or return an existing one.
31837efe6764568a3829fee26aba532283131d1a104Nate Begeman///
31937efe6764568a3829fee26aba532283131d1a104Nate Begemanunsigned MachineJumpTableInfo::getJumpTableIndex(
32037efe6764568a3829fee26aba532283131d1a104Nate Begeman                                     std::vector<MachineBasicBlock*> &DestBBs) {
32137efe6764568a3829fee26aba532283131d1a104Nate Begeman  for (unsigned i = 0, e = JumpTables.size(); i != e; ++i)
32237efe6764568a3829fee26aba532283131d1a104Nate Begeman    if (JumpTables[i].MBBs == DestBBs)
32337efe6764568a3829fee26aba532283131d1a104Nate Begeman      return i;
32437efe6764568a3829fee26aba532283131d1a104Nate Begeman
32537efe6764568a3829fee26aba532283131d1a104Nate Begeman  JumpTables.push_back(MachineJumpTableEntry(DestBBs));
32637efe6764568a3829fee26aba532283131d1a104Nate Begeman  return JumpTables.size()-1;
32737efe6764568a3829fee26aba532283131d1a104Nate Begeman}
32837efe6764568a3829fee26aba532283131d1a104Nate Begeman
32937efe6764568a3829fee26aba532283131d1a104Nate Begeman
33037efe6764568a3829fee26aba532283131d1a104Nate Begemanvoid MachineJumpTableInfo::print(std::ostream &OS) const {
33137efe6764568a3829fee26aba532283131d1a104Nate Begeman  // FIXME: this is lame, maybe we could print out the MBB numbers or something
33237efe6764568a3829fee26aba532283131d1a104Nate Begeman  // like {1, 2, 4, 5, 3, 0}
33337efe6764568a3829fee26aba532283131d1a104Nate Begeman  for (unsigned i = 0, e = JumpTables.size(); i != e; ++i) {
33437efe6764568a3829fee26aba532283131d1a104Nate Begeman    OS << "  <jt #" << i << "> has " << JumpTables[i].MBBs.size()
33537efe6764568a3829fee26aba532283131d1a104Nate Begeman       << " entries\n";
33637efe6764568a3829fee26aba532283131d1a104Nate Begeman  }
33737efe6764568a3829fee26aba532283131d1a104Nate Begeman}
33837efe6764568a3829fee26aba532283131d1a104Nate Begeman
3393700a4d3a27ca8d39c73049020623cf4963d6c13Nate Begemanunsigned MachineJumpTableInfo::getEntrySize() const {
340a69571c7991813c93cba64e88eced6899ce93d81Owen Anderson  return TD->getPointerSize();
3413700a4d3a27ca8d39c73049020623cf4963d6c13Nate Begeman}
3423700a4d3a27ca8d39c73049020623cf4963d6c13Nate Begeman
3433700a4d3a27ca8d39c73049020623cf4963d6c13Nate Begemanunsigned MachineJumpTableInfo::getAlignment() const {
344a69571c7991813c93cba64e88eced6899ce93d81Owen Anderson  return TD->getPointerAlignment();
3453700a4d3a27ca8d39c73049020623cf4963d6c13Nate Begeman}
3463700a4d3a27ca8d39c73049020623cf4963d6c13Nate Begeman
34737efe6764568a3829fee26aba532283131d1a104Nate Begemanvoid MachineJumpTableInfo::dump() const { print(std::cerr); }
34837efe6764568a3829fee26aba532283131d1a104Nate Begeman
34937efe6764568a3829fee26aba532283131d1a104Nate Begeman
35037efe6764568a3829fee26aba532283131d1a104Nate Begeman//===----------------------------------------------------------------------===//
3514d149cdae1553426f49623fdae215d481d56d955Chris Lattner//  MachineConstantPool implementation
3524d149cdae1553426f49623fdae215d481d56d955Chris Lattner//===----------------------------------------------------------------------===//
3534d149cdae1553426f49623fdae215d481d56d955Chris Lattner
354d6594ae54cfde4db4d30272192645c0a45fb9902Evan ChengMachineConstantPool::~MachineConstantPool() {
355d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  for (unsigned i = 0, e = Constants.size(); i != e; ++i)
356d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    if (Constants[i].isMachineConstantPoolEntry())
357d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng      delete Constants[i].Val.MachineCPVal;
358d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng}
359d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng
3603029f920519e0871a5aad5d7c592281093953733Chris Lattner/// getConstantPoolIndex - Create a new entry in the constant pool or return
3613029f920519e0871a5aad5d7c592281093953733Chris Lattner/// an existing one.  User must specify an alignment in bytes for the object.
3623029f920519e0871a5aad5d7c592281093953733Chris Lattner///
3633029f920519e0871a5aad5d7c592281093953733Chris Lattnerunsigned MachineConstantPool::getConstantPoolIndex(Constant *C,
3643029f920519e0871a5aad5d7c592281093953733Chris Lattner                                                   unsigned Alignment) {
3653029f920519e0871a5aad5d7c592281093953733Chris Lattner  assert(Alignment && "Alignment must be specified!");
3663029f920519e0871a5aad5d7c592281093953733Chris Lattner  if (Alignment > PoolAlignment) PoolAlignment = Alignment;
3673029f920519e0871a5aad5d7c592281093953733Chris Lattner
3683029f920519e0871a5aad5d7c592281093953733Chris Lattner  // Check to see if we already have this constant.
3693029f920519e0871a5aad5d7c592281093953733Chris Lattner  //
3703029f920519e0871a5aad5d7c592281093953733Chris Lattner  // FIXME, this could be made much more efficient for large constant pools.
3713029f920519e0871a5aad5d7c592281093953733Chris Lattner  unsigned AlignMask = (1 << Alignment)-1;
3723029f920519e0871a5aad5d7c592281093953733Chris Lattner  for (unsigned i = 0, e = Constants.size(); i != e; ++i)
373d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    if (Constants[i].Val.ConstVal == C && (Constants[i].Offset & AlignMask)== 0)
3743029f920519e0871a5aad5d7c592281093953733Chris Lattner      return i;
3753029f920519e0871a5aad5d7c592281093953733Chris Lattner
3763029f920519e0871a5aad5d7c592281093953733Chris Lattner  unsigned Offset = 0;
3773029f920519e0871a5aad5d7c592281093953733Chris Lattner  if (!Constants.empty()) {
3783029f920519e0871a5aad5d7c592281093953733Chris Lattner    Offset = Constants.back().Offset;
379d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    Offset += TD->getTypeSize(Constants.back().Val.ConstVal->getType());
3803029f920519e0871a5aad5d7c592281093953733Chris Lattner    Offset = (Offset+AlignMask)&~AlignMask;
3813029f920519e0871a5aad5d7c592281093953733Chris Lattner  }
3823029f920519e0871a5aad5d7c592281093953733Chris Lattner
3833029f920519e0871a5aad5d7c592281093953733Chris Lattner  Constants.push_back(MachineConstantPoolEntry(C, Offset));
3843029f920519e0871a5aad5d7c592281093953733Chris Lattner  return Constants.size()-1;
3853029f920519e0871a5aad5d7c592281093953733Chris Lattner}
3863029f920519e0871a5aad5d7c592281093953733Chris Lattner
387d6594ae54cfde4db4d30272192645c0a45fb9902Evan Chengunsigned MachineConstantPool::getConstantPoolIndex(MachineConstantPoolValue *V,
388d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng                                                   unsigned Alignment) {
389d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  assert(Alignment && "Alignment must be specified!");
390d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  if (Alignment > PoolAlignment) PoolAlignment = Alignment;
391d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng
392d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  // Check to see if we already have this constant.
393d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  //
394d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  // FIXME, this could be made much more efficient for large constant pools.
395d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  unsigned AlignMask = (1 << Alignment)-1;
396d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  int Idx = V->getExistingMachineCPValue(this, Alignment);
397d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  if (Idx != -1)
398d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    return (unsigned)Idx;
399d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng
400d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  unsigned Offset = 0;
401d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  if (!Constants.empty()) {
402d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    Offset = Constants.back().Offset;
403d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    Offset += TD->getTypeSize(Constants.back().Val.MachineCPVal->getType());
404d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    Offset = (Offset+AlignMask)&~AlignMask;
405d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  }
406d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng
407d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  Constants.push_back(MachineConstantPoolEntry(V, Offset));
408d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng  return Constants.size()-1;
409d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng}
410d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng
4113029f920519e0871a5aad5d7c592281093953733Chris Lattner
4124d149cdae1553426f49623fdae215d481d56d955Chris Lattnervoid MachineConstantPool::print(std::ostream &OS) const {
413b8973bd8f50d7321635e1e07b81a880a0828d185Evan Cheng  for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
414d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    OS << "  <cp #" << i << "> is";
415d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    if (Constants[i].isMachineConstantPoolEntry())
416d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng      Constants[i].Val.MachineCPVal->print(OS);
417d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    else
418d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng      OS << *(Value*)Constants[i].Val.ConstVal;
4193029f920519e0871a5aad5d7c592281093953733Chris Lattner    OS << " , offset=" << Constants[i].Offset;
420b8973bd8f50d7321635e1e07b81a880a0828d185Evan Cheng    OS << "\n";
421b8973bd8f50d7321635e1e07b81a880a0828d185Evan Cheng  }
4224d149cdae1553426f49623fdae215d481d56d955Chris Lattner}
4234d149cdae1553426f49623fdae215d481d56d955Chris Lattner
4244d149cdae1553426f49623fdae215d481d56d955Chris Lattnervoid MachineConstantPool::dump() const { print(std::cerr); }
425