1263320SdimPull in r199014 from upstream llvm trunk (by Venkatraman Govindaraju):
2263320Sdim
3263320Sdim  [Sparc] Bundle instruction with delay slow and its filler. Now, we can use -verify-machineinstrs with SPARC backend.
4263320Sdim
5269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261
6263320Sdim
7263320SdimIndex: lib/Target/Sparc/DelaySlotFiller.cpp
8263320Sdim===================================================================
9263320Sdim--- lib/Target/Sparc/DelaySlotFiller.cpp
10263320Sdim+++ lib/Target/Sparc/DelaySlotFiller.cpp
11263320Sdim@@ -19,6 +19,7 @@
12263320Sdim #include "llvm/ADT/Statistic.h"
13263320Sdim #include "llvm/CodeGen/MachineFunctionPass.h"
14263320Sdim #include "llvm/CodeGen/MachineInstrBuilder.h"
15263320Sdim+#include "llvm/CodeGen/MachineRegisterInfo.h"
16263320Sdim #include "llvm/Support/CommandLine.h"
17263320Sdim #include "llvm/Target/TargetInstrInfo.h"
18263320Sdim #include "llvm/Target/TargetMachine.h"
19263320Sdim@@ -55,6 +56,11 @@ namespace {
20263320Sdim     bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
21263320Sdim     bool runOnMachineFunction(MachineFunction &F) {
22263320Sdim       bool Changed = false;
23263320Sdim+
24263320Sdim+      // This pass invalidates liveness information when it reorders
25263320Sdim+      // instructions to fill delay slot.
26263320Sdim+      F.getRegInfo().invalidateLiveness();
27263320Sdim+
28263320Sdim       for (MachineFunction::iterator FI = F.begin(), FE = F.end();
29263320Sdim            FI != FE; ++FI)
30263320Sdim         Changed |= runOnMachineBasicBlock(*FI);
31263320Sdim@@ -61,9 +67,6 @@ namespace {
32263320Sdim       return Changed;
33263320Sdim     }
34263320Sdim 
35263320Sdim-    bool isDelayFiller(MachineBasicBlock &MBB,
36263320Sdim-                       MachineBasicBlock::iterator candidate);
37263320Sdim-
38263320Sdim     void insertCallDefsUses(MachineBasicBlock::iterator MI,
39263320Sdim                             SmallSet<unsigned, 32>& RegDefs,
40263320Sdim                             SmallSet<unsigned, 32>& RegUses);
41263320Sdim@@ -152,6 +155,10 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBl
42263320Sdim       assert (J != MBB.end() && "MI needs a delay instruction.");
43263320Sdim       BuildMI(MBB, ++J, MI->getDebugLoc(),
44263320Sdim               TII->get(SP::UNIMP)).addImm(structSize);
45263320Sdim+      // Bundle the delay filler and unimp with the instruction.
46263320Sdim+      MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), J);
47263320Sdim+    } else {
48263320Sdim+      MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), I);
49263320Sdim     }
50263320Sdim   }
51263320Sdim   return Changed;
52263320Sdim@@ -209,7 +216,7 @@ Filler::findDelayInstr(MachineBasicBlock &MBB,
53263320Sdim         || I->isInlineAsm()
54263320Sdim         || I->isLabel()
55263320Sdim         || I->hasDelaySlot()
56263320Sdim-        || isDelayFiller(MBB, I))
57263320Sdim+        || I->isBundledWithSucc())
58263320Sdim       break;
59263320Sdim 
60263320Sdim     if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
61263320Sdim@@ -332,18 +339,6 @@ bool Filler::IsRegInSet(SmallSet<unsigned, 32>& Re
62263320Sdim   return false;
63263320Sdim }
64263320Sdim 
65263320Sdim-// return true if the candidate is a delay filler.
66263320Sdim-bool Filler::isDelayFiller(MachineBasicBlock &MBB,
67263320Sdim-                           MachineBasicBlock::iterator candidate)
68263320Sdim-{
69263320Sdim-  if (candidate == MBB.begin())
70263320Sdim-    return false;
71263320Sdim-  if (candidate->getOpcode() == SP::UNIMP)
72263320Sdim-    return true;
73263320Sdim-  --candidate;
74263320Sdim-  return candidate->hasDelaySlot();
75263320Sdim-}
76263320Sdim-
77263320Sdim bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)
78263320Sdim {
79263320Sdim   if (!I->isCall())
80263320Sdim@@ -484,10 +479,10 @@ bool Filler::tryCombineRestoreWithPrevInst(Machine
81263320Sdim          && MBBI->getOperand(1).getReg() == SP::G0
82263320Sdim          && MBBI->getOperand(2).getReg() == SP::G0);
83263320Sdim 
84263320Sdim-  MachineBasicBlock::iterator PrevInst = MBBI; --PrevInst;
85263320Sdim+  MachineBasicBlock::iterator PrevInst = llvm::prior(MBBI);
86263320Sdim 
87263320Sdim-  // It cannot combine with a delay filler.
88263320Sdim-  if (isDelayFiller(MBB, PrevInst))
89263320Sdim+  // It cannot be combined with a bundled instruction.
90263320Sdim+  if (PrevInst->isBundledWithSucc())
91263320Sdim     return false;
92263320Sdim 
93263320Sdim   const TargetInstrInfo *TII = TM.getInstrInfo();
94263320SdimIndex: lib/Target/Sparc/SparcAsmPrinter.cpp
95263320Sdim===================================================================
96263320Sdim--- lib/Target/Sparc/SparcAsmPrinter.cpp
97263320Sdim+++ lib/Target/Sparc/SparcAsmPrinter.cpp
98263320Sdim@@ -184,7 +184,6 @@ static void LowerGETPCXAndEmitMCInsts(const Machin
99263320Sdim 
100263320Sdim void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI)
101263320Sdim {
102263320Sdim-  MCInst TmpInst;
103263320Sdim 
104263320Sdim   switch (MI->getOpcode()) {
105263320Sdim   default: break;
106263320Sdim@@ -195,8 +194,13 @@ void SparcAsmPrinter::EmitInstruction(const Machin
107263320Sdim     LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
108263320Sdim     return;
109263320Sdim   }
110263320Sdim-  LowerSparcMachineInstrToMCInst(MI, TmpInst, *this);
111263320Sdim-  OutStreamer.EmitInstruction(TmpInst);
112263320Sdim+  MachineBasicBlock::const_instr_iterator I = MI;
113263320Sdim+  MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
114263320Sdim+  do {
115263320Sdim+    MCInst TmpInst;
116263320Sdim+    LowerSparcMachineInstrToMCInst(I, TmpInst, *this);
117263320Sdim+    OutStreamer.EmitInstruction(TmpInst);
118263320Sdim+  } while ((++I != E) && I->isInsideBundle()); // Delay slot check.
119263320Sdim }
120263320Sdim 
121263320Sdim void SparcAsmPrinter::EmitFunctionBodyStart() {
122263320SdimIndex: test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
123263320Sdim===================================================================
124263320Sdim--- test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
125263320Sdim+++ test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
126263320Sdim@@ -1,5 +1,5 @@
127263320Sdim-;RUN: llc -march=sparc < %s | FileCheck %s
128263320Sdim-;RUN: llc -march=sparc -O0 < %s | FileCheck %s -check-prefix=UNOPT
129263320Sdim+;RUN: llc -march=sparc < %s -verify-machineinstrs | FileCheck %s
130263320Sdim+;RUN: llc -march=sparc -O0 < %s -verify-machineinstrs | FileCheck %s -check-prefix=UNOPT
131263320Sdim 
132263320Sdim 
133263320Sdim define i32 @test(i32 %a) nounwind {
134