blob: 0dbcdf3cb9c18f56dfcfae1e8697b78d254e071e [file] [log] [blame]
Chris Lattner55291ea2002-10-28 01:41:47 +00001//===-- PeepholeOpts.cpp --------------------------------------------------===//
Vikram S. Adve25d80cd2002-09-20 00:42:11 +00002//
Chris Lattner55291ea2002-10-28 01:41:47 +00003// Support for performing several peephole opts in one or a few passes over the
4// machine code of a method.
5//
6//===----------------------------------------------------------------------===//
Vikram S. Adve25d80cd2002-09-20 00:42:11 +00007
Chris Lattner67699ff2003-09-01 20:33:07 +00008#include "SparcInternals.h"
Misha Brukmanb7551ef2002-10-28 20:00:31 +00009#include "llvm/CodeGen/MachineFunction.h"
Vikram S. Adve25d80cd2002-09-20 00:42:11 +000010#include "llvm/CodeGen/MachineInstr.h"
11#include "llvm/Target/TargetMachine.h"
Chris Lattner3501fea2003-01-14 22:00:31 +000012#include "llvm/Target/TargetInstrInfo.h"
Vikram S. Adve25d80cd2002-09-20 00:42:11 +000013#include "llvm/BasicBlock.h"
14#include "llvm/Pass.h"
15
Vikram S. Adve25d80cd2002-09-20 00:42:11 +000016//************************* Internal Functions *****************************/
17
Chris Lattnere96e2632003-09-01 20:24:06 +000018static inline void
Chris Lattner55291ea2002-10-28 01:41:47 +000019DeleteInstruction(MachineBasicBlock& mvec,
20 MachineBasicBlock::iterator& BBI,
Chris Lattnere96e2632003-09-01 20:24:06 +000021 const TargetMachine& target) {
Vikram S. Adve25d80cd2002-09-20 00:42:11 +000022 // Check if this instruction is in a delay slot of its predecessor.
Misha Brukmanf96eb642003-05-23 19:20:57 +000023 if (BBI != mvec.begin()) {
Chris Lattner3501fea2003-01-14 22:00:31 +000024 const TargetInstrInfo& mii = target.getInstrInfo();
Vikram S. Adve25d80cd2002-09-20 00:42:11 +000025 MachineInstr* predMI = *(BBI-1);
Misha Brukmanf96eb642003-05-23 19:20:57 +000026 if (unsigned ndelay = mii.getNumDelaySlots(predMI->getOpCode())) {
27 // This instruction is in a delay slot of its predecessor, so
28 // replace it with a nop. By replacing in place, we save having
29 // to update the I-I maps.
30 //
31 assert(ndelay == 1 && "Not yet handling multiple-delay-slot targets");
32 (*BBI)->replace(mii.getNOPOpCode(), 0);
33 return;
34 }
35 }
Vikram S. Adve7e5167a2002-09-27 14:27:37 +000036
37 // The instruction is not in a delay slot, so we can simply erase it.
38 mvec.erase(BBI);
39 BBI = mvec.end();
Vikram S. Adve25d80cd2002-09-20 00:42:11 +000040}
41
42//******************* Individual Peephole Optimizations ********************/
43
Chris Lattnera89d8f72003-09-01 20:38:03 +000044//----------------------------------------------------------------------------
45// Function: IsUselessCopy
46// Decide whether a machine instruction is a redundant copy:
47// -- ADD with g0 and result and operand are identical, or
48// -- OR with g0 and result and operand are identical, or
49// -- FMOVS or FMOVD and result and operand are identical.
50// Other cases are possible but very rare that they would be useless copies,
51// so it's not worth analyzing them.
52//----------------------------------------------------------------------------
53
54static bool IsUselessCopy(const TargetMachine &target, const MachineInstr* MI) {
55 if (MI->getOpCode() == V9::FMOVS || MI->getOpCode() == V9::FMOVD) {
56 return (/* both operands are allocated to the same register */
57 MI->getOperand(0).getAllocatedRegNum() ==
58 MI->getOperand(1).getAllocatedRegNum());
59 } else if (MI->getOpCode() == V9::ADDr || MI->getOpCode() == V9::ORr) {
60 unsigned srcWithDestReg;
61
62 for (srcWithDestReg = 0; srcWithDestReg < 2; ++srcWithDestReg)
63 if (MI->getOperand(srcWithDestReg).hasAllocatedReg() &&
64 MI->getOperand(srcWithDestReg).getAllocatedRegNum()
65 == MI->getOperand(2).getAllocatedRegNum())
66 break;
67
68 if (srcWithDestReg == 2)
69 return false;
70 else {
71 /* else source and dest are allocated to the same register */
72 unsigned otherOp = 1 - srcWithDestReg;
73 return (/* either operand otherOp is register %g0 */
74 (MI->getOperand(otherOp).hasAllocatedReg() &&
75 MI->getOperand(otherOp).getAllocatedRegNum() ==
76 target.getRegInfo().getZeroRegNum()) ||
77
78 /* or operand otherOp == 0 */
79 (MI->getOperand(otherOp).getType()
80 == MachineOperand::MO_SignExtendedImmed &&
81 MI->getOperand(otherOp).getImmedValue() == 0));
82 }
83 }
84 else
85 return false;
86}
87
Vikram S. Adve25d80cd2002-09-20 00:42:11 +000088inline bool
Chris Lattner55291ea2002-10-28 01:41:47 +000089RemoveUselessCopies(MachineBasicBlock& mvec,
90 MachineBasicBlock::iterator& BBI,
Chris Lattnere96e2632003-09-01 20:24:06 +000091 const TargetMachine& target) {
Chris Lattnera89d8f72003-09-01 20:38:03 +000092 if (IsUselessCopy(target, *BBI)) {
Misha Brukmanf96eb642003-05-23 19:20:57 +000093 DeleteInstruction(mvec, BBI, target);
94 return true;
95 }
Vikram S. Adve25d80cd2002-09-20 00:42:11 +000096 return false;
97}
98
99
100//************************ Class Implementations **************************/
101
102class PeepholeOpts: public BasicBlockPass {
103 const TargetMachine &target;
Chris Lattner55291ea2002-10-28 01:41:47 +0000104 bool visit(MachineBasicBlock& mvec,
105 MachineBasicBlock::iterator BBI) const;
Vikram S. Adve25d80cd2002-09-20 00:42:11 +0000106public:
107 PeepholeOpts(const TargetMachine &T): target(T) { }
108 bool runOnBasicBlock(BasicBlock &BB); // apply this pass to each BB
Chris Lattnera8e40f52003-08-14 14:43:24 +0000109 virtual const char *getPassName() const { return "Peephole Optimization"; }
Vikram S. Adve25d80cd2002-09-20 00:42:11 +0000110};
111
Chris Lattnere96e2632003-09-01 20:24:06 +0000112// Apply a list of peephole optimizations to this machine instruction
113// within its local context. They are allowed to delete MI or any
114// instruction before MI, but not
115//
116bool PeepholeOpts::visit(MachineBasicBlock& mvec,
117 MachineBasicBlock::iterator BBI) const {
Vikram S. Adve25d80cd2002-09-20 00:42:11 +0000118 /* Remove redundant copy instructions */
Chris Lattnere96e2632003-09-01 20:24:06 +0000119 return RemoveUselessCopies(mvec, BBI, target);
Vikram S. Adve25d80cd2002-09-20 00:42:11 +0000120}
121
122
Chris Lattnere96e2632003-09-01 20:24:06 +0000123bool PeepholeOpts::runOnBasicBlock(BasicBlock &BB) {
Vikram S. Adve25d80cd2002-09-20 00:42:11 +0000124 // Get the machine instructions for this BB
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000125 // FIXME: MachineBasicBlock::get() is deprecated, hence inlining the function
126 const Function *F = BB.getParent();
127 MachineFunction &MF = MachineFunction::get(F);
128 MachineBasicBlock *MBB = NULL;
Chris Lattnere96e2632003-09-01 20:24:06 +0000129 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000130 if (I->getBasicBlock() == &BB)
131 MBB = I;
Chris Lattnere96e2632003-09-01 20:24:06 +0000132
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000133 assert(MBB && "MachineBasicBlock object not found for specified block!");
134 MachineBasicBlock &mvec = *MBB;
Vikram S. Adve25d80cd2002-09-20 00:42:11 +0000135
136 // Iterate over all machine instructions in the BB
137 // Use a reverse iterator to allow deletion of MI or any instruction after it.
138 // Insertions or deletions *before* MI are not safe.
139 //
Chris Lattner55291ea2002-10-28 01:41:47 +0000140 for (MachineBasicBlock::reverse_iterator RI=mvec.rbegin(),
Chris Lattnere96e2632003-09-01 20:24:06 +0000141 RE=mvec.rend(); RI != RE; ) {
Misha Brukmanf96eb642003-05-23 19:20:57 +0000142 MachineBasicBlock::iterator BBI = RI.base()-1; // save before incr
143 ++RI; // pre-increment to delete MI or after it
144 visit(mvec, BBI);
145 }
Vikram S. Adve25d80cd2002-09-20 00:42:11 +0000146
147 return true;
148}
149
150
151//===----------------------------------------------------------------------===//
152// createPeepholeOptsPass - Public entrypoint for peephole optimization
153// and this file as a whole...
154//
Chris Lattnere96e2632003-09-01 20:24:06 +0000155FunctionPass* createPeepholeOptsPass(TargetMachine &T) {
Vikram S. Adve25d80cd2002-09-20 00:42:11 +0000156 return new PeepholeOpts(T);
157}