Deleted Added
full compact
ARMLoadStoreOptimizer.cpp (200581) ARMLoadStoreOptimizer.cpp (201360)
1//===-- ARMLoadStoreOptimizer.cpp - ARM load / store opt. pass ----*- C++ -*-=//
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//===----------------------------------------------------------------------===//

--- 64 unchanged lines hidden (view full) ---

73
74 private:
75 struct MemOpQueueEntry {
76 int Offset;
77 unsigned Position;
78 MachineBasicBlock::iterator MBBI;
79 bool Merged;
80 MemOpQueueEntry(int o, int p, MachineBasicBlock::iterator i)
1//===-- ARMLoadStoreOptimizer.cpp - ARM load / store opt. pass ----*- C++ -*-=//
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//===----------------------------------------------------------------------===//

--- 64 unchanged lines hidden (view full) ---

73
74 private:
75 struct MemOpQueueEntry {
76 int Offset;
77 unsigned Position;
78 MachineBasicBlock::iterator MBBI;
79 bool Merged;
80 MemOpQueueEntry(int o, int p, MachineBasicBlock::iterator i)
81 : Offset(o), Position(p), MBBI(i), Merged(false) {};
81 : Offset(o), Position(p), MBBI(i), Merged(false) {}
82 };
83 typedef SmallVector<MemOpQueueEntry,8> MemOpQueue;
84 typedef MemOpQueue::iterator MemOpQueueIter;
85
86 bool MergeOps(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
87 int Offset, unsigned Base, bool BaseKill, int Opcode,
88 ARMCC::CondCodes Pred, unsigned PredReg, unsigned Scratch,
89 DebugLoc dl, SmallVector<std::pair<unsigned, bool>, 8> &Regs);
82 };
83 typedef SmallVector<MemOpQueueEntry,8> MemOpQueue;
84 typedef MemOpQueue::iterator MemOpQueueIter;
85
86 bool MergeOps(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
87 int Offset, unsigned Base, bool BaseKill, int Opcode,
88 ARMCC::CondCodes Pred, unsigned PredReg, unsigned Scratch,
89 DebugLoc dl, SmallVector<std::pair<unsigned, bool>, 8> &Regs);
90 void MergeOpsUpdate(MachineBasicBlock &MBB,
91 MemOpQueue &MemOps,
92 unsigned memOpsBegin,
93 unsigned memOpsEnd,
94 unsigned insertAfter,
95 int Offset,
96 unsigned Base,
97 bool BaseKill,
98 int Opcode,
99 ARMCC::CondCodes Pred,
100 unsigned PredReg,
101 unsigned Scratch,
102 DebugLoc dl,
103 SmallVector<MachineBasicBlock::iterator, 4> &Merges);
90 void MergeLDR_STR(MachineBasicBlock &MBB, unsigned SIndex, unsigned Base,
91 int Opcode, unsigned Size,
92 ARMCC::CondCodes Pred, unsigned PredReg,
93 unsigned Scratch, MemOpQueue &MemOps,
94 SmallVector<MachineBasicBlock::iterator, 4> &Merges);
95
96 void AdvanceRS(MachineBasicBlock &MBB, MemOpQueue &MemOps);
97 bool FixInvalidRegPairOp(MachineBasicBlock &MBB,

--- 145 unchanged lines hidden (view full) ---

243 MIB.addReg(0); // Add optional writeback (0 for now).
244 for (unsigned i = 0; i != NumRegs; ++i)
245 MIB = MIB.addReg(Regs[i].first, getDefRegState(isDef)
246 | getKillRegState(Regs[i].second));
247
248 return true;
249}
250
104 void MergeLDR_STR(MachineBasicBlock &MBB, unsigned SIndex, unsigned Base,
105 int Opcode, unsigned Size,
106 ARMCC::CondCodes Pred, unsigned PredReg,
107 unsigned Scratch, MemOpQueue &MemOps,
108 SmallVector<MachineBasicBlock::iterator, 4> &Merges);
109
110 void AdvanceRS(MachineBasicBlock &MBB, MemOpQueue &MemOps);
111 bool FixInvalidRegPairOp(MachineBasicBlock &MBB,

--- 145 unchanged lines hidden (view full) ---

257 MIB.addReg(0); // Add optional writeback (0 for now).
258 for (unsigned i = 0; i != NumRegs; ++i)
259 MIB = MIB.addReg(Regs[i].first, getDefRegState(isDef)
260 | getKillRegState(Regs[i].second));
261
262 return true;
263}
264
265// MergeOpsUpdate - call MergeOps and update MemOps and merges accordingly on
266// success.
267void ARMLoadStoreOpt::
268MergeOpsUpdate(MachineBasicBlock &MBB,
269 MemOpQueue &memOps,
270 unsigned memOpsBegin,
271 unsigned memOpsEnd,
272 unsigned insertAfter,
273 int Offset,
274 unsigned Base,
275 bool BaseKill,
276 int Opcode,
277 ARMCC::CondCodes Pred,
278 unsigned PredReg,
279 unsigned Scratch,
280 DebugLoc dl,
281 SmallVector<MachineBasicBlock::iterator, 4> &Merges) {
282 // First calculate which of the registers should be killed by the merged
283 // instruction.
284 SmallVector<std::pair<unsigned, bool>, 8> Regs;
285 const unsigned insertPos = memOps[insertAfter].Position;
286 for (unsigned i = memOpsBegin; i < memOpsEnd; ++i) {
287 const MachineOperand &MO = memOps[i].MBBI->getOperand(0);
288 unsigned Reg = MO.getReg();
289 bool isKill = MO.isKill();
290
291 // If we are inserting the merged operation after an unmerged operation that
292 // uses the same register, make sure to transfer any kill flag.
293 for (unsigned j = memOpsEnd, e = memOps.size(); !isKill && j != e; ++j)
294 if (memOps[j].Position<insertPos) {
295 const MachineOperand &MOJ = memOps[j].MBBI->getOperand(0);
296 if (MOJ.getReg() == Reg && MOJ.isKill())
297 isKill = true;
298 }
299
300 Regs.push_back(std::make_pair(Reg, isKill));
301 }
302
303 // Try to do the merge.
304 MachineBasicBlock::iterator Loc = memOps[insertAfter].MBBI;
305 Loc++;
306 if (!MergeOps(MBB, Loc, Offset, Base, BaseKill, Opcode,
307 Pred, PredReg, Scratch, dl, Regs))
308 return;
309
310 // Merge succeeded, update records.
311 Merges.push_back(prior(Loc));
312 for (unsigned i = memOpsBegin; i < memOpsEnd; ++i) {
313 // Remove kill flags from any unmerged memops that come before insertPos.
314 if (Regs[i-memOpsBegin].second)
315 for (unsigned j = memOpsEnd, e = memOps.size(); j != e; ++j)
316 if (memOps[j].Position<insertPos) {
317 MachineOperand &MOJ = memOps[j].MBBI->getOperand(0);
318 if (MOJ.getReg() == Regs[i-memOpsBegin].first && MOJ.isKill())
319 MOJ.setIsKill(false);
320 }
321 MBB.erase(memOps[i].MBBI);
322 memOps[i].Merged = true;
323 }
324}
325
251/// MergeLDR_STR - Merge a number of load / store instructions into one or more
252/// load / store multiple instructions.
253void
254ARMLoadStoreOpt::MergeLDR_STR(MachineBasicBlock &MBB, unsigned SIndex,
255 unsigned Base, int Opcode, unsigned Size,
256 ARMCC::CondCodes Pred, unsigned PredReg,
257 unsigned Scratch, MemOpQueue &MemOps,
258 SmallVector<MachineBasicBlock::iterator, 4> &Merges) {
259 bool isAM4 = isi32Load(Opcode) || isi32Store(Opcode);
260 int Offset = MemOps[SIndex].Offset;
261 int SOffset = Offset;
326/// MergeLDR_STR - Merge a number of load / store instructions into one or more
327/// load / store multiple instructions.
328void
329ARMLoadStoreOpt::MergeLDR_STR(MachineBasicBlock &MBB, unsigned SIndex,
330 unsigned Base, int Opcode, unsigned Size,
331 ARMCC::CondCodes Pred, unsigned PredReg,
332 unsigned Scratch, MemOpQueue &MemOps,
333 SmallVector<MachineBasicBlock::iterator, 4> &Merges) {
334 bool isAM4 = isi32Load(Opcode) || isi32Store(Opcode);
335 int Offset = MemOps[SIndex].Offset;
336 int SOffset = Offset;
262 unsigned Pos = MemOps[SIndex].Position;
337 unsigned insertAfter = SIndex;
263 MachineBasicBlock::iterator Loc = MemOps[SIndex].MBBI;
264 DebugLoc dl = Loc->getDebugLoc();
338 MachineBasicBlock::iterator Loc = MemOps[SIndex].MBBI;
339 DebugLoc dl = Loc->getDebugLoc();
265 unsigned PReg = Loc->getOperand(0).getReg();
266 unsigned PRegNum = ARMRegisterInfo::getRegisterNumbering(PReg);
267 bool isKill = Loc->getOperand(0).isKill();
340 const MachineOperand &PMO = Loc->getOperand(0);
341 unsigned PReg = PMO.getReg();
342 unsigned PRegNum = PMO.isUndef() ? UINT_MAX
343 : ARMRegisterInfo::getRegisterNumbering(PReg);
268
344
269 SmallVector<std::pair<unsigned,bool>, 8> Regs;
270 Regs.push_back(std::make_pair(PReg, isKill));
271 for (unsigned i = SIndex+1, e = MemOps.size(); i != e; ++i) {
272 int NewOffset = MemOps[i].Offset;
345 for (unsigned i = SIndex+1, e = MemOps.size(); i != e; ++i) {
346 int NewOffset = MemOps[i].Offset;
273 unsigned Reg = MemOps[i].MBBI->getOperand(0).getReg();
274 unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(Reg);
275 isKill = MemOps[i].MBBI->getOperand(0).isKill();
347 const MachineOperand &MO = MemOps[i].MBBI->getOperand(0);
348 unsigned Reg = MO.getReg();
349 unsigned RegNum = MO.isUndef() ? UINT_MAX
350 : ARMRegisterInfo::getRegisterNumbering(Reg);
276 // AM4 - register numbers in ascending order.
277 // AM5 - consecutive register numbers in ascending order.
278 if (NewOffset == Offset + (int)Size &&
279 ((isAM4 && RegNum > PRegNum) || RegNum == PRegNum+1)) {
280 Offset += Size;
351 // AM4 - register numbers in ascending order.
352 // AM5 - consecutive register numbers in ascending order.
353 if (NewOffset == Offset + (int)Size &&
354 ((isAM4 && RegNum > PRegNum) || RegNum == PRegNum+1)) {
355 Offset += Size;
281 Regs.push_back(std::make_pair(Reg, isKill));
282 PRegNum = RegNum;
283 } else {
284 // Can't merge this in. Try merge the earlier ones first.
356 PRegNum = RegNum;
357 } else {
358 // Can't merge this in. Try merge the earlier ones first.
285 if (MergeOps(MBB, ++Loc, SOffset, Base, false, Opcode, Pred, PredReg,
286 Scratch, dl, Regs)) {
287 Merges.push_back(prior(Loc));
288 for (unsigned j = SIndex; j < i; ++j) {
289 MBB.erase(MemOps[j].MBBI);
290 MemOps[j].Merged = true;
291 }
292 }
359 MergeOpsUpdate(MBB, MemOps, SIndex, i, insertAfter, SOffset,
360 Base, false, Opcode, Pred, PredReg, Scratch, dl, Merges);
293 MergeLDR_STR(MBB, i, Base, Opcode, Size, Pred, PredReg, Scratch,
294 MemOps, Merges);
295 return;
296 }
297
361 MergeLDR_STR(MBB, i, Base, Opcode, Size, Pred, PredReg, Scratch,
362 MemOps, Merges);
363 return;
364 }
365
298 if (MemOps[i].Position > Pos) {
299 Pos = MemOps[i].Position;
300 Loc = MemOps[i].MBBI;
301 }
366 if (MemOps[i].Position > MemOps[insertAfter].Position)
367 insertAfter = i;
302 }
303
304 bool BaseKill = Loc->findRegisterUseOperandIdx(Base, true) != -1;
368 }
369
370 bool BaseKill = Loc->findRegisterUseOperandIdx(Base, true) != -1;
305 if (MergeOps(MBB, ++Loc, SOffset, Base, BaseKill, Opcode, Pred, PredReg,
306 Scratch, dl, Regs)) {
307 Merges.push_back(prior(Loc));
308 for (unsigned i = SIndex, e = MemOps.size(); i != e; ++i) {
309 MBB.erase(MemOps[i].MBBI);
310 MemOps[i].Merged = true;
311 }
312 }
313
371 MergeOpsUpdate(MBB, MemOps, SIndex, MemOps.size(), insertAfter, SOffset,
372 Base, BaseKill, Opcode, Pred, PredReg, Scratch, dl, Merges);
314 return;
315}
316
317static inline bool isMatchingDecrement(MachineInstr *MI, unsigned Base,
318 unsigned Bytes, unsigned Limit,
319 ARMCC::CondCodes Pred, unsigned PredReg){
320 unsigned MyPredReg = 0;
321 if (!MI)

--- 1230 unchanged lines hidden ---
373 return;
374}
375
376static inline bool isMatchingDecrement(MachineInstr *MI, unsigned Base,
377 unsigned Bytes, unsigned Limit,
378 ARMCC::CondCodes Pred, unsigned PredReg){
379 unsigned MyPredReg = 0;
380 if (!MI)

--- 1230 unchanged lines hidden ---