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