blob: 5d0920892ff0c75310a01bdc2162415adcfffc31 [file] [log] [blame]
Chris Dewhurst4f7cac32016-05-23 10:56:36 +00001//===------ LeonPasses.cpp - Define passes specific to LEON ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//
11//===----------------------------------------------------------------------===//
12
13#include "LeonPasses.h"
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000014#include "llvm/CodeGen/ISDOpcodes.h"
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000015#include "llvm/CodeGen/MachineFunction.h"
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000016#include "llvm/CodeGen/MachineInstr.h"
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000017#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000018#include "llvm/CodeGen/MachineRegisterInfo.h"
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000019#include "llvm/IR/LLVMContext.h"
20#include "llvm/Support/raw_ostream.h"
Benjamin Kramer797fb962016-05-27 10:06:27 +000021using namespace llvm;
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000022
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000023LEONMachineFunctionPass::LEONMachineFunctionPass(TargetMachine &tm, char &ID)
24 : MachineFunctionPass(ID) {}
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000025
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000026LEONMachineFunctionPass::LEONMachineFunctionPass(char &ID)
27 : MachineFunctionPass(ID) {}
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000028
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000029int LEONMachineFunctionPass::GetRegIndexForOperand(MachineInstr &MI,
30 int OperandIndex) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +000031 if (MI.getNumOperands() > 0) {
32 if (OperandIndex == LAST_OPERAND) {
33 OperandIndex = MI.getNumOperands() - 1;
34 }
35
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000036 if (MI.getNumOperands() > (unsigned)OperandIndex &&
Chris Dewhurst0c1e0022016-06-19 11:03:28 +000037 MI.getOperand(OperandIndex).isReg()) {
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000038 return (int)MI.getOperand(OperandIndex).getReg();
Chris Dewhurst0c1e0022016-06-19 11:03:28 +000039 }
40 }
41
42 static int NotFoundIndex = -10;
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000043 // Return a different number each time to avoid any comparisons between the
44 // values returned.
Chris Dewhurst0c1e0022016-06-19 11:03:28 +000045 NotFoundIndex -= 10;
46 return NotFoundIndex;
47}
48
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000049// finds a new free FP register
50// checks also the AllocatedRegisters vector
51int LEONMachineFunctionPass::getUnusedFPRegister(MachineRegisterInfo &MRI) {
52 for (int RegisterIndex = SP::F0; RegisterIndex <= SP::F31; ++RegisterIndex) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +000053 if (!MRI.isPhysRegUsed(RegisterIndex) &&
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000054 !(std::find(UsedRegisters.begin(), UsedRegisters.end(),
55 RegisterIndex) != UsedRegisters.end())) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +000056 return RegisterIndex;
57 }
58 }
59
60 return -1;
61}
62
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000063//*****************************************************************************
64//**** InsertNOPLoad pass
65//*****************************************************************************
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000066// This pass fixes the incorrectly working Load instructions that exists for
67// some earlier versions of the LEON processor line. NOP instructions must
68// be inserted after the load instruction to ensure that the Load instruction
69// behaves as expected for these processors.
70//
71// This pass inserts a NOP after any LD or LDF instruction.
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000072//
73char InsertNOPLoad::ID = 0;
74
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000075InsertNOPLoad::InsertNOPLoad(TargetMachine &tm)
76 : LEONMachineFunctionPass(tm, ID) {}
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000077
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000078bool InsertNOPLoad::runOnMachineFunction(MachineFunction &MF) {
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000079 Subtarget = &MF.getSubtarget<SparcSubtarget>();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000080 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000081 DebugLoc DL = DebugLoc();
82
83 bool Modified = false;
84 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
85 MachineBasicBlock &MBB = *MFI;
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000086 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000087 MachineInstr &MI = *MBBI;
88 unsigned Opcode = MI.getOpcode();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000089 if (Opcode >= SP::LDDArr && Opcode <= SP::LDrr) {
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000090 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
91 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
92 Modified = true;
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000093 } else if (MI.isInlineAsm()) {
Benjamin Kramer1cda54f2016-05-27 16:45:37 +000094 // Look for an inline ld or ldf instruction.
95 StringRef AsmString =
96 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName();
97 if (AsmString.startswith_lower("ld")) {
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000098 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
99 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
100 Modified = true;
101 }
102 }
103 }
104 }
105
106 return Modified;
107}
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000108
109//*****************************************************************************
110//**** FixFSMULD pass
111//*****************************************************************************
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000112// This pass fixes the incorrectly working FSMULD instruction that exists for
113// some earlier versions of the LEON processor line.
114//
115// The pass should convert the FSMULD operands to double precision in scratch
116// registers, then calculate the result with the FMULD instruction. Therefore,
117// the pass should replace operations of the form:
118// fsmuld %f20,%f21,%f8
119// with the sequence:
120// fstod %f20,%f0
121// fstod %f21,%f2
122// fmuld %f0,%f2,%f8
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000123//
124char FixFSMULD::ID = 0;
125
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000126FixFSMULD::FixFSMULD(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {}
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000127
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000128bool FixFSMULD::runOnMachineFunction(MachineFunction &MF) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000129 Subtarget = &MF.getSubtarget<SparcSubtarget>();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000130 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000131 DebugLoc DL = DebugLoc();
132
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000133 bool Modified = false;
134 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
135 MachineBasicBlock &MBB = *MFI;
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000136 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000137
138 MachineInstr &MI = *MBBI;
139 unsigned Opcode = MI.getOpcode();
140
141 const int UNASSIGNED_INDEX = -1;
142 int Reg1Index = UNASSIGNED_INDEX;
143 int Reg2Index = UNASSIGNED_INDEX;
144 int Reg3Index = UNASSIGNED_INDEX;
145
146 if (Opcode == SP::FSMULD && MI.getNumOperands() == 3) {
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000147 // take the registers from fsmuld %f20,%f21,%f8
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000148 Reg1Index = MI.getOperand(0).getReg();
149 Reg2Index = MI.getOperand(1).getReg();
150 Reg3Index = MI.getOperand(2).getReg();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000151 } else if (MI.isInlineAsm()) {
Chris Dewhurst3202f062016-07-08 15:33:56 +0000152 StringRef AsmString =
153 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName();
154 if (AsmString.startswith_lower("fsmuld")) {
155 // this is an inline FSMULD instruction
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000156
157 unsigned StartOp = InlineAsm::MIOp_FirstOperand;
158
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000159 // extracts the registers from the inline assembly instruction
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000160 for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) {
161 const MachineOperand &MO = MI.getOperand(i);
162 if (MO.isReg()) {
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000163 if (Reg1Index == UNASSIGNED_INDEX)
164 Reg1Index = MO.getReg();
165 else if (Reg2Index == UNASSIGNED_INDEX)
166 Reg2Index = MO.getReg();
167 else if (Reg3Index == UNASSIGNED_INDEX)
168 Reg3Index = MO.getReg();
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000169 }
170 if (Reg3Index != UNASSIGNED_INDEX)
171 break;
172 }
173 }
174 }
175
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000176 if (Reg1Index != UNASSIGNED_INDEX && Reg2Index != UNASSIGNED_INDEX &&
177 Reg3Index != UNASSIGNED_INDEX) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000178 clearUsedRegisterList();
179 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000180 // Whatever Reg3Index is hasn't been used yet, so we need to reserve it.
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000181 markRegisterUsed(Reg3Index);
182 const int ScratchReg1Index = getUnusedFPRegister(MF.getRegInfo());
183 markRegisterUsed(ScratchReg1Index);
184 const int ScratchReg2Index = getUnusedFPRegister(MF.getRegInfo());
185 markRegisterUsed(ScratchReg2Index);
186
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000187 if (ScratchReg1Index == UNASSIGNED_INDEX ||
188 ScratchReg2Index == UNASSIGNED_INDEX) {
189 errs() << "Cannot allocate free scratch registers for the FixFSMULD "
190 "pass."
191 << "\n";
192 } else {
193 // create fstod %f20,%f0
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000194 BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD))
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000195 .addReg(ScratchReg1Index)
196 .addReg(Reg1Index);
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000197
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000198 // create fstod %f21,%f2
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000199 BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD))
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000200 .addReg(ScratchReg2Index)
201 .addReg(Reg2Index);
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000202
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000203 // create fmuld %f0,%f2,%f8
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000204 BuildMI(MBB, MBBI, DL, TII.get(SP::FMULD))
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000205 .addReg(Reg3Index)
206 .addReg(ScratchReg1Index)
207 .addReg(ScratchReg2Index);
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000208
209 MI.eraseFromParent();
210 MBBI = NMBBI;
211
212 Modified = true;
213 }
214 }
215 }
216 }
217
218 return Modified;
219}
220
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000221//*****************************************************************************
222//**** ReplaceFMULS pass
223//*****************************************************************************
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000224// This pass fixes the incorrectly working FMULS instruction that exists for
225// some earlier versions of the LEON processor line.
226//
227// This pass converts the FMULS operands to double precision in scratch
228// registers, then calculates the result with the FMULD instruction.
229// The pass should replace operations of the form:
230// fmuls %f20,%f21,%f8
231// with the sequence:
232// fstod %f20,%f0
233// fstod %f21,%f2
234// fmuld %f0,%f2,%f8
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000235//
236char ReplaceFMULS::ID = 0;
237
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000238ReplaceFMULS::ReplaceFMULS(TargetMachine &tm)
239 : LEONMachineFunctionPass(tm, ID) {}
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000240
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000241bool ReplaceFMULS::runOnMachineFunction(MachineFunction &MF) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000242 Subtarget = &MF.getSubtarget<SparcSubtarget>();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000243 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000244 DebugLoc DL = DebugLoc();
245
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000246 bool Modified = false;
247 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
248 MachineBasicBlock &MBB = *MFI;
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000249 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000250 MachineInstr &MI = *MBBI;
251 unsigned Opcode = MI.getOpcode();
252
253 const int UNASSIGNED_INDEX = -1;
254 int Reg1Index = UNASSIGNED_INDEX;
255 int Reg2Index = UNASSIGNED_INDEX;
256 int Reg3Index = UNASSIGNED_INDEX;
257
258 if (Opcode == SP::FMULS && MI.getNumOperands() == 3) {
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000259 // take the registers from fmuls %f20,%f21,%f8
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000260 Reg1Index = MI.getOperand(0).getReg();
261 Reg2Index = MI.getOperand(1).getReg();
262 Reg3Index = MI.getOperand(2).getReg();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000263 } else if (MI.isInlineAsm()) {
Chris Dewhurst3202f062016-07-08 15:33:56 +0000264 StringRef AsmString =
265 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName();
266 if (AsmString.startswith_lower("fmuls")) {
267 // this is an inline FMULS instruction
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000268 unsigned StartOp = InlineAsm::MIOp_FirstOperand;
269
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000270 // extracts the registers from the inline assembly instruction
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000271 for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) {
272 const MachineOperand &MO = MI.getOperand(i);
273 if (MO.isReg()) {
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000274 if (Reg1Index == UNASSIGNED_INDEX)
275 Reg1Index = MO.getReg();
276 else if (Reg2Index == UNASSIGNED_INDEX)
277 Reg2Index = MO.getReg();
278 else if (Reg3Index == UNASSIGNED_INDEX)
279 Reg3Index = MO.getReg();
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000280 }
281 if (Reg3Index != UNASSIGNED_INDEX)
282 break;
283 }
284 }
285 }
286
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000287 if (Reg1Index != UNASSIGNED_INDEX && Reg2Index != UNASSIGNED_INDEX &&
288 Reg3Index != UNASSIGNED_INDEX) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000289 clearUsedRegisterList();
290 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000291 // Whatever Reg3Index is hasn't been used yet, so we need to reserve it.
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000292 markRegisterUsed(Reg3Index);
293 const int ScratchReg1Index = getUnusedFPRegister(MF.getRegInfo());
294 markRegisterUsed(ScratchReg1Index);
295 const int ScratchReg2Index = getUnusedFPRegister(MF.getRegInfo());
296 markRegisterUsed(ScratchReg2Index);
297
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000298 if (ScratchReg1Index == UNASSIGNED_INDEX ||
299 ScratchReg2Index == UNASSIGNED_INDEX) {
300 errs() << "Cannot allocate free scratch registers for the "
301 "ReplaceFMULS pass."
302 << "\n";
303 } else {
304 // create fstod %f20,%f0
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000305 BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD))
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000306 .addReg(ScratchReg1Index)
307 .addReg(Reg1Index);
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000308
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000309 // create fstod %f21,%f2
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000310 BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD))
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000311 .addReg(ScratchReg2Index)
312 .addReg(Reg2Index);
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000313
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000314 // create fmuld %f0,%f2,%f8
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000315 BuildMI(MBB, MBBI, DL, TII.get(SP::FMULD))
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000316 .addReg(Reg3Index)
317 .addReg(ScratchReg1Index)
318 .addReg(ScratchReg2Index);
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000319
320 MI.eraseFromParent();
321 MBBI = NMBBI;
322
323 Modified = true;
324 }
325 }
326 }
327 }
328
329 return Modified;
330}
331
332//*****************************************************************************
333//**** FixAllFDIVSQRT pass
334//*****************************************************************************
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000335// This pass fixes the incorrectly working FDIVx and FSQRTx instructions that
336// exist for some earlier versions of the LEON processor line. Five NOP
337// instructions need to be inserted after these instructions to ensure the
338// correct result is placed in the destination registers before they are used.
339//
340// This pass implements two fixes:
341// 1) fixing the FSQRTS and FSQRTD instructions.
342// 2) fixing the FDIVS and FDIVD instructions.
343//
344// FSQRTS and FDIVS are converted to FDIVD and FSQRTD respectively earlier in
345// the pipeline when this option is enabled, so this pass needs only to deal
346// with the changes that still need implementing for the "double" versions
347// of these instructions.
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000348//
349char FixAllFDIVSQRT::ID = 0;
350
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000351FixAllFDIVSQRT::FixAllFDIVSQRT(TargetMachine &tm)
352 : LEONMachineFunctionPass(tm, ID) {}
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000353
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000354bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000355 Subtarget = &MF.getSubtarget<SparcSubtarget>();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000356 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000357 DebugLoc DL = DebugLoc();
358
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000359 bool Modified = false;
360 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
361 MachineBasicBlock &MBB = *MFI;
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000362 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000363 MachineInstr &MI = *MBBI;
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000364 unsigned Opcode = MI.getOpcode();
365
366 if (MI.isInlineAsm()) {
Chris Dewhurst3202f062016-07-08 15:33:56 +0000367 StringRef AsmString =
368 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName();
369 if (AsmString.startswith_lower("fsqrtd")) {
370 // this is an inline fsqrts instruction
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000371 Opcode = SP::FSQRTD;
Chris Dewhurst3202f062016-07-08 15:33:56 +0000372 } else if (AsmString.startswith_lower("fdivd")) {
373 // this is an inline fsqrts instruction
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000374 Opcode = SP::FDIVD;
375 }
376 }
377
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000378 // Note: FDIVS and FSQRTS cannot be generated when this erratum fix is
379 // switched on so we don't need to check for them here. They will
380 // already have been converted to FSQRTD or FDIVD earlier in the
381 // pipeline.
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000382 if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) {
Chris Dewhurst3202f062016-07-08 15:33:56 +0000383 // Insert 5 NOPs before FSQRTD,FDIVD.
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000384 for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++)
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000385 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
386
387 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
Chris Dewhurst3202f062016-07-08 15:33:56 +0000388 // ... and inserting 28 NOPs after FSQRTD,FDIVD.
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000389 for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++)
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000390 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
391
392 Modified = true;
393 }
394 }
395 }
396
397 return Modified;
398}
Chris Dewhurst3202f062016-07-08 15:33:56 +0000399
400//*****************************************************************************
401//**** ReplaceSDIV pass
402//*****************************************************************************
403// This pass fixes the incorrectly working SDIV instruction that
404// exist for some earlier versions of the LEON processor line. The instruction
405// is replaced with an SDIVcc instruction instead, which is working.
406//
407char ReplaceSDIV::ID = 0;
408
409ReplaceSDIV::ReplaceSDIV() : LEONMachineFunctionPass(ID) {}
410
411ReplaceSDIV::ReplaceSDIV(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {}
412
413bool ReplaceSDIV::runOnMachineFunction(MachineFunction &MF) {
414 Subtarget = &MF.getSubtarget<SparcSubtarget>();
415 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
416
417 bool Modified = false;
418 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
419 MachineBasicBlock &MBB = *MFI;
420 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
421 MachineInstr &MI = *MBBI;
422 unsigned Opcode = MI.getOpcode();
423 if (Opcode == SP::SDIVrr) {
424 MI.setDesc(TII.get(SP::SDIVCCrr));
425 Modified = true;
426 } else if (Opcode == SP::SDIVri) {
427 MI.setDesc(TII.get(SP::SDIVCCri));
428 Modified = true;
429 }
430 }
431 }
432
433 return Modified;
434}
435
436static RegisterPass<ReplaceSDIV> X("replace-sdiv", "Replase SDIV Pass", false,
437 false);
438
439//*****************************************************************************
440//**** FixCALL pass
441//*****************************************************************************
442// This pass restricts the size of the immediate operand of the CALL
443// instruction, which can cause problems on some earlier versions of the LEON
444// processor, which can interpret some of the call address bits incorrectly.
445//
446char FixCALL::ID = 0;
447
448FixCALL::FixCALL(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {}
449
450bool FixCALL::runOnMachineFunction(MachineFunction &MF) {
451 bool Modified = false;
452
453 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
454 MachineBasicBlock &MBB = *MFI;
455 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
456 MachineInstr &MI = *MBBI;
457 MI.print(errs());
458 errs() << "\n";
459
460 unsigned Opcode = MI.getOpcode();
461 if (Opcode == SP::CALL || Opcode == SP::CALLrr) {
462 unsigned NumOperands = MI.getNumOperands();
463 for (unsigned OperandIndex = 0; OperandIndex < NumOperands;
464 OperandIndex++) {
465 MachineOperand &MO = MI.getOperand(OperandIndex);
466 if (MO.isImm()) {
467 int64_t Value = MO.getImm();
468 MO.setImm(Value & 0x000fffffL);
469 Modified = true;
470 break;
471 }
472 }
473 } else if (MI.isInlineAsm()) // inline assembly immediate call
474 {
475 StringRef AsmString =
476 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName();
477 if (AsmString.startswith_lower("call")) {
478 // this is an inline call instruction
479 unsigned StartOp = InlineAsm::MIOp_FirstOperand;
480
481 // extracts the registers from the inline assembly instruction
482 for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) {
483 MachineOperand &MO = MI.getOperand(i);
484 if (MO.isImm()) {
485 int64_t Value = MO.getImm();
486 MO.setImm(Value & 0x000fffffL);
487 Modified = true;
488 }
489 }
490 }
491 }
492 }
493 }
494
495 return Modified;
496}
497
498//*****************************************************************************
499//**** IgnoreZeroFlag pass
500//*****************************************************************************
501// This erratum fix fixes the overflow behavior of SDIVCC and UDIVCC
502// instructions that exists on some earlier LEON processors. Where these
503// instructions are detected, they are replaced by a sequence that will
504// explicitly write the overflow bit flag if this is required.
505//
506char IgnoreZeroFlag::ID = 0;
507
508IgnoreZeroFlag::IgnoreZeroFlag(TargetMachine &tm)
509 : LEONMachineFunctionPass(tm, ID) {}
510
511bool IgnoreZeroFlag::runOnMachineFunction(MachineFunction &MF) {
512 Subtarget = &MF.getSubtarget<SparcSubtarget>();
513 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
514 DebugLoc DL = DebugLoc();
515
516 bool Modified = false;
517 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
518 MachineBasicBlock &MBB = *MFI;
519 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
520 MachineInstr &MI = *MBBI;
521 unsigned Opcode = MI.getOpcode();
522 if (Opcode == SP::SDIVCCrr || Opcode == SP::SDIVCCri ||
523 Opcode == SP::UDIVCCrr || Opcode == SP::UDIVCCri) {
524
525 // split the current machine basic block - just after the sdivcc/udivcc
526 // instruction
527 // create a label that help us skip the zero flag update (of PSR -
528 // Processor Status Register)
529 // if conditions are not met
530 const BasicBlock *LLVM_BB = MBB.getBasicBlock();
531 MachineFunction::iterator It =
532 std::next(MachineFunction::iterator(MBB));
533
534 MachineBasicBlock *dneBB = MF.CreateMachineBasicBlock(LLVM_BB);
535 MF.insert(It, dneBB);
536
537 // Transfer the remainder of MBB and its successor edges to dneBB.
538 dneBB->splice(dneBB->begin(), &MBB,
539 std::next(MachineBasicBlock::iterator(MI)), MBB.end());
540 dneBB->transferSuccessorsAndUpdatePHIs(&MBB);
541
542 MBB.addSuccessor(dneBB);
543
544 MachineBasicBlock::iterator NextMBBI = std::next(MBBI);
545
546 // bvc - branch if overflow flag not set
547 BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND))
548 .addMBB(dneBB)
549 .addImm(SPCC::ICC_VS);
550
551 // bnz - branch if not zero
552 BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND))
553 .addMBB(dneBB)
554 .addImm(SPCC::ICC_NE);
555
556 // use the WRPSR (Write Processor State Register) instruction to set the
557 // zeo flag to 1
558 // create wr %g0, 1, %psr
559 BuildMI(MBB, NextMBBI, DL, TII.get(SP::WRPSRri))
560 .addReg(SP::G0)
561 .addImm(1);
562
563 BuildMI(MBB, NextMBBI, DL, TII.get(SP::NOP));
564
565 Modified = true;
566 } else if (MI.isInlineAsm()) {
567 StringRef AsmString =
568 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName();
569 if (AsmString.startswith_lower("sdivcc") ||
570 AsmString.startswith_lower("udivcc")) {
571 // this is an inline SDIVCC or UDIVCC instruction
572
573 // split the current machine basic block - just after the
574 // sdivcc/udivcc instruction
575 // create a label that help us skip the zero flag update (of PSR -
576 // Processor Status Register)
577 // if conditions are not met
578 const BasicBlock *LLVM_BB = MBB.getBasicBlock();
579 MachineFunction::iterator It =
580 std::next(MachineFunction::iterator(MBB));
581
582 MachineBasicBlock *dneBB = MF.CreateMachineBasicBlock(LLVM_BB);
583 MF.insert(It, dneBB);
584
585 // Transfer the remainder of MBB and its successor edges to dneBB.
586 dneBB->splice(dneBB->begin(), &MBB,
587 std::next(MachineBasicBlock::iterator(MI)), MBB.end());
588 dneBB->transferSuccessorsAndUpdatePHIs(&MBB);
589
590 MBB.addSuccessor(dneBB);
591
592 MachineBasicBlock::iterator NextMBBI = std::next(MBBI);
593
594 // bvc - branch if overflow flag not set
595 BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND))
596 .addMBB(dneBB)
597 .addImm(SPCC::ICC_VS);
598
599 // bnz - branch if not zero
600 BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND))
601 .addMBB(dneBB)
602 .addImm(SPCC::ICC_NE);
603
604 // use the WRPSR (Write Processor State Register) instruction to set
605 // the zeo flag to 1
606 // create wr %g0, 1, %psr
607 BuildMI(MBB, NextMBBI, DL, TII.get(SP::WRPSRri))
608 .addReg(SP::G0)
609 .addImm(1);
610
611 BuildMI(MBB, NextMBBI, DL, TII.get(SP::NOP));
612
613 Modified = true;
614 }
615 }
616 }
617 }
618
619 return Modified;
620}
621
622//*****************************************************************************
623//**** InsertNOPDoublePrecision pass
624//*****************************************************************************
625// This erratum fix for some earlier LEON processors fixes a problem where a
626// double precision load will not yield the correct result if used in FMUL,
627// FDIV, FADD, FSUB or FSQRT instructions later. If this sequence is detected,
628// inserting a NOP between the two instructions will fix the erratum.
629// 1.scans the code after register allocation;
630// 2.checks for the problem conditions as described in the AT697E erratum
631// “Odd-Numbered FPU Register Dependency not Properly Checked in some
632// Double-Precision FPU Operations”;
633// 3.inserts NOPs if the problem exists.
634//
635char InsertNOPDoublePrecision::ID = 0;
636
637InsertNOPDoublePrecision::InsertNOPDoublePrecision(TargetMachine &tm)
638 : LEONMachineFunctionPass(tm, ID) {}
639
640bool InsertNOPDoublePrecision::runOnMachineFunction(MachineFunction &MF) {
641 Subtarget = &MF.getSubtarget<SparcSubtarget>();
642 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
643 DebugLoc DL = DebugLoc();
644
645 bool Modified = false;
646 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
647 MachineBasicBlock &MBB = *MFI;
648 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
649 MachineInstr &MI = *MBBI;
650 unsigned Opcode = MI.getOpcode();
651 if (Opcode == SP::LDDFri || Opcode == SP::LDDFrr) {
652 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
653 MachineInstr &NMI = *NMBBI;
654
655 unsigned NextOpcode = NMI.getOpcode();
656 // NMI.print(errs());
657 if (NextOpcode == SP::FADDD || NextOpcode == SP::FSUBD ||
658 NextOpcode == SP::FMULD || NextOpcode == SP::FDIVD) {
659 int RegAIndex = GetRegIndexForOperand(MI, 0);
660 int RegBIndex = GetRegIndexForOperand(NMI, 0);
661 int RegCIndex =
662 GetRegIndexForOperand(NMI, 2); // Second source operand is index 2
663 int RegDIndex =
664 GetRegIndexForOperand(NMI, 1); // Destination operand is index 1
665
666 if ((RegAIndex == RegBIndex + 1 && RegBIndex == RegDIndex) ||
667 (RegAIndex == RegCIndex + 1 && RegCIndex == RegDIndex) ||
668 (RegAIndex == RegBIndex + 1 && RegCIndex == RegDIndex) ||
669 (RegAIndex == RegCIndex + 1 && RegBIndex == RegDIndex)) {
670 // Insert NOP between the two instructions.
671 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
672 Modified = true;
673 }
674
675 // Check the errata patterns that only happen for FADDD and FMULD
676 if (Modified == false &&
677 (NextOpcode == SP::FADDD || NextOpcode == SP::FMULD)) {
678 RegAIndex = GetRegIndexForOperand(MI, 1);
679 if (RegAIndex == RegBIndex + 1 && RegBIndex == RegCIndex &&
680 RegBIndex == RegDIndex) {
681 // Insert NOP between the two instructions.
682 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
683 Modified = true;
684 }
685 }
686 } else if (NextOpcode == SP::FSQRTD) {
687 int RegAIndex = GetRegIndexForOperand(MI, 1);
688 int RegBIndex = GetRegIndexForOperand(NMI, 0);
689 int RegCIndex = GetRegIndexForOperand(NMI, 1);
690
691 if (RegAIndex == RegBIndex + 1 && RegBIndex == RegCIndex) {
692 // Insert NOP between the two instructions.
693 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
694 Modified = true;
695 }
696 }
697 }
698 }
699 }
700
701 return Modified;
702}
703
704//*****************************************************************************
705//**** PreventRoundChange pass
706//*****************************************************************************
707// To prevent any explicit change of the default rounding mode, this pass
708// detects any call of the fesetround function and removes this call from the
709// list of generated operations.
710//
711char PreventRoundChange::ID = 0;
712
713PreventRoundChange::PreventRoundChange(TargetMachine &tm)
714 : LEONMachineFunctionPass(tm, ID) {}
715
716bool PreventRoundChange::runOnMachineFunction(MachineFunction &MF) {
717 Subtarget = &MF.getSubtarget<SparcSubtarget>();
718
719 bool Modified = false;
720 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
721 MachineBasicBlock &MBB = *MFI;
722 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
723 MachineInstr &MI = *MBBI;
724 unsigned Opcode = MI.getOpcode();
725 if (Opcode == SP::CALL && MI.getNumOperands() > 0) {
726 MachineOperand &MO = MI.getOperand(0);
727
728 if (MO.isGlobal()) {
729 StringRef FuncName = MO.getGlobal()->getName();
730 if (FuncName.compare_lower("fesetround") == 0) {
731 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
732 MI.eraseFromParent();
733 MBBI = NMBBI;
734 Modified = true;
735 }
736 }
737 }
738 }
739 }
740
741 return Modified;
742}
743//*****************************************************************************
744//**** FlushCacheLineSWAP pass
745//*****************************************************************************
746// This pass inserts FLUSHW just before any SWAP atomic instruction.
747//
748char FlushCacheLineSWAP::ID = 0;
749
750FlushCacheLineSWAP::FlushCacheLineSWAP(TargetMachine &tm)
751 : LEONMachineFunctionPass(tm, ID) {}
752
753bool FlushCacheLineSWAP::runOnMachineFunction(MachineFunction &MF) {
754 Subtarget = &MF.getSubtarget<SparcSubtarget>();
755 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
756 DebugLoc DL = DebugLoc();
757
758 bool Modified = false;
759 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
760 MachineBasicBlock &MBB = *MFI;
761 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
762 MachineInstr &MI = *MBBI;
763 unsigned Opcode = MI.getOpcode();
764 if (Opcode == SP::SWAPrr || Opcode == SP::SWAPri ||
765 Opcode == SP::LDSTUBrr || Opcode == SP::LDSTUBri) {
766 // insert flush and 5 NOPs before the swap/ldstub instruction
767 BuildMI(MBB, MBBI, DL, TII.get(SP::FLUSH));
768 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
769 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
770 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
771 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
772 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
773
774 Modified = true;
775 } else if (MI.isInlineAsm()) {
776 StringRef AsmString =
777 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName();
778 if (AsmString.startswith_lower("swap") ||
779 AsmString.startswith_lower("ldstub")) {
780 // this is an inline swap or ldstub instruction
781
782 // insert flush and 5 NOPs before the swap/ldstub instruction
783 BuildMI(MBB, MBBI, DL, TII.get(SP::FLUSH));
784 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
785 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
786 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
787 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
788 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
789
790 Modified = true;
791 }
792 }
793 }
794 }
795
796 return Modified;
797}
798
799//*****************************************************************************
800//**** InsertNOPsLoadStore pass
801//*****************************************************************************
802// This pass shall insert NOPs between floating point loads and stores when the
803// following circumstances are present [5]:
804// Pattern 1:
805// 1. single-precision load or single-precision FPOP to register %fX, where X is
806// the same register as the store being checked;
807// 2. single-precision load or single-precision FPOP to register %fY , where Y
808// is the opposite register in the same double-precision pair;
809// 3. 0-3 instructions of any kind, except stores from %fX or %fY or operations
810// with %fX as destination;
811// 4. the store (from register %fX) being considered.
812// Pattern 2:
813// 1. double-precision FPOP;
814// 2. any number of operations on any kind, except no double-precision FPOP and
815// at most one (less than two) single-precision or single-to-double FPOPs;
816// 3. the store (from register %fX) being considered.
817//
818char InsertNOPsLoadStore::ID = 0;
819
820InsertNOPsLoadStore::InsertNOPsLoadStore(TargetMachine &tm)
821 : LEONMachineFunctionPass(tm, ID) {}
822
823bool InsertNOPsLoadStore::runOnMachineFunction(MachineFunction &MF) {
824 Subtarget = &MF.getSubtarget<SparcSubtarget>();
825 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
826 DebugLoc DL = DebugLoc();
827
828 MachineInstr *Pattern1FirstInstruction = NULL;
829 MachineInstr *Pattern2FirstInstruction = NULL;
830 unsigned int StoreInstructionsToCheck = 0;
831 int FxRegIndex, FyRegIndex;
832
833 bool Modified = false;
834 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
835 MachineBasicBlock &MBB = *MFI;
836 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
837 MachineInstr &MI = *MBBI;
838
839 if (StoreInstructionsToCheck > 0) {
840 if (((MI.getOpcode() == SP::STFrr || MI.getOpcode() == SP::STFri) &&
841 (GetRegIndexForOperand(MI, LAST_OPERAND) == FxRegIndex ||
842 GetRegIndexForOperand(MI, LAST_OPERAND) == FyRegIndex)) ||
843 GetRegIndexForOperand(MI, 0) == FxRegIndex) {
844 // Insert four NOPs
845 for (unsigned InsertedCount = 0; InsertedCount < 4; InsertedCount++) {
846 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
847 }
848 Modified = true;
849 }
850 StoreInstructionsToCheck--;
851 }
852
853 switch (MI.getOpcode()) {
854 // Watch for Pattern 1 FPop instructions
855 case SP::LDrr:
856 case SP::LDri:
857 case SP::LDFrr:
858 case SP::LDFri:
859 case SP::FADDS:
860 case SP::FSUBS:
861 case SP::FMULS:
862 case SP::FDIVS:
863 case SP::FSQRTS:
864 case SP::FCMPS:
865 case SP::FMOVS:
866 case SP::FNEGS:
867 case SP::FABSS:
868 case SP::FITOS:
869 case SP::FSTOI:
870 case SP::FITOD:
871 case SP::FDTOI:
872 case SP::FDTOS:
873 if (Pattern1FirstInstruction != NULL) {
874 FxRegIndex = GetRegIndexForOperand(*Pattern1FirstInstruction, 0);
875 FyRegIndex = GetRegIndexForOperand(MI, 0);
876
877 // Check to see if these registers are part of the same double
878 // precision
879 // register pair.
880 int DoublePrecRegIndexForX = (FxRegIndex - SP::F0) / 2;
881 int DoublePrecRegIndexForY = (FyRegIndex - SP::F0) / 2;
882
883 if (DoublePrecRegIndexForX == DoublePrecRegIndexForY)
884 StoreInstructionsToCheck = 4;
885 }
886
887 Pattern1FirstInstruction = &MI;
888 break;
889 // End of Pattern 1
890
891 // Search for Pattern 2
892 case SP::FADDD:
893 case SP::FSUBD:
894 case SP::FMULD:
895 case SP::FDIVD:
896 case SP::FSQRTD:
897 case SP::FCMPD:
898 Pattern2FirstInstruction = &MI;
899 Pattern1FirstInstruction = NULL;
900 break;
901
902 case SP::STFrr:
903 case SP::STFri:
904 case SP::STDFrr:
905 case SP::STDFri:
906 if (Pattern2FirstInstruction != NULL) {
907 if (GetRegIndexForOperand(MI, LAST_OPERAND) ==
908 GetRegIndexForOperand(*Pattern2FirstInstruction, 0)) {
909 // Insert four NOPs
910 for (unsigned InsertedCount = 0; InsertedCount < 4;
911 InsertedCount++) {
912 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
913 }
914
915 Pattern2FirstInstruction = NULL;
916 }
917 }
918 Pattern1FirstInstruction = NULL;
919 break;
920 // End of Pattern 2
921
922 default:
923 // Ensure we don't count debug-only values while we're testing for the
924 // patterns.
925 if (!MI.isDebugValue())
926 Pattern1FirstInstruction = NULL;
927 break;
928 }
929 }
930 }
931
932 return Modified;
933}