2014-03-18 22:07:45 +00:00
|
|
|
Pull in r199061 from upstream llvm trunk (by Jakob Stoklund Olesen):
|
|
|
|
|
|
|
|
Handle bundled terminators in isBlockOnlyReachableByFallthrough.
|
|
|
|
|
|
|
|
Targets like SPARC and MIPS have delay slots and normally bundle the
|
|
|
|
delay slot instruction with the corresponding terminator.
|
|
|
|
|
|
|
|
Teach isBlockOnlyReachableByFallthrough to find any MBB operands on
|
|
|
|
bundled terminators so SPARC doesn't need to specialize this function.
|
|
|
|
|
2014-05-24 22:27:31 +00:00
|
|
|
Introduced here: http://svnweb.freebsd.org/changeset/base/262261
|
2014-03-18 22:07:45 +00:00
|
|
|
|
|
|
|
Index: test/CodeGen/SPARC/missinglabel.ll
|
|
|
|
===================================================================
|
|
|
|
--- test/CodeGen/SPARC/missinglabel.ll
|
|
|
|
+++ test/CodeGen/SPARC/missinglabel.ll
|
|
|
|
@@ -0,0 +1,23 @@
|
|
|
|
+; RUN: llc < %s -verify-machineinstrs | FileCheck %s
|
|
|
|
+target datalayout = "E-m:e-i64:64-n32:64-S128"
|
|
|
|
+target triple = "sparc64-unknown-linux-gnu"
|
|
|
|
+
|
|
|
|
+define void @f() align 2 {
|
|
|
|
+entry:
|
|
|
|
+; CHECK: %xcc, .LBB0_1
|
|
|
|
+ %cmp = icmp eq i64 undef, 0
|
|
|
|
+ br i1 %cmp, label %targetblock, label %cond.false
|
|
|
|
+
|
|
|
|
+cond.false:
|
|
|
|
+ unreachable
|
|
|
|
+
|
|
|
|
+; CHECK: .LBB0_1: ! %targetblock
|
|
|
|
+targetblock:
|
|
|
|
+ br i1 undef, label %cond.false.i83, label %exit.i85
|
|
|
|
+
|
|
|
|
+cond.false.i83:
|
|
|
|
+ unreachable
|
|
|
|
+
|
|
|
|
+exit.i85:
|
|
|
|
+ unreachable
|
|
|
|
+}
|
|
|
|
Index: lib/Target/Sparc/SparcAsmPrinter.cpp
|
|
|
|
===================================================================
|
|
|
|
--- lib/Target/Sparc/SparcAsmPrinter.cpp
|
|
|
|
+++ lib/Target/Sparc/SparcAsmPrinter.cpp
|
|
|
|
@@ -65,10 +65,6 @@ namespace {
|
|
|
|
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
|
|
|
unsigned AsmVariant, const char *ExtraCode,
|
|
|
|
raw_ostream &O);
|
|
|
|
-
|
|
|
|
- virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
|
|
|
|
- const;
|
|
|
|
-
|
|
|
|
};
|
|
|
|
} // end of anonymous namespace
|
|
|
|
|
|
|
|
@@ -390,37 +386,6 @@ bool SparcAsmPrinter::PrintAsmMemoryOperand(const
|
|
|
|
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.
|
|
|
|
-///
|
|
|
|
-/// This overrides AsmPrinter's 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)->isTerminator())
|
|
|
|
- ; // Noop
|
|
|
|
- return I == Pred->end() || !I->isBarrier();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
// Force static initialization.
|
|
|
|
extern "C" void LLVMInitializeSparcAsmPrinter() {
|
|
|
|
RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget);
|
|
|
|
Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp
|
|
|
|
===================================================================
|
|
|
|
--- lib/CodeGen/AsmPrinter/AsmPrinter.cpp
|
|
|
|
+++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp
|
|
|
|
@@ -23,6 +23,7 @@
|
|
|
|
#include "llvm/CodeGen/MachineConstantPool.h"
|
|
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
|
|
+#include "llvm/CodeGen/MachineInstrBundle.h"
|
|
|
|
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineLoopInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
|
|
|
@@ -2221,14 +2222,13 @@ isBlockOnlyReachableByFallthrough(const MachineBas
|
|
|
|
if (!MI.isBranch() || MI.isIndirectBranch())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
- // If we are the operands of one of the branches, this is not
|
|
|
|
- // a fall through.
|
|
|
|
- for (MachineInstr::mop_iterator OI = MI.operands_begin(),
|
|
|
|
- OE = MI.operands_end(); OI != OE; ++OI) {
|
|
|
|
- const MachineOperand& OP = *OI;
|
|
|
|
- if (OP.isJTI())
|
|
|
|
+ // If we are the operands of one of the branches, this is not a fall
|
|
|
|
+ // through. Note that targets with delay slots will usually bundle
|
|
|
|
+ // terminators with the delay slot instruction.
|
|
|
|
+ for (ConstMIBundleOperands OP(&MI); OP.isValid(); ++OP) {
|
|
|
|
+ if (OP->isJTI())
|
|
|
|
return false;
|
|
|
|
- if (OP.isMBB() && OP.getMBB() == MBB)
|
|
|
|
+ if (OP->isMBB() && OP->getMBB() == MBB)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|