c6606b64532e909f224333cb424318a73cd3d90d
[oota-llvm.git] / lib / Target / Sparc / DelaySlotFiller.cpp
1 //===-- DelaySlotFiller.cpp - SparcV8 delay slot filler -------------------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // Simple local delay slot filler for SparcV8 machine code
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SparcV8.h"
15 #include "llvm/CodeGen/MachineFunctionPass.h"
16 #include "llvm/CodeGen/MachineInstrBuilder.h"
17 #include "Support/Statistic.h"
18
19 using namespace llvm;
20
21 namespace {
22   Statistic<> FilledSlots ("delayslotfiller", "Num. of delay slots filled");
23
24   struct Filler : public MachineFunctionPass {
25     /// Target machine description which we query for reg. names, data
26     /// layout, etc.
27     ///
28     TargetMachine &TM;
29
30     Filler (TargetMachine &tm) : TM (tm) { }
31
32     virtual const char *getPassName () const {
33       return "SparcV8 Delay Slot Filler";
34     }
35
36     bool runOnMachineBasicBlock (MachineBasicBlock &MBB);
37     bool runOnMachineFunction (MachineFunction &F) {
38       bool Changed = false;
39       for (MachineFunction::iterator FI = F.begin (), FE = F.end ();
40            FI != FE; ++FI)
41         Changed |= runOnMachineBasicBlock (*FI);
42       return Changed;
43     }
44
45   };
46 } // end of anonymous namespace
47
48 /// createSparcV8DelaySlotFillerPass - Returns a pass that fills in delay
49 /// slots in SparcV8 MachineFunctions
50 ///
51 FunctionPass *llvm::createSparcV8DelaySlotFillerPass (TargetMachine &tm) {
52   return new Filler (tm);
53 }
54
55 static bool hasDelaySlot (unsigned Opcode) {
56   switch (Opcode) {
57     case V8::BA:
58     case V8::BCC:
59     case V8::BCS:
60     case V8::BE:
61     case V8::BG:
62     case V8::BGE:
63     case V8::BGU:
64     case V8::BL:
65     case V8::BLE:
66     case V8::BLEU:
67     case V8::BNE:
68     case V8::CALL:
69     case V8::JMPLrr:
70     case V8::RETL:
71       return true;
72     default:
73       return false;
74   }
75 }
76
77 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
78 /// Currently, we fill delay slots with NOPs. We assume there is only one
79 /// delay slot per delayed instruction.
80 ///
81 bool Filler::runOnMachineBasicBlock (MachineBasicBlock &MBB) {
82   bool Changed = false;
83   for (MachineBasicBlock::iterator I = MBB.begin (); I != MBB.end (); ++I)
84     if (hasDelaySlot (I->getOpcode ())) {
85       MachineBasicBlock::iterator J = I;
86       ++J;
87       BuildMI (MBB, J, V8::NOP, 0);
88       ++FilledSlots;
89       Changed = true;
90     }
91   return Changed;
92 }