X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineBasicBlock.cpp;h=01aaba5282b1568dcebdceca00c190f8cf9b43ab;hb=55e283c71eaa0428b63c901d726c0666f985ce85;hp=ba428c5bdb32938bf81314d79b755d3ce1e6a88e;hpb=8a46d342d8cbca7c9c7be6c66007d41329babad0;p=oota-llvm.git diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index ba428c5bdb3..01aaba5282b 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -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. // //===----------------------------------------------------------------------===// // @@ -14,10 +14,9 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/BasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetInstrDesc.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/LeakDetector.h" #include @@ -32,21 +31,37 @@ std::ostream& llvm::operator<<(std::ostream &OS, const MachineBasicBlock &MBB) { return OS; } -// MBBs start out as #-1. When a MBB is added to a MachineFunction, it -// gets the next available unique MBB number. If it is removed from a -// MachineFunction, it goes back to being #-1. +/// addNodeToList (MBB) - When an MBB is added to an MF, we need to update the +/// parent pointer of the MBB, the MBB numbering, and any instructions in the +/// MBB to be on the right operand list for registers. +/// +/// MBBs start out as #-1. When a MBB is added to a MachineFunction, it +/// gets the next available unique MBB number. If it is removed from a +/// MachineFunction, it goes back to being #-1. void ilist_traits::addNodeToList(MachineBasicBlock* N) { - assert(N->Parent == 0 && "machine instruction already in a basic block"); - N->Parent = Parent; + assert(N->getParent() == 0 && "machine instruction already in a basic block"); + N->setParent(Parent); N->Number = Parent->addToMBBNumbering(N); + + // Make sure the instructions have their operands in the reginfo lists. + MachineRegisterInfo &RegInfo = Parent->getRegInfo(); + for (MachineBasicBlock::iterator I = N->begin(), E = N->end(); I != E; ++I) + I->AddRegOperandsToUseLists(RegInfo); + LeakDetector::removeGarbageObject(N); } void ilist_traits::removeNodeFromList(MachineBasicBlock* N) { - assert(N->Parent != 0 && "machine instruction not in a basic block"); - N->Parent->removeFromMBBNumbering(N->Number); + assert(N->getParent() != 0 && "machine instruction not in a basic block"); + N->getParent()->removeFromMBBNumbering(N->Number); N->Number = -1; - N->Parent = 0; + N->setParent(0); + + // Make sure the instructions have their operands removed from the reginfo + // lists. + for (MachineBasicBlock::iterator I = N->begin(), E = N->end(); I != E; ++I) + I->RemoveRegOperandsFromUseLists(); + LeakDetector::addGarbageObject(N); } @@ -57,32 +72,69 @@ MachineInstr* ilist_traits::createSentinel() { return dummy; } +/// addNodeToList (MI) - When we add an instruction to a basic block +/// list, we update its parent pointer and add its operands from reg use/def +/// lists if appropriate. void ilist_traits::addNodeToList(MachineInstr* N) { - assert(N->parent == 0 && "machine instruction already in a basic block"); - N->parent = parent; + assert(N->getParent() == 0 && "machine instruction already in a basic block"); + N->setParent(parent); LeakDetector::removeGarbageObject(N); + + // If the block is in a function, add the instruction's register operands to + // their corresponding use/def lists. + if (MachineFunction *MF = parent->getParent()) + N->AddRegOperandsToUseLists(MF->getRegInfo()); } +/// removeNodeFromList (MI) - When we remove an instruction from a basic block +/// list, we update its parent pointer and remove its operands from reg use/def +/// lists if appropriate. void ilist_traits::removeNodeFromList(MachineInstr* N) { - assert(N->parent != 0 && "machine instruction not in a basic block"); - N->parent = 0; + assert(N->getParent() != 0 && "machine instruction not in a basic block"); + // If this block is in a function, remove from the use/def lists. + if (parent->getParent() != 0) + N->RemoveRegOperandsFromUseLists(); + + N->setParent(0); LeakDetector::addGarbageObject(N); } +/// transferNodesFromList (MI) - When moving a range of instructions from one +/// MBB list to another, we need to update the parent pointers and the use/def +/// lists. void ilist_traits::transferNodesFromList( - iplist >& fromList, - ilist_iterator first, - ilist_iterator last) { - if (parent != fromList.parent) + iplist >& fromList, + ilist_iterator first, + ilist_iterator last) { + // Splice within the same MBB -> no change. + if (parent == fromList.parent) return; + + // If splicing between two blocks within the same function, just update the + // parent pointers. + if (parent->getParent() == fromList.parent->getParent()) { for (; first != last; ++first) - first->parent = parent; + first->setParent(parent); + return; + } + + // Otherwise, we have to update the parent and the use/def lists. The common + // case when this occurs is if we're splicing from a block in a MF to a block + // that is not in an MF. + bool HasOldMF = fromList.parent->getParent() != 0; + MachineFunction *NewMF = parent->getParent(); + + for (; first != last; ++first) { + if (HasOldMF) first->RemoveRegOperandsFromUseLists(); + first->setParent(parent); + if (NewMF) first->AddRegOperandsToUseLists(NewMF->getRegInfo()); + } } MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() { - const TargetInstrInfo& TII = *getParent()->getTarget().getInstrInfo(); iterator I = end(); - while (I != begin() && TII.isTerminatorInstr((--I)->getOpcode())); - if (I != end() && !TII.isTerminatorInstr(I->getOpcode())) ++I; + while (I != begin() && (--I)->getDesc().isTerminator()) + ; /*noop */ + if (I != end() && !I->getDesc().isTerminator()) ++I; return I; } @@ -91,10 +143,10 @@ void MachineBasicBlock::dump() const { } static inline void OutputReg(std::ostream &os, unsigned RegNo, - const MRegisterInfo *MRI = 0) { - if (!RegNo || MRegisterInfo::isPhysicalRegister(RegNo)) { - if (MRI) - os << " %" << MRI->get(RegNo).Name; + const TargetRegisterInfo *TRI = 0) { + if (!RegNo || TargetRegisterInfo::isPhysicalRegister(RegNo)) { + if (TRI) + os << " %" << TRI->get(RegNo).Name; else os << " %mreg(" << RegNo << ")"; } else @@ -114,14 +166,15 @@ void MachineBasicBlock::print(std::ostream &OS) const { if (LBB) OS << LBB->getName() << ": "; OS << (const void*)this << ", LLVM BB @" << (const void*) LBB << ", ID#" << getNumber(); + if (Alignment) OS << ", Alignment " << Alignment; if (isLandingPad()) OS << ", EH LANDING PAD"; OS << ":\n"; - const MRegisterInfo *MRI = MF->getTarget().getRegisterInfo(); - if (livein_begin() != livein_end()) { + const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); + if (!livein_empty()) { OS << "Live Ins:"; for (const_livein_iterator I = livein_begin(),E = livein_end(); I != E; ++I) - OutputReg(OS, *I, MRI); + OutputReg(OS, *I, TRI); OS << "\n"; } // Print the preds of this block according to the CFG. @@ -152,6 +205,11 @@ void MachineBasicBlock::removeLiveIn(unsigned Reg) { LiveIns.erase(I); } +bool MachineBasicBlock::isLiveIn(unsigned Reg) const { + const_livein_iterator I = std::find(livein_begin(), livein_end(), Reg); + return I != livein_end(); +} + void MachineBasicBlock::moveBefore(MachineBasicBlock *NewAfter) { MachineFunction::BasicBlockListType &BBList =getParent()->getBasicBlockList(); getParent()->getBasicBlockList().splice(NewAfter, BBList, this); @@ -176,7 +234,8 @@ void MachineBasicBlock::removeSuccessor(MachineBasicBlock *succ) { Successors.erase(I); } -MachineBasicBlock::succ_iterator MachineBasicBlock::removeSuccessor(succ_iterator I) { +MachineBasicBlock::succ_iterator +MachineBasicBlock::removeSuccessor(succ_iterator I) { assert(I != Successors.end() && "Not a current successor!"); (*I)->removePredecessor(this); return(Successors.erase(I)); @@ -193,6 +252,19 @@ void MachineBasicBlock::removePredecessor(MachineBasicBlock *pred) { Predecessors.erase(I); } +void MachineBasicBlock::transferSuccessors(MachineBasicBlock *fromMBB) +{ + if (this == fromMBB) + return; + + for(MachineBasicBlock::succ_iterator iter = fromMBB->succ_begin(), + end = fromMBB->succ_end(); iter != end; ++iter) { + addSuccessor(*iter); + } + while(!fromMBB->succ_empty()) + fromMBB->removeSuccessor(fromMBB->succ_begin()); +} + bool MachineBasicBlock::isSuccessor(MachineBasicBlock *MBB) const { std::vector::const_iterator I = std::find(Successors.begin(), Successors.end(), MBB); @@ -208,14 +280,13 @@ void MachineBasicBlock::ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock::iterator I = end(); while (I != begin()) { --I; - if (!(I->getInstrDescriptor()->Flags & M_TERMINATOR_FLAG)) break; + if (!I->getDesc().isTerminator()) break; // Scan the operands of this machine instruction, replacing any uses of Old // with New. for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (I->getOperand(i).isMachineBasicBlock() && - I->getOperand(i).getMachineBasicBlock() == Old) - I->getOperand(i).setMachineBasicBlock(New); + if (I->getOperand(i).isMBB() && I->getOperand(i).getMBB() == Old) + I->getOperand(i).setMBB(New); } // Update the successor information. If New was already a successor, just @@ -229,8 +300,8 @@ void MachineBasicBlock::ReplaceUsesOfBlockWith(MachineBasicBlock *Old, /// CFG to be inserted. If we have proven that MBB can only branch to DestA and /// DestB, remove any other MBB successors from the CFG. DestA and DestB can /// be null. -/// Besides DestA and DestB, retain other edges leading to LandingPads (currently -/// there can be only one; we don't check or require that here). +/// Besides DestA and DestB, retain other edges leading to LandingPads +/// (currently there can be only one; we don't check or require that here). /// Note it is possible that DestA and/or DestB are LandingPads. bool MachineBasicBlock::CorrectExtraCFGEdges(MachineBasicBlock *DestA, MachineBasicBlock *DestB,