From 0a3f39985b3827a02a7ce1ca5e310b68820fd26d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 17 Feb 2010 18:52:56 +0000 Subject: [PATCH] move isOnlyReachableByFallthrough out of MachineBasicBlock into AsmPrinter, and add a sparc implementation that knows about delay slots. Patch by Nathan Keynes! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96492 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 5 +++ include/llvm/CodeGen/MachineBasicBlock.h | 5 --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 35 ++++++++++++++++++- lib/CodeGen/MachineBasicBlock.cpp | 30 ---------------- .../Sparc/AsmPrinter/SparcAsmPrinter.cpp | 35 +++++++++++++++++++ utils/TableGen/DAGISelEmitter.cpp | 2 +- 6 files changed, 75 insertions(+), 37 deletions(-) diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 28a1a3e7f3a..d4e8887288f 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -356,6 +356,11 @@ namespace llvm { /// printOffset - This is just convenient handler for printing offsets. void printOffset(int64_t Offset) const; + /// isBlockOnlyReachableByFallthough - Return true if the basic block has + /// exactly one predecessor and the control transfer mechanism between + /// the predecessor and this block is a fall-through. + virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; + private: /// processDebugLoc - Processes the debug information of each machine diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index db82ba5b565..d92650b42c9 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -285,11 +285,6 @@ public: /// it returns end() iterator getFirstTerminator(); - /// isOnlyReachableViaFallthough - Return true if this basic block has - /// exactly one predecessor and the control transfer mechanism between - /// the predecessor and this block is a fall-through. - bool isOnlyReachableByFallthrough() const; - void pop_front() { Insts.pop_front(); } void pop_back() { Insts.pop_back(); } void push_back(MachineInstr *MI) { Insts.push_back(MI); } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index fc083845938..9f905db70e9 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1717,7 +1717,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { } // Print the main label for the block. - if (MBB->pred_empty() || MBB->isOnlyReachableByFallthrough()) { + if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) { if (VerboseAsm) { // NOTE: Want this comment at start of line. O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':'; @@ -1764,6 +1764,39 @@ void AsmPrinter::printOffset(int64_t Offset) const { O << Offset; } +/// isBlockOnlyReachableByFallthough - Return true if the basic block has +/// exactly one predecessor and the control transfer mechanism between +/// the predecessor and this block is a fall-through. +bool AsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) + const { + // If this is a landing pad, it isn't a fall through. If it has no preds, + // then nothing falls through to it. + if (MBB->isLandingPad() || MBB->pred_empty()) + return false; + + // If there isn't exactly one predecessor, it can't be a fall through. + MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; + ++PI2; + if (PI2 != MBB->pred_end()) + return false; + + // The predecessor has to be immediately before this block. + const MachineBasicBlock *Pred = *PI; + + if (!Pred->isLayoutSuccessor(MBB)) + return false; + + // If the block is completely empty, then it definitely does fall through. + if (Pred->empty()) + return true; + + // Otherwise, check the last instruction. + const MachineInstr &LastInst = Pred->back(); + return !LastInst.getDesc().isBarrier(); +} + + + GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { if (!S->usesMetadata()) return 0; diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index 655a0bf4450..64134ce59e9 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -143,36 +143,6 @@ MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() { return I; } -/// isOnlyReachableViaFallthough - Return true if this basic block has -/// exactly one predecessor and the control transfer mechanism between -/// the predecessor and this block is a fall-through. -bool MachineBasicBlock::isOnlyReachableByFallthrough() const { - // If this is a landing pad, it isn't a fall through. If it has no preds, - // then nothing falls through to it. - if (isLandingPad() || pred_empty()) - return false; - - // If there isn't exactly one predecessor, it can't be a fall through. - const_pred_iterator PI = pred_begin(), PI2 = PI; - ++PI2; - if (PI2 != pred_end()) - return false; - - // The predecessor has to be immediately before this block. - const MachineBasicBlock *Pred = *PI; - - if (!Pred->isLayoutSuccessor(this)) - return false; - - // If the block is completely empty, then it definitely does fall through. - if (Pred->empty()) - return true; - - // Otherwise, check the last instruction. - const MachineInstr &LastInst = Pred->back(); - return !LastInst.getDesc().isBarrier(); -} - void MachineBasicBlock::dump() const { print(dbgs()); } diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp index 9a2ce6bec17..ecb8b0084f0 100644 --- a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp +++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp @@ -56,6 +56,9 @@ namespace { unsigned AsmVariant, const char *ExtraCode); bool printGetPCX(const MachineInstr *MI, unsigned OpNo); + + virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) + const; }; } // end of anonymous namespace @@ -197,6 +200,38 @@ bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, return false; } +/// isBlockOnlyReachableByFallthough - Return true if the basic block has +/// exactly one predecessor and the control transfer mechanism between +/// the predecessor and this block is a fall-through. +/// Override AsmPrinter implementation to handle delay slots +bool SparcAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) + const { + // If this is a landing pad, it isn't a fall through. If it has no preds, + // then nothing falls through to it. + if (MBB->isLandingPad() || MBB->pred_empty()) + return false; + + // If there isn't exactly one predecessor, it can't be a fall through. + MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; + ++PI2; + if (PI2 != MBB->pred_end()) + return false; + + // The predecessor has to be immediately before this block. + const MachineBasicBlock *Pred = *PI; + + if (!Pred->isLayoutSuccessor(MBB)) + return false; + + // Check if the last terminator is an unconditional branch + MachineBasicBlock::const_iterator I = Pred->end(); + while( I != Pred->begin() && !(--I)->getDesc().isTerminator() ) + ; /* Noop */ + return I == Pred->end() || !I->getDesc().isBarrier(); +} + + + // Force static initialization. extern "C" void LLVMInitializeSparcAsmPrinter() { RegisterAsmPrinter X(TheSparcTarget); diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index e0e25731e5b..28ac762c6d9 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -1975,7 +1975,7 @@ void DAGISelEmitter::run(raw_ostream &OS) { // definitions. Emit the resultant instruction selector. EmitInstructionSelector(OS); -#if 0 +#if 1 MatcherNode *Matcher = 0; // Walk the patterns backwards, building a matcher for each and adding it to // the matcher for the whole target. -- 2.34.1