diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 3c7b213533f..76738e28c26 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -43,6 +43,10 @@ class MachineMemOperand; //===----------------------------------------------------------------------===// /// MachineInstr - Representation of each machine instruction. /// +/// This class isn't a POD type, but it must have a trivial destructor. When a +/// MachineFunction is deleted, all the contained MachineInstrs are deallocated +/// without having their destructor called. +/// class MachineInstr : public ilist_node { public: typedef MachineMemOperand **mmo_iterator; @@ -90,6 +94,8 @@ private: MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION; void operator=(const MachineInstr&) LLVM_DELETED_FUNCTION; + // Use MachineFunction::DeleteMachineInstr() instead. + ~MachineInstr() LLVM_DELETED_FUNCTION; // Intrusive list support friend struct ilist_traits; @@ -106,8 +112,6 @@ private: MachineInstr(MachineFunction&, const MCInstrDesc &MCID, const DebugLoc dl, bool NoImp = false); - ~MachineInstr(); - // MachineInstrs are pool-allocated and owned by MachineFunction. friend class MachineFunction; diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 08d116afead..9647e83e24c 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -76,7 +76,13 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM, } MachineFunction::~MachineFunction() { - BasicBlocks.clear(); + // Don't call destructors on MachineInstr and MachineOperand. All of their + // memory comes from the BumpPtrAllocator which is about to be purged. + // + // Do call MachineBasicBlock destructors, it contains std::vectors. + for (iterator I = begin(), E = end(); I != E; I = BasicBlocks.erase(I)) + I->Insts.clearAndLeakNodesUnsafely(); + InstructionRecycler.clear(Allocator); OperandRecycler.clear(Allocator); BasicBlockRecycler.clear(Allocator); @@ -176,15 +182,17 @@ MachineFunction::CloneMachineInstr(const MachineInstr *Orig) { /// DeleteMachineInstr - Delete the given MachineInstr. /// +/// This function also serves as the MachineInstr destructor - the real +/// ~MachineInstr() destructor must be empty. void MachineFunction::DeleteMachineInstr(MachineInstr *MI) { // Strip it for parts. The operand array and the MI object itself are // independently recyclable. if (MI->Operands) deallocateOperandArray(MI->CapOperands, MI->Operands); - MI->Operands = 0; - MI->NumOperands = 0; - MI->~MachineInstr(); + // Don't call ~MachineInstr() which must be trivial anyway because + // ~MachineFunction drops whole lists of MachineInstrs wihout calling their + // destructors. InstructionRecycler.Deallocate(Allocator, MI); } diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index d3342987c05..3255fa6e451 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -35,7 +35,6 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/LeakDetector.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" @@ -544,8 +543,6 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, if (!NoImp) addImplicitDefUseOperands(MF); - // Make sure that we get added to a machine basicblock - LeakDetector::addGarbageObject(this); } /// MachineInstr ctor - Copies MachineInstr arg exactly @@ -558,28 +555,12 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) CapOperands = OperandCapacity::get(MI.getNumOperands()); Operands = MF.allocateOperandArray(CapOperands); - // Add operands + // Copy operands. for (unsigned i = 0; i != MI.getNumOperands(); ++i) addOperand(MF, MI.getOperand(i)); // Copy all the sensible flags. setFlags(MI.Flags); - - // Set parent to null. - Parent = 0; - - LeakDetector::addGarbageObject(this); -} - -MachineInstr::~MachineInstr() { - LeakDetector::removeGarbageObject(this); -#ifndef NDEBUG - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - assert(Operands[i].ParentMI == this && "ParentMI mismatch!"); - assert((!Operands[i].isReg() || !Operands[i].isOnRegUseList()) && - "Reg operand def/use list corrupted"); - } -#endif } /// getRegInfo - If this instruction is embedded into a MachineFunction, diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp index 9858b4999e0..21877e52c25 100644 --- a/lib/CodeGen/MachineRegisterInfo.cpp +++ b/lib/CodeGen/MachineRegisterInfo.cpp @@ -30,12 +30,6 @@ MachineRegisterInfo::MachineRegisterInfo(const TargetRegisterInfo &TRI) } MachineRegisterInfo::~MachineRegisterInfo() { -#ifndef NDEBUG - clearVirtRegs(); - for (unsigned i = 0, e = TRI->getNumRegs(); i != e; ++i) - assert(!PhysRegUseDefLists[i] && - "PhysRegUseDefLists has entries after all instructions are deleted"); -#endif delete [] PhysRegUseDefLists; }