LLVM 24.0.0git
MipsExpandPseudo.cpp
Go to the documentation of this file.
1//===-- MipsExpandPseudoInsts.cpp - Expand pseudo instructions ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a pass that expands pseudo instructions into target
10// instructions to allow proper scheduling, if-conversion, and other late
11// optimizations. This pass should be run after register allocation but before
12// the post-regalloc scheduling pass.
13//
14// This is currently only used for expanding atomic pseudos after register
15// allocation. We do this to avoid the fast register allocator introducing
16// spills between ll and sc. These stores cause some MIPS implementations to
17// abort the atomic RMW sequence.
18//
19//===----------------------------------------------------------------------===//
20
21#include "Mips.h"
22#include "MipsInstrInfo.h"
23#include "MipsSubtarget.h"
29#include "llvm/IR/Analysis.h"
30
31using namespace llvm;
32
33#define DEBUG_TYPE "mips-expand-pseudo"
34
35namespace {
36class MipsExpandPseudoLegacy : public MachineFunctionPass {
37public:
38 static char ID;
39 MipsExpandPseudoLegacy() : MachineFunctionPass(ID) {}
40
41 bool runOnMachineFunction(MachineFunction &Fn) override;
42
43 MachineFunctionProperties getRequiredProperties() const override {
44 return MachineFunctionProperties().setNoVRegs();
45 }
46
47 StringRef getPassName() const override {
48 return "Mips pseudo instruction expansion pass";
49 }
50};
51char MipsExpandPseudoLegacy::ID = 0;
52} // namespace
53
57 const MipsSubtarget *STI,
58 const MipsInstrInfo *TII) {
59
60 MachineFunction *MF = BB.getParent();
61
62 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
63 DebugLoc DL = I->getDebugLoc();
64 unsigned LL, SC;
65
66 unsigned ZERO = Mips::R0;
67 unsigned BNE = Mips::BNE;
68 unsigned BEQ = Mips::BEQ;
69 unsigned SEOp =
70 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I8_POSTRA ? Mips::SEB : Mips::SEH;
71
72 if (STI->inMicroMipsMode()) {
73 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
74 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
75 BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
76 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
77 } else {
78 LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
79 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
80 SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
81 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
82 }
83
84 Register Dest = I->getOperand(0).getReg();
85 Register Ptr = I->getOperand(1).getReg();
86 Register Mask = I->getOperand(2).getReg();
87 Register ShiftCmpVal = I->getOperand(3).getReg();
88 Register Mask2 = I->getOperand(4).getReg();
89 Register ShiftNewVal = I->getOperand(5).getReg();
90 Register ShiftAmnt = I->getOperand(6).getReg();
91 Register Scratch = I->getOperand(7).getReg();
92 Register Scratch2 = I->getOperand(8).getReg();
93
94 // insert new blocks after the current block
95 const BasicBlock *LLVM_BB = BB.getBasicBlock();
96 MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
97 MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
98 MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
99 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
101 MF->insert(It, loop1MBB);
102 MF->insert(It, loop2MBB);
103 MF->insert(It, sinkMBB);
104 MF->insert(It, exitMBB);
105
106 // Transfer the remainder of BB and its successor edges to exitMBB.
107 exitMBB->splice(exitMBB->begin(), &BB,
108 std::next(MachineBasicBlock::iterator(I)), BB.end());
110
111 // thisMBB:
112 // ...
113 // fallthrough --> loop1MBB
115 loop1MBB->addSuccessor(sinkMBB);
116 loop1MBB->addSuccessor(loop2MBB);
117 loop1MBB->normalizeSuccProbs();
118 loop2MBB->addSuccessor(loop1MBB);
119 loop2MBB->addSuccessor(sinkMBB);
120 loop2MBB->normalizeSuccProbs();
121 sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
122
123 // loop1MBB:
124 // ll dest, 0(ptr)
125 // and Mask', dest, Mask
126 // bne Mask', ShiftCmpVal, exitMBB
127 BuildMI(loop1MBB, DL, TII->get(LL), Scratch).addReg(Ptr).addImm(0);
128 BuildMI(loop1MBB, DL, TII->get(Mips::AND), Scratch2)
129 .addReg(Scratch)
130 .addReg(Mask);
131 BuildMI(loop1MBB, DL, TII->get(BNE))
132 .addReg(Scratch2).addReg(ShiftCmpVal).addMBB(sinkMBB);
133
134 // loop2MBB:
135 // and dest, dest, mask2
136 // or dest, dest, ShiftNewVal
137 // sc dest, dest, 0(ptr)
138 // beq dest, $0, loop1MBB
139 BuildMI(loop2MBB, DL, TII->get(Mips::AND), Scratch)
140 .addReg(Scratch, RegState::Kill)
141 .addReg(Mask2);
142 BuildMI(loop2MBB, DL, TII->get(Mips::OR), Scratch)
143 .addReg(Scratch, RegState::Kill)
144 .addReg(ShiftNewVal);
145 BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
146 .addReg(Scratch, RegState::Kill)
147 .addReg(Ptr)
148 .addImm(0);
149 BuildMI(loop2MBB, DL, TII->get(BEQ))
150 .addReg(Scratch, RegState::Kill)
151 .addReg(ZERO)
152 .addMBB(loop1MBB);
153
154 // sinkMBB:
155 // srl srlres, Mask', shiftamt
156 // sign_extend dest,srlres
157 BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
158 .addReg(Scratch2)
159 .addReg(ShiftAmnt);
160 if (STI->hasMips32r2()) {
161 BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
162 } else {
163 const unsigned ShiftImm =
164 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I16_POSTRA ? 16 : 24;
165 BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
166 .addReg(Dest, RegState::Kill)
167 .addImm(ShiftImm);
168 BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
169 .addReg(Dest, RegState::Kill)
170 .addImm(ShiftImm);
171 }
172
174 computeAndAddLiveIns(LiveRegs, *loop1MBB);
175 computeAndAddLiveIns(LiveRegs, *loop2MBB);
178
179 NMBBI = BB.end();
180 I->eraseFromParent();
181 return true;
182}
183
187 const MipsSubtarget *STI,
188 const MipsInstrInfo *TII) {
189
190 const unsigned Size =
191 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8;
192 MachineFunction *MF = BB.getParent();
193
194 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
195 DebugLoc DL = I->getDebugLoc();
196
197 unsigned LL, SC, ZERO, BNE, BEQ, MOVE;
198
199 if (Size == 4) {
200 if (STI->inMicroMipsMode()) {
201 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
202 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
203 BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
204 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
205 } else {
206 LL = STI->hasMips32r6()
207 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
208 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
209 SC = STI->hasMips32r6()
210 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
211 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
212 BNE = Mips::BNE;
213 BEQ = Mips::BEQ;
214 }
215
216 ZERO = Mips::R0;
217 MOVE = Mips::OR;
218 } else {
219 LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
220 SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
221 ZERO = Mips::R0_64;
222 BNE = Mips::BNE64;
223 BEQ = Mips::BEQ64;
224 MOVE = Mips::OR64;
225 }
226
227 Register Dest = I->getOperand(0).getReg();
228 Register Ptr = I->getOperand(1).getReg();
229 Register OldVal = I->getOperand(2).getReg();
230 Register NewVal = I->getOperand(3).getReg();
231 Register Scratch = I->getOperand(4).getReg();
232
233 // insert new blocks after the current block
234 const BasicBlock *LLVM_BB = BB.getBasicBlock();
235 MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
236 MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
237 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
239 MF->insert(It, loop1MBB);
240 MF->insert(It, loop2MBB);
241 MF->insert(It, exitMBB);
242
243 // Transfer the remainder of BB and its successor edges to exitMBB.
244 exitMBB->splice(exitMBB->begin(), &BB,
245 std::next(MachineBasicBlock::iterator(I)), BB.end());
247
248 // thisMBB:
249 // ...
250 // fallthrough --> loop1MBB
252 loop1MBB->addSuccessor(exitMBB);
253 loop1MBB->addSuccessor(loop2MBB);
254 loop1MBB->normalizeSuccProbs();
255 loop2MBB->addSuccessor(loop1MBB);
256 loop2MBB->addSuccessor(exitMBB);
257 loop2MBB->normalizeSuccProbs();
258
259 // loop1MBB:
260 // ll dest, 0(ptr)
261 // bne dest, oldval, exitMBB
262 BuildMI(loop1MBB, DL, TII->get(LL), Dest).addReg(Ptr).addImm(0);
263 BuildMI(loop1MBB, DL, TII->get(BNE))
264 .addReg(Dest, RegState::Kill).addReg(OldVal).addMBB(exitMBB);
265
266 // loop2MBB:
267 // move scratch, NewVal
268 // sc Scratch, Scratch, 0(ptr)
269 // beq Scratch, $0, loop1MBB
270 BuildMI(loop2MBB, DL, TII->get(MOVE), Scratch).addReg(NewVal).addReg(ZERO);
271 BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
272 .addReg(Scratch).addReg(Ptr).addImm(0);
273 BuildMI(loop2MBB, DL, TII->get(BEQ))
274 .addReg(Scratch, RegState::Kill).addReg(ZERO).addMBB(loop1MBB);
275
277 computeAndAddLiveIns(LiveRegs, *loop1MBB);
278 computeAndAddLiveIns(LiveRegs, *loop2MBB);
280
281 NMBBI = BB.end();
282 I->eraseFromParent();
283 return true;
284}
285
289 const MipsSubtarget *STI,
290 const MipsInstrInfo *TII) {
291
292 MachineFunction *MF = BB.getParent();
293
294 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
295 DebugLoc DL = I->getDebugLoc();
296
297 unsigned LL, SC, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
298 unsigned BEQ = Mips::BEQ;
299 unsigned SEOp = Mips::SEH;
300
301 if (STI->inMicroMipsMode()) {
302 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
303 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
304 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
305 SLT = Mips::SLT_MM;
306 SLTu = Mips::SLTu_MM;
307 OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
308 MOVN = Mips::MOVN_I_MM;
309 MOVZ = Mips::MOVZ_I_MM;
310 SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
311 SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
312 } else {
313 LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
314 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
315 SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
316 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
317 SLT = Mips::SLT;
318 SLTu = Mips::SLTu;
319 OR = Mips::OR;
320 MOVN = Mips::MOVN_I_I;
321 MOVZ = Mips::MOVZ_I_I;
322 SELNEZ = Mips::SELNEZ;
323 SELEQZ = Mips::SELEQZ;
324 }
325
326 bool IsSwap = false;
327 bool IsNand = false;
328 bool IsMin = false;
329 bool IsMax = false;
330 bool IsUnsigned = false;
331 bool DestOK = false;
332
333 unsigned Opcode = 0;
334 switch (I->getOpcode()) {
335 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
336 SEOp = Mips::SEB;
337 [[fallthrough]];
338 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
339 IsNand = true;
340 break;
341 case Mips::ATOMIC_SWAP_I8_POSTRA:
342 SEOp = Mips::SEB;
343 [[fallthrough]];
344 case Mips::ATOMIC_SWAP_I16_POSTRA:
345 IsSwap = true;
346 break;
347 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
348 SEOp = Mips::SEB;
349 [[fallthrough]];
350 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
351 Opcode = Mips::ADDu;
352 break;
353 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
354 SEOp = Mips::SEB;
355 [[fallthrough]];
356 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
357 Opcode = Mips::SUBu;
358 break;
359 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
360 SEOp = Mips::SEB;
361 [[fallthrough]];
362 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
363 Opcode = Mips::AND;
364 break;
365 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
366 SEOp = Mips::SEB;
367 [[fallthrough]];
368 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
369 Opcode = Mips::OR;
370 break;
371 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
372 SEOp = Mips::SEB;
373 [[fallthrough]];
374 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
375 Opcode = Mips::XOR;
376 break;
377 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
378 SEOp = Mips::SEB;
379 IsUnsigned = true;
380 IsMin = true;
381 break;
382 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
383 IsUnsigned = true;
384 IsMin = true;
385 break;
386 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
387 SEOp = Mips::SEB;
388 IsMin = true;
389 break;
390 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
391 IsMin = true;
392 break;
393 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
394 SEOp = Mips::SEB;
395 IsUnsigned = true;
396 IsMax = true;
397 break;
398 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
399 IsUnsigned = true;
400 IsMax = true;
401 break;
402 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
403 SEOp = Mips::SEB;
404 IsMax = true;
405 break;
406 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
407 IsMax = true;
408 break;
409 default:
410 llvm_unreachable("Unknown subword atomic pseudo for expansion!");
411 }
412
413 Register Dest = I->getOperand(0).getReg();
414 Register Ptr = I->getOperand(1).getReg();
415 Register Incr = I->getOperand(2).getReg();
416 Register Mask = I->getOperand(3).getReg();
417 Register Mask2 = I->getOperand(4).getReg();
418 Register ShiftAmnt = I->getOperand(5).getReg();
419 Register OldVal = I->getOperand(6).getReg();
420 Register BinOpRes = I->getOperand(7).getReg();
421 Register StoreVal = I->getOperand(8).getReg();
422 bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32();
423
424 const BasicBlock *LLVM_BB = BB.getBasicBlock();
425 MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
426 MachineBasicBlock *loop1MBB = nullptr;
427 MachineBasicBlock *loop2MBB = nullptr;
428 if (NoMovnInstr) {
429 loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
430 loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
431 }
432 MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
433 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
435 MF->insert(It, loopMBB);
436 if (NoMovnInstr) {
437 MF->insert(It, loop1MBB);
438 MF->insert(It, loop2MBB);
439 }
440 MF->insert(It, sinkMBB);
441 MF->insert(It, exitMBB);
442
443 exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());
445
447 if (NoMovnInstr) {
448 loopMBB->addSuccessor(loop1MBB);
449 loopMBB->addSuccessor(loop2MBB);
450 } else {
451 loopMBB->addSuccessor(sinkMBB);
452 loopMBB->addSuccessor(loopMBB);
453 loopMBB->normalizeSuccProbs();
454 }
455 if (NoMovnInstr) {
456 loop1MBB->addSuccessor(loop2MBB);
457 loop2MBB->addSuccessor(loopMBB);
458 loop2MBB->addSuccessor(sinkMBB);
459 }
460
461 BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
462 if (IsNand) {
463 // and andres, oldval, incr2
464 // nor binopres, $0, andres
465 // and newval, binopres, mask
466 BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
467 .addReg(OldVal)
468 .addReg(Incr);
469 BuildMI(loopMBB, DL, TII->get(Mips::NOR), BinOpRes)
470 .addReg(Mips::R0)
471 .addReg(BinOpRes);
472 BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
473 .addReg(BinOpRes)
474 .addReg(Mask);
475 } else if (IsMin || IsMax) {
476
477 assert(I->getNumOperands() == 10 &&
478 "Atomics min|max|umin|umax use an additional register");
479 Register Scratch4 = I->getOperand(9).getReg();
480
481 unsigned SLTScratch4 = IsUnsigned ? SLTu : SLT;
482 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
483 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
484 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
485
486 BuildMI(loopMBB, DL, TII->get(Mips::SRAV), StoreVal)
487 .addReg(OldVal)
488 .addReg(ShiftAmnt);
489 if (IsUnsigned) {
490 const unsigned OpMask = SEOp == Mips::SEH ? 0xffff : 0xff;
491 BuildMI(loopMBB, DL, TII->get(Mips::ANDi), StoreVal)
492 .addReg(StoreVal)
493 .addImm(OpMask);
494 } else if (STI->hasMips32r2()) {
495 BuildMI(loopMBB, DL, TII->get(SEOp), StoreVal).addReg(StoreVal);
496 } else {
497 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
498 const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA;
499 BuildMI(loopMBB, DL, TII->get(Mips::SLL), StoreVal)
500 .addReg(StoreVal, RegState::Kill)
501 .addImm(ShiftImm);
502 BuildMI(loopMBB, DL, TII->get(SROp), StoreVal)
503 .addReg(StoreVal, RegState::Kill)
504 .addImm(ShiftImm);
505 }
506 BuildMI(loopMBB, DL, TII->get(Mips::OR), Dest)
507 .addReg(Mips::R0)
508 .addReg(StoreVal);
509 DestOK = true;
510 BuildMI(loopMBB, DL, TII->get(Mips::SLLV), StoreVal)
511 .addReg(StoreVal)
512 .addReg(ShiftAmnt);
513
514 // unsigned: sltu Scratch4, StoreVal, Incr
515 // signed: slt Scratch4, StoreVal, Incr
516 BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4)
517 .addReg(StoreVal)
518 .addReg(Incr);
519
520 if (STI->hasMips64r6() || STI->hasMips32r6()) {
521 // max: seleqz BinOpRes, OldVal, Scratch4
522 // selnez Scratch4, Incr, Scratch4
523 // or BinOpRes, BinOpRes, Scratch4
524 // min: selnqz BinOpRes, OldVal, Scratch4
525 // seleqz Scratch4, Incr, Scratch4
526 // or BinOpRes, BinOpRes, Scratch4
527 BuildMI(loopMBB, DL, TII->get(SELOldVal), BinOpRes)
528 .addReg(StoreVal)
529 .addReg(Scratch4);
530 BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch4)
531 .addReg(Incr)
532 .addReg(Scratch4);
533 BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
534 .addReg(BinOpRes)
535 .addReg(Scratch4);
536 } else if (STI->hasMips4() || STI->hasMips32()) {
537 // max: move BinOpRes, StoreVal
538 // movn BinOpRes, Incr, Scratch4, BinOpRes
539 // min: move BinOpRes, StoreVal
540 // movz BinOpRes, Incr, Scratch4, BinOpRes
541 BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
542 .addReg(StoreVal)
543 .addReg(Mips::R0);
544 BuildMI(loopMBB, DL, TII->get(MOVIncr), BinOpRes)
545 .addReg(Incr)
546 .addReg(Scratch4)
547 .addReg(BinOpRes);
548 } else {
549 // if min:
550 // loopMBB: move BinOpRes, StoreVal
551 // beq Scratch4, 0, loop1MBB
552 // j loop2MBB
553 // loop1MBB: move BinOpRes, Incr
554 // loop2MBB: and BinOpRes, BinOpRes, Mask
555 // and StoreVal, OlddVal, Mask2
556 // or StoreVal, StoreVal, BinOpRes
557 // StoreVal<tied1> = sc StoreVal, 0(Ptr)
558 // beq StoreVal, zero, loopMBB
559 //
560 // if max:
561 // loopMBB: move BinOpRes, Incr
562 // beq Scratch4, 0, loop1MBB
563 // j loop2MBB
564 // loop1MBB: move BinOpRes, StoreVal
565 // loop2MBB: and BinOpRes, BinOpRes, Mask
566 // and StoreVal, OlddVal, Mask2
567 // or StoreVal, StoreVal, BinOpRes
568 // StoreVal<tied1> = sc StoreVal, 0(Ptr)
569 // beq StoreVal, zero, loopMBB
570 if (IsMin) {
571 BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
572 .addReg(StoreVal)
573 .addReg(Mips::R0);
574 BuildMI(loop1MBB, DL, TII->get(OR), BinOpRes)
575 .addReg(Incr)
576 .addReg(Mips::R0);
577 } else {
578 BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
579 .addReg(Incr)
580 .addReg(Mips::R0);
581 BuildMI(loop1MBB, DL, TII->get(OR), BinOpRes)
582 .addReg(StoreVal)
583 .addReg(Mips::R0);
584 }
585 BuildMI(loopMBB, DL, TII->get(BEQ))
586 .addReg(Scratch4)
587 .addReg(Mips::R0)
588 .addMBB(loop1MBB);
589 BuildMI(loopMBB, DL, TII->get(Mips::J)).addMBB(loop2MBB);
590 }
591
592 // and BinOpRes, BinOpRes, Mask
593 if (NoMovnInstr)
594 BuildMI(loop2MBB, DL, TII->get(Mips::AND), BinOpRes)
595 .addReg(BinOpRes)
596 .addReg(Mask);
597 else
598 BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
599 .addReg(BinOpRes)
600 .addReg(Mask);
601
602 } else if (!IsSwap) {
603 // <binop> binopres, oldval, incr2
604 // and newval, binopres, mask
605 BuildMI(loopMBB, DL, TII->get(Opcode), BinOpRes)
606 .addReg(OldVal)
607 .addReg(Incr);
608 BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
609 .addReg(BinOpRes)
610 .addReg(Mask);
611 } else { // atomic.swap
612 // and newval, incr2, mask
613 BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
614 .addReg(Incr)
615 .addReg(Mask);
616 }
617
618 // and StoreVal, OlddVal, Mask2
619 // or StoreVal, StoreVal, BinOpRes
620 // StoreVal<tied1> = sc StoreVal, 0(Ptr)
621 // beq StoreVal, zero, loopMBB
622 if (NoMovnInstr) {
623 BuildMI(loop2MBB, DL, TII->get(Mips::AND), StoreVal)
624 .addReg(OldVal)
625 .addReg(Mask2);
626 BuildMI(loop2MBB, DL, TII->get(Mips::OR), StoreVal)
627 .addReg(StoreVal)
628 .addReg(BinOpRes);
629 BuildMI(loop2MBB, DL, TII->get(SC), StoreVal)
630 .addReg(StoreVal)
631 .addReg(Ptr)
632 .addImm(0);
633 BuildMI(loop2MBB, DL, TII->get(BEQ))
634 .addReg(StoreVal)
635 .addReg(Mips::R0)
636 .addMBB(loopMBB);
637 } else {
638 BuildMI(loopMBB, DL, TII->get(Mips::AND), StoreVal)
639 .addReg(OldVal)
640 .addReg(Mask2);
641 BuildMI(loopMBB, DL, TII->get(Mips::OR), StoreVal)
642 .addReg(StoreVal)
643 .addReg(BinOpRes);
644 BuildMI(loopMBB, DL, TII->get(SC), StoreVal)
645 .addReg(StoreVal)
646 .addReg(Ptr)
647 .addImm(0);
648 BuildMI(loopMBB, DL, TII->get(BEQ))
649 .addReg(StoreVal)
650 .addReg(Mips::R0)
651 .addMBB(loopMBB);
652 }
653
654 // sinkMBB:
655 // and maskedoldval1,oldval,mask
656 // srl srlres,maskedoldval1,shiftamt
657 // sign_extend dest,srlres
658
659 if (!DestOK) {
660 sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
661 BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest).addReg(OldVal).addReg(Mask);
662 BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
663 .addReg(Dest)
664 .addReg(ShiftAmnt);
665
666 if (STI->hasMips32r2()) {
667 BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
668 } else {
669 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
670 BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
671 .addReg(Dest, RegState::Kill)
672 .addImm(ShiftImm);
673 BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
674 .addReg(Dest, RegState::Kill)
675 .addImm(ShiftImm);
676 }
677 }
678
681 if (loop1MBB) {
682 assert(loop2MBB && "should have 2 loop blocks");
683 computeAndAddLiveIns(LiveRegs, *loop1MBB);
684 computeAndAddLiveIns(LiveRegs, *loop2MBB);
685 }
688
689 NMBBI = BB.end();
690 I->eraseFromParent();
691
692 return true;
693}
694
697 MachineBasicBlock::iterator &NMBBI, unsigned Size,
698 const MipsSubtarget *STI,
699 const MipsInstrInfo *TII) {
700 MachineFunction *MF = BB.getParent();
701
702 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
703 DebugLoc DL = I->getDebugLoc();
704
705 unsigned LL, SC, ZERO, BEQ, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
706
707 if (Size == 4) {
708 if (STI->inMicroMipsMode()) {
709 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
710 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
711 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
712 SLT = Mips::SLT_MM;
713 SLTu = Mips::SLTu_MM;
714 OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
715 MOVN = Mips::MOVN_I_MM;
716 MOVZ = Mips::MOVZ_I_MM;
717 SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
718 SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
719 } else {
720 LL = STI->hasMips32r6()
721 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
722 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
723 SC = STI->hasMips32r6()
724 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
725 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
726 BEQ = Mips::BEQ;
727 SLT = Mips::SLT;
728 SLTu = Mips::SLTu;
729 OR = Mips::OR;
730 MOVN = Mips::MOVN_I_I;
731 MOVZ = Mips::MOVZ_I_I;
732 SELNEZ = Mips::SELNEZ;
733 SELEQZ = Mips::SELEQZ;
734 }
735
736 ZERO = Mips::R0;
737 } else {
738 LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
739 SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
740 ZERO = Mips::R0_64;
741 BEQ = Mips::BEQ64;
742 SLT = Mips::SLT64;
743 SLTu = Mips::SLTu64;
744 OR = Mips::OR64;
745 MOVN = Mips::MOVN_I64_I64;
746 MOVZ = Mips::MOVZ_I64_I64;
747 SELNEZ = Mips::SELNEZ64;
748 SELEQZ = Mips::SELEQZ64;
749 }
750
751 Register OldVal = I->getOperand(0).getReg();
752 Register Ptr = I->getOperand(1).getReg();
753 Register Incr = I->getOperand(2).getReg();
754 Register Scratch = I->getOperand(3).getReg();
755
756 unsigned Opcode = 0;
757 unsigned AND = 0;
758 unsigned NOR = 0;
759
760 bool IsOr = false;
761 bool IsNand = false;
762 bool IsMin = false;
763 bool IsMax = false;
764 bool IsUnsigned = false;
765
766 switch (I->getOpcode()) {
767 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
768 Opcode = Mips::ADDu;
769 break;
770 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
771 Opcode = Mips::SUBu;
772 break;
773 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
774 Opcode = Mips::AND;
775 break;
776 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
777 Opcode = Mips::OR;
778 break;
779 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
780 Opcode = Mips::XOR;
781 break;
782 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
783 IsNand = true;
784 AND = Mips::AND;
785 NOR = Mips::NOR;
786 break;
787 case Mips::ATOMIC_SWAP_I32_POSTRA:
788 IsOr = true;
789 break;
790 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
791 Opcode = Mips::DADDu;
792 break;
793 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
794 Opcode = Mips::DSUBu;
795 break;
796 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
797 Opcode = Mips::AND64;
798 break;
799 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
800 Opcode = Mips::OR64;
801 break;
802 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
803 Opcode = Mips::XOR64;
804 break;
805 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
806 IsNand = true;
807 AND = Mips::AND64;
808 NOR = Mips::NOR64;
809 break;
810 case Mips::ATOMIC_SWAP_I64_POSTRA:
811 IsOr = true;
812 break;
813 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
814 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
815 IsUnsigned = true;
816 [[fallthrough]];
817 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
818 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
819 IsMin = true;
820 break;
821 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
822 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
823 IsUnsigned = true;
824 [[fallthrough]];
825 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
826 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
827 IsMax = true;
828 break;
829 default:
830 llvm_unreachable("Unknown pseudo atomic!");
831 }
832
833 bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32();
834 const BasicBlock *LLVM_BB = BB.getBasicBlock();
835 MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
836 MachineBasicBlock *loop1MBB = nullptr;
837 MachineBasicBlock *loop2MBB = nullptr;
838 if (NoMovnInstr) {
839 loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
840 loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
841 }
842 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
844 MF->insert(It, loopMBB);
845 if (NoMovnInstr) {
846 MF->insert(It, loop1MBB);
847 MF->insert(It, loop2MBB);
848 }
849 MF->insert(It, exitMBB);
850
851 exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());
853
855 if (NoMovnInstr) {
856 loopMBB->addSuccessor(loop1MBB);
857 loopMBB->addSuccessor(loop2MBB);
858 } else {
859 loopMBB->addSuccessor(exitMBB);
860 loopMBB->addSuccessor(loopMBB);
861 }
862 loopMBB->normalizeSuccProbs();
863 if (NoMovnInstr) {
864 loop1MBB->addSuccessor(loop2MBB);
865 loop2MBB->addSuccessor(loopMBB);
866 loop2MBB->addSuccessor(exitMBB);
867 }
868
869 BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
870 assert((OldVal != Ptr) && "Clobbered the wrong ptr reg!");
871 assert((OldVal != Incr) && "Clobbered the wrong reg!");
872 if (IsMin || IsMax) {
873 // Remove trailing kill/dead register operands added by
874 // MachineInstr::addRegisterKilled. These are super-register markers that
875 // must correspond to one of the physical registers in operands 1-4.
876 // The kill/dead markers may also appear on preceding subregs.
877 const TargetRegisterInfo *TRI = STI->getRegisterInfo();
878 while (I->getNumOperands() > 5) {
879 auto &Op = I->getOperand(I->getNumOperands() - 1);
880 // Check if this register overlaps with any physical register in
881 // operands 1-4 that has kill/dead marker (i.e., it's a super-register
882 // marker for subregs).
883 bool HasOverlapWithKill = false;
884 for (unsigned i = 1; i <= 4; ++i) {
885 auto &RefOp = I->getOperand(i);
886 if (RefOp.isReg() && RefOp.getReg().isPhysical() &&
887 TRI->regsOverlap(Op.getReg(), RefOp.getReg()) &&
888 (RefOp.isKill() || RefOp.isDead())) {
889 HasOverlapWithKill = true;
890 break;
891 }
892 }
893 // Remove if HasOverlapWithKill is true or Op has kill/dead marker.
894 bool HasKillOrDead = Op.isReg() && Op.getReg().isPhysical() &&
895 (Op.isKill() || Op.isDead());
896 if (!HasOverlapWithKill && !HasKillOrDead)
897 break;
898 I->removeOperand(I->getNumOperands() - 1);
899 }
900
901 assert(I->getNumOperands() == 5 &&
902 "Atomics min|max|umin|umax use an additional register");
903 MCRegister Scratch2 = I->getOperand(4).getReg().asMCReg();
904
905 // On Mips64 result of slt is GPR32.
906 MCRegister Scratch2_32 =
907 (Size == 8) ? STI->getRegisterInfo()->getSubReg(Scratch2, Mips::sub_32)
908 : Scratch2;
909
910 unsigned SLTScratch2 = IsUnsigned ? SLTu : SLT;
911 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
912 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
913 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
914
915 // unsigned: sltu Scratch2, oldVal, Incr
916 // signed: slt Scratch2, oldVal, Incr
917 BuildMI(loopMBB, DL, TII->get(SLTScratch2), Scratch2_32)
918 .addReg(OldVal)
919 .addReg(Incr);
920
921 if (STI->hasMips64r6() || STI->hasMips32r6()) {
922 // max: seleqz Scratch, OldVal, Scratch2
923 // selnez Scratch2, Incr, Scratch2
924 // or Scratch, Scratch, Scratch2
925 // min: selnez Scratch, OldVal, Scratch2
926 // seleqz Scratch2, Incr, Scratch2
927 // or Scratch, Scratch, Scratch2
928 BuildMI(loopMBB, DL, TII->get(SELOldVal), Scratch)
929 .addReg(OldVal)
930 .addReg(Scratch2);
931 BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch2)
932 .addReg(Incr)
933 .addReg(Scratch2);
934 BuildMI(loopMBB, DL, TII->get(OR), Scratch)
935 .addReg(Scratch)
936 .addReg(Scratch2);
937 } else if (STI->hasMips4() || STI->hasMips32()) {
938 // max: move Scratch, OldVal
939 // movn Scratch, Incr, Scratch2, Scratch
940 // min: move Scratch, OldVal
941 // movz Scratch, Incr, Scratch2, Scratch
942 BuildMI(loopMBB, DL, TII->get(OR), Scratch)
943 .addReg(OldVal)
944 .addReg(ZERO);
945 BuildMI(loopMBB, DL, TII->get(MOVIncr), Scratch)
946 .addReg(Incr)
947 .addReg(Scratch2)
948 .addReg(Scratch);
949 } else {
950 // if min:
951 // loopMBB: move Scratch, OldVal
952 // beq Scratch2_32, 0, loop1MBB
953 // j loop2MBB
954 // loop1MBB: move Scratch, Incr
955 // loop2MBB: sc $2, 0($4)
956 // beqz $2, $BB0_1
957 // nop
958 //
959 // if max:
960 // loopMBB: move Scratch, Incr
961 // beq Scratch2_32, 0, loop1MBB
962 // j loop2MBB
963 // loop1MBB: move Scratch, OldVal
964 // loop2MBB: sc $2, 0($4)
965 // beqz $2, $BB0_1
966 // nop
967 if (IsMin) {
968 BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(OldVal).addReg(ZERO);
969 BuildMI(loop1MBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);
970 } else {
971 BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);
972 BuildMI(loop1MBB, DL, TII->get(OR), Scratch)
973 .addReg(OldVal)
974 .addReg(ZERO);
975 }
976 BuildMI(loopMBB, DL, TII->get(BEQ))
977 .addReg(Scratch2_32)
978 .addReg(ZERO)
979 .addMBB(loop1MBB);
980 BuildMI(loopMBB, DL, TII->get(Mips::J)).addMBB(loop2MBB);
981 }
982
983 } else if (Opcode) {
984 BuildMI(loopMBB, DL, TII->get(Opcode), Scratch).addReg(OldVal).addReg(Incr);
985 } else if (IsNand) {
986 assert(AND && NOR &&
987 "Unknown nand instruction for atomic pseudo expansion");
988 BuildMI(loopMBB, DL, TII->get(AND), Scratch).addReg(OldVal).addReg(Incr);
989 BuildMI(loopMBB, DL, TII->get(NOR), Scratch).addReg(ZERO).addReg(Scratch);
990 } else {
991 assert(IsOr && OR && "Unknown instruction for atomic pseudo expansion!");
992 (void)IsOr;
993 BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);
994 }
995
996 if (NoMovnInstr) {
997 BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
998 .addReg(Scratch)
999 .addReg(Ptr)
1000 .addImm(0);
1001 BuildMI(loop2MBB, DL, TII->get(BEQ))
1002 .addReg(Scratch)
1003 .addReg(ZERO)
1004 .addMBB(loopMBB);
1005 } else {
1006 BuildMI(loopMBB, DL, TII->get(SC), Scratch)
1007 .addReg(Scratch)
1008 .addReg(Ptr)
1009 .addImm(0);
1010 BuildMI(loopMBB, DL, TII->get(BEQ))
1011 .addReg(Scratch)
1012 .addReg(ZERO)
1013 .addMBB(loopMBB);
1014 }
1015
1016 NMBBI = BB.end();
1017 I->eraseFromParent();
1018
1020 computeAndAddLiveIns(LiveRegs, *loopMBB);
1021 if (loop1MBB) {
1022 assert(loop2MBB && "should have 2 loop blocks");
1023 computeAndAddLiveIns(LiveRegs, *loop1MBB);
1024 computeAndAddLiveIns(LiveRegs, *loop2MBB);
1025 }
1026 computeAndAddLiveIns(LiveRegs, *exitMBB);
1027
1028 return true;
1029}
1030
1033 const MipsSubtarget *STI, const MipsInstrInfo *TII) {
1034
1035 bool Modified = false;
1036
1037 switch (MBBI->getOpcode()) {
1038 case Mips::ATOMIC_CMP_SWAP_I32_POSTRA:
1039 case Mips::ATOMIC_CMP_SWAP_I64_POSTRA:
1040 return expandAtomicCmpSwap(MBB, MBBI, NMBB, STI, TII);
1041 case Mips::ATOMIC_CMP_SWAP_I8_POSTRA:
1042 case Mips::ATOMIC_CMP_SWAP_I16_POSTRA:
1043 return expandAtomicCmpSwapSubword(MBB, MBBI, NMBB, STI, TII);
1044 case Mips::ATOMIC_SWAP_I8_POSTRA:
1045 case Mips::ATOMIC_SWAP_I16_POSTRA:
1046 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
1047 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
1048 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
1049 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
1050 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
1051 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
1052 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
1053 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
1054 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
1055 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
1056 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
1057 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
1058 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
1059 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
1060 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
1061 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
1062 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
1063 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
1064 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
1065 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
1066 return expandAtomicBinOpSubword(MBB, MBBI, NMBB, STI, TII);
1067 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
1068 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
1069 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
1070 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
1071 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
1072 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
1073 case Mips::ATOMIC_SWAP_I32_POSTRA:
1074 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
1075 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
1076 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
1077 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
1078 return expandAtomicBinOp(MBB, MBBI, NMBB, 4, STI, TII);
1079 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
1080 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
1081 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
1082 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
1083 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
1084 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
1085 case Mips::ATOMIC_SWAP_I64_POSTRA:
1086 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
1087 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
1088 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
1089 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
1090 return expandAtomicBinOp(MBB, MBBI, NMBB, 8, STI, TII);
1091 default:
1092 return Modified;
1093 }
1094}
1095
1097 const MipsInstrInfo *TII) {
1098 bool Modified = false;
1099
1100 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
1101 while (MBBI != E) {
1102 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
1103 Modified |= expandMI(MBB, MBBI, NMBBI, STI, TII);
1104 MBBI = NMBBI;
1105 }
1106
1107 return Modified;
1108}
1109
1111 const MipsSubtarget *STI = &MF.getSubtarget<MipsSubtarget>();
1112 const MipsInstrInfo *TII = STI->getInstrInfo();
1113
1114 bool Modified = false;
1115 for (MachineBasicBlock &MBB : MF)
1116 Modified |= expandMBB(MBB, STI, TII);
1117
1118 if (Modified)
1119 MF.RenumberBlocks();
1120
1121 return Modified;
1122}
1123
1124/// createMipsExpandPseudoPass - returns an instance of the pseudo instruction
1125/// expansion pass.
1127 return new MipsExpandPseudoLegacy();
1128}
1129
1130bool MipsExpandPseudoLegacy::runOnMachineFunction(MachineFunction &MF) {
1131 return expandPseudosInMF(MF);
1132}
1133
1134PreservedAnalyses
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
@ ZERO
Special weight used for cases with exact zero probability.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define I(x, y, z)
Definition MD5.cpp:57
Register const TargetRegisterInfo * TRI
static bool expandPseudosInMF(MachineFunction &MF)
static bool expandAtomicBinOp(MachineBasicBlock &BB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &NMBBI, unsigned Size, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandAtomicCmpSwap(MachineBasicBlock &BB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &NMBBI, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandMBB(MachineBasicBlock &MBB, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandAtomicCmpSwapSubword(MachineBasicBlock &BB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &NMBBI, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NMBB, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandAtomicBinOpSubword(MachineBasicBlock &BB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &NMBBI, const MipsSubtarget *STI, const MipsInstrInfo *TII)
LLVM Basic Block Representation.
Definition BasicBlock.h:62
static constexpr BranchProbability getOne()
A debug info location.
Definition DebugLoc.h:126
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
BasicBlockListType::iterator iterator
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
bool ArePtrs64bit() const
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
bool hasMips32r6() const
bool hasMips4() const
bool inMicroMipsMode() const
const MipsInstrInfo * getInstrInfo() const override
bool hasMips64r6() const
bool hasMips32() const
const MipsRegisterInfo * getRegisterInfo() const override
bool hasMips32r2() const
const MipsABIInfo & getABI() const
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
Definition ilist_node.h:123
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
FunctionPass * createMipsExpandPseudoLegacyPass()
createMipsExpandPseudoPass - returns an instance of the pseudo instruction expansion pass.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
DWARFExpression::Operation Op
LLVM_ABI void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().