If compile unit's language is not set then don't crash while dump'ing compile unit.
[oota-llvm.git] / lib / CodeGen / MachineFunction.cpp
index 4453be80c1c0aa21d405e80734304a371604a0a3..cf7f39140b8663e25daf837a8973b3001d2b7384 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DerivedTypes.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetLowering.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/Function.h"
 #include "llvm/Instructions.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/GraphWriter.h"
-#include "llvm/Support/LeakDetector.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Config/config.h"
 #include <fstream>
@@ -44,11 +43,13 @@ void MachineFunctionPass::virtfn() {}
 
 namespace {
   struct VISIBILITY_HIDDEN Printer : public MachineFunctionPass {
+    static char ID;
+
     std::ostream *OS;
     const std::string Banner;
 
-    Printer (std::ostream *_OS, const std::string &_Banner) :
-      OS (_OS), Banner (_Banner) { }
+    Printer (std::ostream *os, const std::string &banner) 
+      : MachineFunctionPass(&ID), OS(os), Banner(banner) {}
 
     const char *getPassName() const { return "MachineFunction Printer"; }
 
@@ -62,6 +63,7 @@ namespace {
       return false;
     }
   };
+  char Printer::ID = 0;
 }
 
 /// Returns a newly-created MachineFunction Printer pass. The default output
@@ -74,6 +76,9 @@ FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS,
 
 namespace {
   struct VISIBILITY_HIDDEN Deleter : public MachineFunctionPass {
+    static char ID;
+    Deleter() : MachineFunctionPass(&ID) {}
+
     const char *getPassName() const { return "Machine Code Deleter"; }
 
     bool runOnMachineFunction(MachineFunction &MF) {
@@ -82,6 +87,7 @@ namespace {
       return true;
     }
   };
+  char Deleter::ID = 0;
 }
 
 /// MachineCodeDeletion Pass - This pass deletes all of the machine code for
@@ -97,28 +103,23 @@ FunctionPass *llvm::createMachineCodeDeleter() {
 // MachineFunction implementation
 //===---------------------------------------------------------------------===//
 
-MachineBasicBlock* ilist_traits<MachineBasicBlock>::createSentinel() {
-  MachineBasicBlock* dummy = new MachineBasicBlock();
-  LeakDetector::removeGarbageObject(dummy);
-  return dummy;
-}
-
-void ilist_traits<MachineBasicBlock>::transferNodesFromList(
-  iplist<MachineBasicBlock, ilist_traits<MachineBasicBlock> >& toList,
-  ilist_iterator<MachineBasicBlock> first,
-  ilist_iterator<MachineBasicBlock> last) {
-  if (Parent != toList.Parent)
-    for (; first != last; ++first)
-      first->Parent = toList.Parent;
+void ilist_traits<MachineBasicBlock>::deleteNode(MachineBasicBlock *MBB) {
+  MBB->getParent()->DeleteMachineBasicBlock(MBB);
 }
 
 MachineFunction::MachineFunction(const Function *F,
                                  const TargetMachine &TM)
-  : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0) {
-  SSARegMapping = new SSARegMap();
+  : Annotation(MF_AID), Fn(F), Target(TM) {
+  if (TM.getRegisterInfo())
+    RegInfo = new (Allocator.Allocate<MachineRegisterInfo>())
+                  MachineRegisterInfo(*TM.getRegisterInfo());
+  else
+    RegInfo = 0;
   MFInfo = 0;
-  FrameInfo = new MachineFrameInfo();
-  ConstantPool = new MachineConstantPool(TM.getTargetData());
+  FrameInfo = new (Allocator.Allocate<MachineFrameInfo>())
+                  MachineFrameInfo(*TM.getFrameInfo());
+  ConstantPool = new (Allocator.Allocate<MachineConstantPool>())
+                     MachineConstantPool(TM.getTargetData());
   
   // Set up jump table.
   const TargetData &TD = *TM.getTargetData();
@@ -126,19 +127,22 @@ MachineFunction::MachineFunction(const Function *F,
   unsigned EntrySize = IsPic ? 4 : TD.getPointerSize();
   unsigned Alignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty)
                              : TD.getPointerABIAlignment();
-  JumpTableInfo = new MachineJumpTableInfo(EntrySize, Alignment);
-  
-  BasicBlocks.Parent = this;
+  JumpTableInfo = new (Allocator.Allocate<MachineJumpTableInfo>())
+                      MachineJumpTableInfo(EntrySize, Alignment);
 }
 
 MachineFunction::~MachineFunction() {
   BasicBlocks.clear();
-  delete SSARegMapping;
-  delete MFInfo;
-  delete FrameInfo;
-  delete ConstantPool;
-  delete JumpTableInfo;
-  delete[] UsedPhysRegs;
+  InstructionRecycler.clear(Allocator);
+  BasicBlockRecycler.clear(Allocator);
+  if (RegInfo)
+    RegInfo->~MachineRegisterInfo();        Allocator.Deallocate(RegInfo);
+  if (MFInfo) {
+    MFInfo->~MachineFunctionInfo();       Allocator.Deallocate(MFInfo);
+  }
+  FrameInfo->~MachineFrameInfo();         Allocator.Deallocate(FrameInfo);
+  ConstantPool->~MachineConstantPool();   Allocator.Deallocate(ConstantPool);
+  JumpTableInfo->~MachineJumpTableInfo(); Allocator.Deallocate(JumpTableInfo);
 }
 
 
@@ -184,28 +188,84 @@ void MachineFunction::RenumberBlocks(MachineBasicBlock *MBB) {
   MBBNumbering.resize(BlockNo);
 }
 
+/// CreateMachineInstr - Allocate a new MachineInstr. Use this instead
+/// of `new MachineInstr'.
+///
+MachineInstr *
+MachineFunction::CreateMachineInstr(const TargetInstrDesc &TID,
+                                    DebugLoc DL, bool NoImp) {
+  return new (InstructionRecycler.Allocate<MachineInstr>(Allocator))
+    MachineInstr(TID, DL, NoImp);
+}
 
-void MachineFunction::dump() const { print(*cerr.stream()); }
+/// CloneMachineInstr - Create a new MachineInstr which is a copy of the
+/// 'Orig' instruction, identical in all ways except the the instruction
+/// has no parent, prev, or next.
+///
+MachineInstr *
+MachineFunction::CloneMachineInstr(const MachineInstr *Orig) {
+  return new (InstructionRecycler.Allocate<MachineInstr>(Allocator))
+             MachineInstr(*this, *Orig);
+}
+
+/// DeleteMachineInstr - Delete the given MachineInstr.
+///
+void
+MachineFunction::DeleteMachineInstr(MachineInstr *MI) {
+  // Clear the instructions memoperands. This must be done manually because
+  // the instruction's parent pointer is now null, so it can't properly
+  // deallocate them on its own.
+  MI->clearMemOperands(*this);
+
+  MI->~MachineInstr();
+  InstructionRecycler.Deallocate(Allocator, MI);
+}
+
+/// CreateMachineBasicBlock - Allocate a new MachineBasicBlock. Use this
+/// instead of `new MachineBasicBlock'.
+///
+MachineBasicBlock *
+MachineFunction::CreateMachineBasicBlock(const BasicBlock *bb) {
+  return new (BasicBlockRecycler.Allocate<MachineBasicBlock>(Allocator))
+             MachineBasicBlock(*this, bb);
+}
+
+/// DeleteMachineBasicBlock - Delete the given MachineBasicBlock.
+///
+void
+MachineFunction::DeleteMachineBasicBlock(MachineBasicBlock *MBB) {
+  assert(MBB->getParent() == this && "MBB parent mismatch!");
+  MBB->~MachineBasicBlock();
+  BasicBlockRecycler.Deallocate(Allocator, MBB);
+}
+
+void MachineFunction::dump() const {
+  print(*cerr.stream());
+}
 
 void MachineFunction::print(std::ostream &OS) const {
   OS << "# Machine code for " << Fn->getName () << "():\n";
 
   // Print Frame Information
-  getFrameInfo()->print(*this, OS);
+  FrameInfo->print(*this, OS);
   
   // Print JumpTable Information
-  getJumpTableInfo()->print(OS);
+  JumpTableInfo->print(OS);
 
   // Print Constant Pool
-  getConstantPool()->print(OS);
+  {
+    raw_os_ostream OSS(OS);
+    ConstantPool->print(OSS);
+  }
   
-  const MRegisterInfo *MRI = getTarget().getRegisterInfo();
+  const TargetRegisterInfo *TRI = getTarget().getRegisterInfo();
   
-  if (livein_begin() != livein_end()) {
+  if (RegInfo && !RegInfo->livein_empty()) {
     OS << "Live Ins:";
-    for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) {
-      if (MRI)
-        OS << " " << MRI->getName(I->first);
+    for (MachineRegisterInfo::livein_iterator
+         I = RegInfo->livein_begin(), E = RegInfo->livein_end(); I != E; ++I) {
+      if (TRI)
+        OS << " " << TRI->getName(I->first);
       else
         OS << " Reg #" << I->first;
       
@@ -214,11 +274,12 @@ void MachineFunction::print(std::ostream &OS) const {
     }
     OS << "\n";
   }
-  if (liveout_begin() != liveout_end()) {
+  if (RegInfo && !RegInfo->liveout_empty()) {
     OS << "Live Outs:";
-    for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I)
-      if (MRI)
-        OS << " " << MRI->getName(*I);
+    for (MachineRegisterInfo::liveout_iterator
+         I = RegInfo->liveout_begin(), E = RegInfo->liveout_end(); I != E; ++I)
+      if (TRI)
+        OS << " " << TRI->getName(*I);
       else
         OS << " Reg #" << *I;
     OS << "\n";
@@ -307,7 +368,8 @@ MachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
 
 void MachineFunction::destruct(const Function *Fn) {
   bool Deleted = Fn->deleteAnnotation(MF_AID);
-  assert(Deleted && "Machine code did not exist for function!");
+  assert(Deleted && "Machine code did not exist for function!"); 
+  Deleted = Deleted; // silence warning when no assertions.
 }
 
 MachineFunction& MachineFunction::get(const Function *F)
@@ -317,21 +379,59 @@ MachineFunction& MachineFunction::get(const Function *F)
   return *mc;
 }
 
-void MachineFunction::clearSSARegMap() {
-  delete SSARegMapping;
-  SSARegMapping = 0;
+/// getOrCreateDebugLocID - Look up the DebugLocTuple index with the given
+/// source file, line, and column. If none currently exists, create a new
+/// DebugLocTuple, and insert it into the DebugIdMap.
+unsigned MachineFunction::getOrCreateDebugLocID(unsigned Src, unsigned Line,
+                                                unsigned Col) {
+  DebugLocTuple Tuple(Src, Line, Col);
+  DenseMap<DebugLocTuple, unsigned>::iterator II
+    = DebugLocInfo.DebugIdMap.find(Tuple);
+  if (II != DebugLocInfo.DebugIdMap.end())
+    return II->second;
+  // Add a new tuple.
+  unsigned Id = DebugLocInfo.DebugLocations.size();
+  DebugLocInfo.DebugLocations.push_back(Tuple);
+  DebugLocInfo.DebugIdMap[Tuple] = Id;
+  return Id;
+}
+
+/// getDebugLocTuple - Get the DebugLocTuple for a given DebugLoc object.
+DebugLocTuple MachineFunction::getDebugLocTuple(DebugLoc DL) const {
+  unsigned Idx = DL.getIndex();
+  assert(Idx < DebugLocInfo.DebugLocations.size() &&
+         "Invalid index into debug locations!");
+  return DebugLocInfo.DebugLocations[Idx];
 }
 
 //===----------------------------------------------------------------------===//
 //  MachineFrameInfo implementation
 //===----------------------------------------------------------------------===//
 
+/// CreateFixedObject - Create a new object at a fixed location on the stack.
+/// All fixed objects should be created before other objects are created for
+/// efficiency. By default, fixed objects are immutable. This returns an
+/// index with a negative value.
+///
+int MachineFrameInfo::CreateFixedObject(uint64_t Size, int64_t SPOffset,
+                                        bool Immutable) {
+  assert(Size != 0 && "Cannot allocate zero size fixed stack objects!");
+  Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset, Immutable));
+  return -++NumFixedObjects;
+}
+
+
 void MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{
-  int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea();
+  const TargetFrameInfo *FI = MF.getTarget().getFrameInfo();
+  int ValOffset = (FI ? FI->getOffsetOfLocalArea() : 0);
 
   for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
     const StackObject &SO = Objects[i];
-    OS << "  <fi #" << (int)(i-NumFixedObjects) << ">: ";
+    OS << "  <fi#" << (int)(i-NumFixedObjects) << ">: ";
+    if (SO.Size == ~0ULL) {
+      OS << "dead\n";
+      continue;
+    }
     if (SO.Size == 0)
       OS << "variable sized";
     else
@@ -385,7 +485,7 @@ void MachineJumpTableInfo::print(std::ostream &OS) const {
   // FIXME: this is lame, maybe we could print out the MBB numbers or something
   // like {1, 2, 4, 5, 3, 0}
   for (unsigned i = 0, e = JumpTables.size(); i != e; ++i) {
-    OS << "  <jt #" << i << "> has " << JumpTables[i].MBBs.size() 
+    OS << "  <jt#" << i << "> has " << JumpTables[i].MBBs.size() 
        << " entries\n";
   }
 }
@@ -410,7 +510,8 @@ MachineConstantPool::~MachineConstantPool() {
 }
 
 /// getConstantPoolIndex - Create a new entry in the constant pool or return
-/// an existing one.  User must specify an alignment in bytes for the object.
+/// an existing one.  User must specify the log2 of the minimum required
+/// alignment for the object.
 ///
 unsigned MachineConstantPool::getConstantPoolIndex(Constant *C, 
                                                    unsigned Alignment) {
@@ -428,7 +529,7 @@ unsigned MachineConstantPool::getConstantPoolIndex(Constant *C,
   unsigned Offset = 0;
   if (!Constants.empty()) {
     Offset = Constants.back().getOffset();
-    Offset += TD->getTypeSize(Constants.back().getType());
+    Offset += TD->getTypePaddedSize(Constants.back().getType());
     Offset = (Offset+AlignMask)&~AlignMask;
   }
   
@@ -452,7 +553,7 @@ unsigned MachineConstantPool::getConstantPoolIndex(MachineConstantPoolValue *V,
   unsigned Offset = 0;
   if (!Constants.empty()) {
     Offset = Constants.back().getOffset();
-    Offset += TD->getTypeSize(Constants.back().getType());
+    Offset += TD->getTypePaddedSize(Constants.back().getType());
     Offset = (Offset+AlignMask)&~AlignMask;
   }
   
@@ -460,10 +561,9 @@ unsigned MachineConstantPool::getConstantPoolIndex(MachineConstantPoolValue *V,
   return Constants.size()-1;
 }
 
-
-void MachineConstantPool::print(std::ostream &OS) const {
+void MachineConstantPool::print(raw_ostream &OS) const {
   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
-    OS << "  <cp #" << i << "> is";
+    OS << "  <cp#" << i << "> is";
     if (Constants[i].isMachineConstantPoolEntry())
       Constants[i].Val.MachineCPVal->print(OS);
     else
@@ -473,4 +573,4 @@ void MachineConstantPool::print(std::ostream &OS) const {
   }
 }
 
-void MachineConstantPool::dump() const { print(*cerr.stream()); }
+void MachineConstantPool::dump() const { print(errs()); errs().flush(); }