1 //===-- MipsExpandPseudoInsts.cpp - Expand pseudo instructions ------------===//
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 // This file contains a pass that expands pseudo instructions into target
11 // instructions to allow proper scheduling, if-conversion, and other late
12 // optimizations. This pass should be run after register allocation but before
13 // the post-regalloc scheduling pass.
14 //
15 // This is currently only used for expanding atomic pseudos after register
16 // allocation. We do this to avoid the fast register allocator introducing
17 // spills between ll and sc. These stores cause some MIPS implementations to
18 // abort the atomic RMW sequence.
19 //
20 //===----------------------------------------------------------------------===//
21
22 #include "Mips.h"
23 #include "MipsInstrInfo.h"
24 #include "MipsSubtarget.h"
25 #include "llvm/CodeGen/LivePhysRegs.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/MachineInstrBuilder.h"
28
29 using namespace llvm;
30
31 #define DEBUG_TYPE "mips-pseudo"
32
33 namespace {
34 class MipsExpandPseudo : public MachineFunctionPass {
35 public:
36 static char ID;
MipsExpandPseudo()37 MipsExpandPseudo() : MachineFunctionPass(ID) {}
38
39 const MipsInstrInfo *TII;
40 const MipsSubtarget *STI;
41
42 bool runOnMachineFunction(MachineFunction &Fn) override;
43
getRequiredProperties() const44 MachineFunctionProperties getRequiredProperties() const override {
45 return MachineFunctionProperties().set(
46 MachineFunctionProperties::Property::NoVRegs);
47 }
48
getPassName() const49 StringRef getPassName() const override {
50 return "Mips pseudo instruction expansion pass";
51 }
52
53 private:
54 bool expandAtomicCmpSwap(MachineBasicBlock &MBB,
55 MachineBasicBlock::iterator MBBI,
56 MachineBasicBlock::iterator &NextMBBI);
57 bool expandAtomicCmpSwapSubword(MachineBasicBlock &MBB,
58 MachineBasicBlock::iterator MBBI,
59 MachineBasicBlock::iterator &NextMBBI);
60
61 bool expandAtomicBinOp(MachineBasicBlock &BB,
62 MachineBasicBlock::iterator I,
63 MachineBasicBlock::iterator &NMBBI, unsigned Size);
64 bool expandAtomicBinOpSubword(MachineBasicBlock &BB,
65 MachineBasicBlock::iterator I,
66 MachineBasicBlock::iterator &NMBBI);
67
68 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
69 MachineBasicBlock::iterator &NMBB);
70 bool expandMBB(MachineBasicBlock &MBB);
71 };
72 char MipsExpandPseudo::ID = 0;
73 }
74
expandAtomicCmpSwapSubword(MachineBasicBlock & BB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & NMBBI)75 bool MipsExpandPseudo::expandAtomicCmpSwapSubword(
76 MachineBasicBlock &BB, MachineBasicBlock::iterator I,
77 MachineBasicBlock::iterator &NMBBI) {
78
79 MachineFunction *MF = BB.getParent();
80
81 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
82 DebugLoc DL = I->getDebugLoc();
83 unsigned LL, SC;
84
85 unsigned ZERO = Mips::ZERO;
86 unsigned BNE = Mips::BNE;
87 unsigned BEQ = Mips::BEQ;
88 unsigned SEOp =
89 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I8_POSTRA ? Mips::SEB : Mips::SEH;
90
91 if (STI->inMicroMipsMode()) {
92 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
93 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
94 BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
95 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
96 } else {
97 LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
98 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
99 SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
100 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
101 }
102
103 unsigned Dest = I->getOperand(0).getReg();
104 unsigned Ptr = I->getOperand(1).getReg();
105 unsigned Mask = I->getOperand(2).getReg();
106 unsigned ShiftCmpVal = I->getOperand(3).getReg();
107 unsigned Mask2 = I->getOperand(4).getReg();
108 unsigned ShiftNewVal = I->getOperand(5).getReg();
109 unsigned ShiftAmnt = I->getOperand(6).getReg();
110 unsigned Scratch = I->getOperand(7).getReg();
111 unsigned Scratch2 = I->getOperand(8).getReg();
112
113 // insert new blocks after the current block
114 const BasicBlock *LLVM_BB = BB.getBasicBlock();
115 MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
116 MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
117 MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
118 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
119 MachineFunction::iterator It = ++BB.getIterator();
120 MF->insert(It, loop1MBB);
121 MF->insert(It, loop2MBB);
122 MF->insert(It, sinkMBB);
123 MF->insert(It, exitMBB);
124
125 // Transfer the remainder of BB and its successor edges to exitMBB.
126 exitMBB->splice(exitMBB->begin(), &BB,
127 std::next(MachineBasicBlock::iterator(I)), BB.end());
128 exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
129
130 // thisMBB:
131 // ...
132 // fallthrough --> loop1MBB
133 BB.addSuccessor(loop1MBB, BranchProbability::getOne());
134 loop1MBB->addSuccessor(sinkMBB);
135 loop1MBB->addSuccessor(loop2MBB);
136 loop1MBB->normalizeSuccProbs();
137 loop2MBB->addSuccessor(loop1MBB);
138 loop2MBB->addSuccessor(sinkMBB);
139 loop2MBB->normalizeSuccProbs();
140 sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
141
142 // loop1MBB:
143 // ll dest, 0(ptr)
144 // and Mask', dest, Mask
145 // bne Mask', ShiftCmpVal, exitMBB
146 BuildMI(loop1MBB, DL, TII->get(LL), Scratch).addReg(Ptr).addImm(0);
147 BuildMI(loop1MBB, DL, TII->get(Mips::AND), Scratch2)
148 .addReg(Scratch)
149 .addReg(Mask);
150 BuildMI(loop1MBB, DL, TII->get(BNE))
151 .addReg(Scratch2).addReg(ShiftCmpVal).addMBB(sinkMBB);
152
153 // loop2MBB:
154 // and dest, dest, mask2
155 // or dest, dest, ShiftNewVal
156 // sc dest, dest, 0(ptr)
157 // beq dest, $0, loop1MBB
158 BuildMI(loop2MBB, DL, TII->get(Mips::AND), Scratch)
159 .addReg(Scratch, RegState::Kill)
160 .addReg(Mask2);
161 BuildMI(loop2MBB, DL, TII->get(Mips::OR), Scratch)
162 .addReg(Scratch, RegState::Kill)
163 .addReg(ShiftNewVal);
164 BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
165 .addReg(Scratch, RegState::Kill)
166 .addReg(Ptr)
167 .addImm(0);
168 BuildMI(loop2MBB, DL, TII->get(BEQ))
169 .addReg(Scratch, RegState::Kill)
170 .addReg(ZERO)
171 .addMBB(loop1MBB);
172
173 // sinkMBB:
174 // srl srlres, Mask', shiftamt
175 // sign_extend dest,srlres
176 BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
177 .addReg(Scratch2)
178 .addReg(ShiftAmnt);
179 if (STI->hasMips32r2()) {
180 BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
181 } else {
182 const unsigned ShiftImm =
183 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I16_POSTRA ? 16 : 24;
184 BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
185 .addReg(Dest, RegState::Kill)
186 .addImm(ShiftImm);
187 BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
188 .addReg(Dest, RegState::Kill)
189 .addImm(ShiftImm);
190 }
191
192 LivePhysRegs LiveRegs;
193 computeAndAddLiveIns(LiveRegs, *loop1MBB);
194 computeAndAddLiveIns(LiveRegs, *loop2MBB);
195 computeAndAddLiveIns(LiveRegs, *sinkMBB);
196 computeAndAddLiveIns(LiveRegs, *exitMBB);
197
198 NMBBI = BB.end();
199 I->eraseFromParent();
200 return true;
201 }
202
expandAtomicCmpSwap(MachineBasicBlock & BB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & NMBBI)203 bool MipsExpandPseudo::expandAtomicCmpSwap(MachineBasicBlock &BB,
204 MachineBasicBlock::iterator I,
205 MachineBasicBlock::iterator &NMBBI) {
206
207 const unsigned Size =
208 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8;
209 MachineFunction *MF = BB.getParent();
210
211 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
212 DebugLoc DL = I->getDebugLoc();
213
214 unsigned LL, SC, ZERO, BNE, BEQ, MOVE;
215
216 if (Size == 4) {
217 if (STI->inMicroMipsMode()) {
218 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
219 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
220 BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
221 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
222 } else {
223 LL = STI->hasMips32r6()
224 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
225 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
226 SC = STI->hasMips32r6()
227 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
228 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
229 BNE = Mips::BNE;
230 BEQ = Mips::BEQ;
231 }
232
233 ZERO = Mips::ZERO;
234 MOVE = Mips::OR;
235 } else {
236 LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
237 SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
238 ZERO = Mips::ZERO_64;
239 BNE = Mips::BNE64;
240 BEQ = Mips::BEQ64;
241 MOVE = Mips::OR64;
242 }
243
244 unsigned Dest = I->getOperand(0).getReg();
245 unsigned Ptr = I->getOperand(1).getReg();
246 unsigned OldVal = I->getOperand(2).getReg();
247 unsigned NewVal = I->getOperand(3).getReg();
248 unsigned Scratch = I->getOperand(4).getReg();
249
250 // insert new blocks after the current block
251 const BasicBlock *LLVM_BB = BB.getBasicBlock();
252 MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
253 MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
254 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
255 MachineFunction::iterator It = ++BB.getIterator();
256 MF->insert(It, loop1MBB);
257 MF->insert(It, loop2MBB);
258 MF->insert(It, exitMBB);
259
260 // Transfer the remainder of BB and its successor edges to exitMBB.
261 exitMBB->splice(exitMBB->begin(), &BB,
262 std::next(MachineBasicBlock::iterator(I)), BB.end());
263 exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
264
265 // thisMBB:
266 // ...
267 // fallthrough --> loop1MBB
268 BB.addSuccessor(loop1MBB, BranchProbability::getOne());
269 loop1MBB->addSuccessor(exitMBB);
270 loop1MBB->addSuccessor(loop2MBB);
271 loop1MBB->normalizeSuccProbs();
272 loop2MBB->addSuccessor(loop1MBB);
273 loop2MBB->addSuccessor(exitMBB);
274 loop2MBB->normalizeSuccProbs();
275
276 // loop1MBB:
277 // ll dest, 0(ptr)
278 // bne dest, oldval, exitMBB
279 BuildMI(loop1MBB, DL, TII->get(LL), Dest).addReg(Ptr).addImm(0);
280 BuildMI(loop1MBB, DL, TII->get(BNE))
281 .addReg(Dest, RegState::Kill).addReg(OldVal).addMBB(exitMBB);
282
283 // loop2MBB:
284 // move scratch, NewVal
285 // sc Scratch, Scratch, 0(ptr)
286 // beq Scratch, $0, loop1MBB
287 BuildMI(loop2MBB, DL, TII->get(MOVE), Scratch).addReg(NewVal).addReg(ZERO);
288 BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
289 .addReg(Scratch).addReg(Ptr).addImm(0);
290 BuildMI(loop2MBB, DL, TII->get(BEQ))
291 .addReg(Scratch, RegState::Kill).addReg(ZERO).addMBB(loop1MBB);
292
293 LivePhysRegs LiveRegs;
294 computeAndAddLiveIns(LiveRegs, *loop1MBB);
295 computeAndAddLiveIns(LiveRegs, *loop2MBB);
296 computeAndAddLiveIns(LiveRegs, *exitMBB);
297
298 NMBBI = BB.end();
299 I->eraseFromParent();
300 return true;
301 }
302
expandAtomicBinOpSubword(MachineBasicBlock & BB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & NMBBI)303 bool MipsExpandPseudo::expandAtomicBinOpSubword(
304 MachineBasicBlock &BB, MachineBasicBlock::iterator I,
305 MachineBasicBlock::iterator &NMBBI) {
306
307 MachineFunction *MF = BB.getParent();
308
309 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
310 DebugLoc DL = I->getDebugLoc();
311
312 unsigned LL, SC;
313 unsigned BEQ = Mips::BEQ;
314 unsigned SEOp = Mips::SEH;
315
316 if (STI->inMicroMipsMode()) {
317 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
318 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
319 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
320 } else {
321 LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
322 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
323 SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
324 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
325 }
326
327 bool IsSwap = false;
328 bool IsNand = false;
329
330 unsigned Opcode = 0;
331 switch (I->getOpcode()) {
332 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
333 SEOp = Mips::SEB;
334 LLVM_FALLTHROUGH;
335 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
336 IsNand = true;
337 break;
338 case Mips::ATOMIC_SWAP_I8_POSTRA:
339 SEOp = Mips::SEB;
340 LLVM_FALLTHROUGH;
341 case Mips::ATOMIC_SWAP_I16_POSTRA:
342 IsSwap = true;
343 break;
344 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
345 SEOp = Mips::SEB;
346 LLVM_FALLTHROUGH;
347 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
348 Opcode = Mips::ADDu;
349 break;
350 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
351 SEOp = Mips::SEB;
352 LLVM_FALLTHROUGH;
353 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
354 Opcode = Mips::SUBu;
355 break;
356 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
357 SEOp = Mips::SEB;
358 LLVM_FALLTHROUGH;
359 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
360 Opcode = Mips::AND;
361 break;
362 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
363 SEOp = Mips::SEB;
364 LLVM_FALLTHROUGH;
365 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
366 Opcode = Mips::OR;
367 break;
368 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
369 SEOp = Mips::SEB;
370 LLVM_FALLTHROUGH;
371 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
372 Opcode = Mips::XOR;
373 break;
374 default:
375 llvm_unreachable("Unknown subword atomic pseudo for expansion!");
376 }
377
378 unsigned Dest = I->getOperand(0).getReg();
379 unsigned Ptr = I->getOperand(1).getReg();
380 unsigned Incr = I->getOperand(2).getReg();
381 unsigned Mask = I->getOperand(3).getReg();
382 unsigned Mask2 = I->getOperand(4).getReg();
383 unsigned ShiftAmnt = I->getOperand(5).getReg();
384 unsigned OldVal = I->getOperand(6).getReg();
385 unsigned BinOpRes = I->getOperand(7).getReg();
386 unsigned StoreVal = I->getOperand(8).getReg();
387
388 const BasicBlock *LLVM_BB = BB.getBasicBlock();
389 MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
390 MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
391 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
392 MachineFunction::iterator It = ++BB.getIterator();
393 MF->insert(It, loopMBB);
394 MF->insert(It, sinkMBB);
395 MF->insert(It, exitMBB);
396
397 exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());
398 exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
399
400 BB.addSuccessor(loopMBB, BranchProbability::getOne());
401 loopMBB->addSuccessor(sinkMBB);
402 loopMBB->addSuccessor(loopMBB);
403 loopMBB->normalizeSuccProbs();
404
405 BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
406 if (IsNand) {
407 // and andres, oldval, incr2
408 // nor binopres, $0, andres
409 // and newval, binopres, mask
410 BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
411 .addReg(OldVal)
412 .addReg(Incr);
413 BuildMI(loopMBB, DL, TII->get(Mips::NOR), BinOpRes)
414 .addReg(Mips::ZERO)
415 .addReg(BinOpRes);
416 BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
417 .addReg(BinOpRes)
418 .addReg(Mask);
419 } else if (!IsSwap) {
420 // <binop> binopres, oldval, incr2
421 // and newval, binopres, mask
422 BuildMI(loopMBB, DL, TII->get(Opcode), BinOpRes)
423 .addReg(OldVal)
424 .addReg(Incr);
425 BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
426 .addReg(BinOpRes)
427 .addReg(Mask);
428 } else { // atomic.swap
429 // and newval, incr2, mask
430 BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
431 .addReg(Incr)
432 .addReg(Mask);
433 }
434
435 // and StoreVal, OlddVal, Mask2
436 // or StoreVal, StoreVal, BinOpRes
437 // StoreVal<tied1> = sc StoreVal, 0(Ptr)
438 // beq StoreVal, zero, loopMBB
439 BuildMI(loopMBB, DL, TII->get(Mips::AND), StoreVal)
440 .addReg(OldVal).addReg(Mask2);
441 BuildMI(loopMBB, DL, TII->get(Mips::OR), StoreVal)
442 .addReg(StoreVal).addReg(BinOpRes);
443 BuildMI(loopMBB, DL, TII->get(SC), StoreVal)
444 .addReg(StoreVal).addReg(Ptr).addImm(0);
445 BuildMI(loopMBB, DL, TII->get(BEQ))
446 .addReg(StoreVal).addReg(Mips::ZERO).addMBB(loopMBB);
447
448 // sinkMBB:
449 // and maskedoldval1,oldval,mask
450 // srl srlres,maskedoldval1,shiftamt
451 // sign_extend dest,srlres
452
453 sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
454
455 BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest)
456 .addReg(OldVal).addReg(Mask);
457 BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
458 .addReg(Dest).addReg(ShiftAmnt);
459
460 if (STI->hasMips32r2()) {
461 BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
462 } else {
463 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
464 BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
465 .addReg(Dest, RegState::Kill)
466 .addImm(ShiftImm);
467 BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
468 .addReg(Dest, RegState::Kill)
469 .addImm(ShiftImm);
470 }
471
472 LivePhysRegs LiveRegs;
473 computeAndAddLiveIns(LiveRegs, *loopMBB);
474 computeAndAddLiveIns(LiveRegs, *sinkMBB);
475 computeAndAddLiveIns(LiveRegs, *exitMBB);
476
477 NMBBI = BB.end();
478 I->eraseFromParent();
479
480 return true;
481 }
482
expandAtomicBinOp(MachineBasicBlock & BB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & NMBBI,unsigned Size)483 bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
484 MachineBasicBlock::iterator I,
485 MachineBasicBlock::iterator &NMBBI,
486 unsigned Size) {
487 MachineFunction *MF = BB.getParent();
488
489 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
490 DebugLoc DL = I->getDebugLoc();
491
492 unsigned LL, SC, ZERO, BEQ;
493
494 if (Size == 4) {
495 if (STI->inMicroMipsMode()) {
496 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
497 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
498 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
499 } else {
500 LL = STI->hasMips32r6()
501 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
502 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
503 SC = STI->hasMips32r6()
504 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
505 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
506 BEQ = Mips::BEQ;
507 }
508
509 ZERO = Mips::ZERO;
510 } else {
511 LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
512 SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
513 ZERO = Mips::ZERO_64;
514 BEQ = Mips::BEQ64;
515 }
516
517 unsigned OldVal = I->getOperand(0).getReg();
518 unsigned Ptr = I->getOperand(1).getReg();
519 unsigned Incr = I->getOperand(2).getReg();
520 unsigned Scratch = I->getOperand(3).getReg();
521
522 unsigned Opcode = 0;
523 unsigned OR = 0;
524 unsigned AND = 0;
525 unsigned NOR = 0;
526 bool IsNand = false;
527 switch (I->getOpcode()) {
528 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
529 Opcode = Mips::ADDu;
530 break;
531 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
532 Opcode = Mips::SUBu;
533 break;
534 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
535 Opcode = Mips::AND;
536 break;
537 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
538 Opcode = Mips::OR;
539 break;
540 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
541 Opcode = Mips::XOR;
542 break;
543 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
544 IsNand = true;
545 AND = Mips::AND;
546 NOR = Mips::NOR;
547 break;
548 case Mips::ATOMIC_SWAP_I32_POSTRA:
549 OR = Mips::OR;
550 break;
551 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
552 Opcode = Mips::DADDu;
553 break;
554 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
555 Opcode = Mips::DSUBu;
556 break;
557 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
558 Opcode = Mips::AND64;
559 break;
560 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
561 Opcode = Mips::OR64;
562 break;
563 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
564 Opcode = Mips::XOR64;
565 break;
566 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
567 IsNand = true;
568 AND = Mips::AND64;
569 NOR = Mips::NOR64;
570 break;
571 case Mips::ATOMIC_SWAP_I64_POSTRA:
572 OR = Mips::OR64;
573 break;
574 default:
575 llvm_unreachable("Unknown pseudo atomic!");
576 }
577
578 const BasicBlock *LLVM_BB = BB.getBasicBlock();
579 MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
580 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
581 MachineFunction::iterator It = ++BB.getIterator();
582 MF->insert(It, loopMBB);
583 MF->insert(It, exitMBB);
584
585 exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());
586 exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
587
588 BB.addSuccessor(loopMBB, BranchProbability::getOne());
589 loopMBB->addSuccessor(exitMBB);
590 loopMBB->addSuccessor(loopMBB);
591 loopMBB->normalizeSuccProbs();
592
593 BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
594 assert((OldVal != Ptr) && "Clobbered the wrong ptr reg!");
595 assert((OldVal != Incr) && "Clobbered the wrong reg!");
596 if (Opcode) {
597 BuildMI(loopMBB, DL, TII->get(Opcode), Scratch).addReg(OldVal).addReg(Incr);
598 } else if (IsNand) {
599 assert(AND && NOR &&
600 "Unknown nand instruction for atomic pseudo expansion");
601 BuildMI(loopMBB, DL, TII->get(AND), Scratch).addReg(OldVal).addReg(Incr);
602 BuildMI(loopMBB, DL, TII->get(NOR), Scratch).addReg(ZERO).addReg(Scratch);
603 } else {
604 assert(OR && "Unknown instruction for atomic pseudo expansion!");
605 BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);
606 }
607
608 BuildMI(loopMBB, DL, TII->get(SC), Scratch).addReg(Scratch).addReg(Ptr).addImm(0);
609 BuildMI(loopMBB, DL, TII->get(BEQ)).addReg(Scratch).addReg(ZERO).addMBB(loopMBB);
610
611 NMBBI = BB.end();
612 I->eraseFromParent();
613
614 LivePhysRegs LiveRegs;
615 computeAndAddLiveIns(LiveRegs, *loopMBB);
616 computeAndAddLiveIns(LiveRegs, *exitMBB);
617
618 return true;
619 }
620
expandMI(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NMBB)621 bool MipsExpandPseudo::expandMI(MachineBasicBlock &MBB,
622 MachineBasicBlock::iterator MBBI,
623 MachineBasicBlock::iterator &NMBB) {
624
625 bool Modified = false;
626
627 switch (MBBI->getOpcode()) {
628 case Mips::ATOMIC_CMP_SWAP_I32_POSTRA:
629 case Mips::ATOMIC_CMP_SWAP_I64_POSTRA:
630 return expandAtomicCmpSwap(MBB, MBBI, NMBB);
631 case Mips::ATOMIC_CMP_SWAP_I8_POSTRA:
632 case Mips::ATOMIC_CMP_SWAP_I16_POSTRA:
633 return expandAtomicCmpSwapSubword(MBB, MBBI, NMBB);
634 case Mips::ATOMIC_SWAP_I8_POSTRA:
635 case Mips::ATOMIC_SWAP_I16_POSTRA:
636 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
637 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
638 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
639 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
640 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
641 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
642 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
643 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
644 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
645 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
646 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
647 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
648 return expandAtomicBinOpSubword(MBB, MBBI, NMBB);
649 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
650 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
651 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
652 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
653 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
654 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
655 case Mips::ATOMIC_SWAP_I32_POSTRA:
656 return expandAtomicBinOp(MBB, MBBI, NMBB, 4);
657 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
658 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
659 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
660 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
661 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
662 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
663 case Mips::ATOMIC_SWAP_I64_POSTRA:
664 return expandAtomicBinOp(MBB, MBBI, NMBB, 8);
665 default:
666 return Modified;
667 }
668 }
669
expandMBB(MachineBasicBlock & MBB)670 bool MipsExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
671 bool Modified = false;
672
673 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
674 while (MBBI != E) {
675 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
676 Modified |= expandMI(MBB, MBBI, NMBBI);
677 MBBI = NMBBI;
678 }
679
680 return Modified;
681 }
682
runOnMachineFunction(MachineFunction & MF)683 bool MipsExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
684 STI = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
685 TII = STI->getInstrInfo();
686
687 bool Modified = false;
688 for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
689 ++MFI)
690 Modified |= expandMBB(*MFI);
691
692 if (Modified)
693 MF.RenumberBlocks();
694
695 return Modified;
696 }
697
698 /// createMipsExpandPseudoPass - returns an instance of the pseudo instruction
699 /// expansion pass.
createMipsExpandPseudoPass()700 FunctionPass *llvm::createMipsExpandPseudoPass() {
701 return new MipsExpandPseudo();
702 }
703