134 lines
4.9 KiB
Diff
134 lines
4.9 KiB
Diff
Pull in r199014 from upstream llvm trunk (by Venkatraman Govindaraju):
|
|
|
|
[Sparc] Bundle instruction with delay slow and its filler. Now, we can use -verify-machineinstrs with SPARC backend.
|
|
|
|
Introduced here: http://svnweb.freebsd.org/changeset/base/262261
|
|
|
|
Index: lib/Target/Sparc/DelaySlotFiller.cpp
|
|
===================================================================
|
|
--- lib/Target/Sparc/DelaySlotFiller.cpp
|
|
+++ lib/Target/Sparc/DelaySlotFiller.cpp
|
|
@@ -19,6 +19,7 @@
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
+#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
@@ -55,6 +56,11 @@ namespace {
|
|
bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
|
|
bool runOnMachineFunction(MachineFunction &F) {
|
|
bool Changed = false;
|
|
+
|
|
+ // This pass invalidates liveness information when it reorders
|
|
+ // instructions to fill delay slot.
|
|
+ F.getRegInfo().invalidateLiveness();
|
|
+
|
|
for (MachineFunction::iterator FI = F.begin(), FE = F.end();
|
|
FI != FE; ++FI)
|
|
Changed |= runOnMachineBasicBlock(*FI);
|
|
@@ -61,9 +67,6 @@ namespace {
|
|
return Changed;
|
|
}
|
|
|
|
- bool isDelayFiller(MachineBasicBlock &MBB,
|
|
- MachineBasicBlock::iterator candidate);
|
|
-
|
|
void insertCallDefsUses(MachineBasicBlock::iterator MI,
|
|
SmallSet<unsigned, 32>& RegDefs,
|
|
SmallSet<unsigned, 32>& RegUses);
|
|
@@ -152,6 +155,10 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBl
|
|
assert (J != MBB.end() && "MI needs a delay instruction.");
|
|
BuildMI(MBB, ++J, MI->getDebugLoc(),
|
|
TII->get(SP::UNIMP)).addImm(structSize);
|
|
+ // Bundle the delay filler and unimp with the instruction.
|
|
+ MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), J);
|
|
+ } else {
|
|
+ MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), I);
|
|
}
|
|
}
|
|
return Changed;
|
|
@@ -209,7 +216,7 @@ Filler::findDelayInstr(MachineBasicBlock &MBB,
|
|
|| I->isInlineAsm()
|
|
|| I->isLabel()
|
|
|| I->hasDelaySlot()
|
|
- || isDelayFiller(MBB, I))
|
|
+ || I->isBundledWithSucc())
|
|
break;
|
|
|
|
if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
|
|
@@ -332,18 +339,6 @@ bool Filler::IsRegInSet(SmallSet<unsigned, 32>& Re
|
|
return false;
|
|
}
|
|
|
|
-// return true if the candidate is a delay filler.
|
|
-bool Filler::isDelayFiller(MachineBasicBlock &MBB,
|
|
- MachineBasicBlock::iterator candidate)
|
|
-{
|
|
- if (candidate == MBB.begin())
|
|
- return false;
|
|
- if (candidate->getOpcode() == SP::UNIMP)
|
|
- return true;
|
|
- --candidate;
|
|
- return candidate->hasDelaySlot();
|
|
-}
|
|
-
|
|
bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)
|
|
{
|
|
if (!I->isCall())
|
|
@@ -484,10 +479,10 @@ bool Filler::tryCombineRestoreWithPrevInst(Machine
|
|
&& MBBI->getOperand(1).getReg() == SP::G0
|
|
&& MBBI->getOperand(2).getReg() == SP::G0);
|
|
|
|
- MachineBasicBlock::iterator PrevInst = MBBI; --PrevInst;
|
|
+ MachineBasicBlock::iterator PrevInst = llvm::prior(MBBI);
|
|
|
|
- // It cannot combine with a delay filler.
|
|
- if (isDelayFiller(MBB, PrevInst))
|
|
+ // It cannot be combined with a bundled instruction.
|
|
+ if (PrevInst->isBundledWithSucc())
|
|
return false;
|
|
|
|
const TargetInstrInfo *TII = TM.getInstrInfo();
|
|
Index: lib/Target/Sparc/SparcAsmPrinter.cpp
|
|
===================================================================
|
|
--- lib/Target/Sparc/SparcAsmPrinter.cpp
|
|
+++ lib/Target/Sparc/SparcAsmPrinter.cpp
|
|
@@ -184,7 +184,6 @@ static void LowerGETPCXAndEmitMCInsts(const Machin
|
|
|
|
void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI)
|
|
{
|
|
- MCInst TmpInst;
|
|
|
|
switch (MI->getOpcode()) {
|
|
default: break;
|
|
@@ -195,8 +194,13 @@ void SparcAsmPrinter::EmitInstruction(const Machin
|
|
LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
|
|
return;
|
|
}
|
|
- LowerSparcMachineInstrToMCInst(MI, TmpInst, *this);
|
|
- OutStreamer.EmitInstruction(TmpInst);
|
|
+ MachineBasicBlock::const_instr_iterator I = MI;
|
|
+ MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
|
|
+ do {
|
|
+ MCInst TmpInst;
|
|
+ LowerSparcMachineInstrToMCInst(I, TmpInst, *this);
|
|
+ OutStreamer.EmitInstruction(TmpInst);
|
|
+ } while ((++I != E) && I->isInsideBundle()); // Delay slot check.
|
|
}
|
|
|
|
void SparcAsmPrinter::EmitFunctionBodyStart() {
|
|
Index: test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
|
|
===================================================================
|
|
--- test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
|
|
+++ test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
|
|
@@ -1,5 +1,5 @@
|
|
-;RUN: llc -march=sparc < %s | FileCheck %s
|
|
-;RUN: llc -march=sparc -O0 < %s | FileCheck %s -check-prefix=UNOPT
|
|
+;RUN: llc -march=sparc < %s -verify-machineinstrs | FileCheck %s
|
|
+;RUN: llc -march=sparc -O0 < %s -verify-machineinstrs | FileCheck %s -check-prefix=UNOPT
|
|
|
|
|
|
define i32 @test(i32 %a) nounwind {
|