blob: 35c185aa5edd3bae2e7dcc3b889be06d0b48bdb0 [file] [log] [blame]
Alex Bradbury21aea512018-09-19 10:54:22 +00001//===-- RISCVExpandPseudoInsts.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. This pass should be run after register allocation but before
12// the post-regalloc scheduling pass.
13//
14//===----------------------------------------------------------------------===//
15
16#include "RISCV.h"
17#include "RISCVInstrInfo.h"
18#include "RISCVTargetMachine.h"
19
20#include "llvm/CodeGen/LivePhysRegs.h"
21#include "llvm/CodeGen/MachineFunctionPass.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
23
24using namespace llvm;
25
26#define RISCV_EXPAND_PSEUDO_NAME "RISCV pseudo instruction expansion pass"
27
28namespace {
29
30class RISCVExpandPseudo : public MachineFunctionPass {
31public:
32 const RISCVInstrInfo *TII;
33 static char ID;
34
35 RISCVExpandPseudo() : MachineFunctionPass(ID) {
36 initializeRISCVExpandPseudoPass(*PassRegistry::getPassRegistry());
37 }
38
39 bool runOnMachineFunction(MachineFunction &MF) override;
40
41 StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; }
42
43private:
44 bool expandMBB(MachineBasicBlock &MBB);
45 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
46 MachineBasicBlock::iterator &NextMBBI);
47 bool expandAtomicBinOp(MachineBasicBlock &MBB,
48 MachineBasicBlock::iterator MBBI, AtomicRMWInst::BinOp,
49 bool IsMasked, int Width,
50 MachineBasicBlock::iterator &NextMBBI);
51 bool expandAtomicMinMaxOp(MachineBasicBlock &MBB,
52 MachineBasicBlock::iterator MBBI,
53 AtomicRMWInst::BinOp, bool IsMasked, int Width,
54 MachineBasicBlock::iterator &NextMBBI);
Alex Bradbury66d9a752018-11-29 20:43:42 +000055 bool expandAtomicCmpXchg(MachineBasicBlock &MBB,
56 MachineBasicBlock::iterator MBBI, bool IsMasked,
57 int Width, MachineBasicBlock::iterator &NextMBBI);
Alex Bradbury21aea512018-09-19 10:54:22 +000058};
59
60char RISCVExpandPseudo::ID = 0;
61
62bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
63 TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo());
64 bool Modified = false;
65 for (auto &MBB : MF)
66 Modified |= expandMBB(MBB);
67 return Modified;
68}
69
70bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
71 bool Modified = false;
72
73 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
74 while (MBBI != E) {
75 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
76 Modified |= expandMI(MBB, MBBI, NMBBI);
77 MBBI = NMBBI;
78 }
79
80 return Modified;
81}
82
83bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
84 MachineBasicBlock::iterator MBBI,
85 MachineBasicBlock::iterator &NextMBBI) {
86 switch (MBBI->getOpcode()) {
87 case RISCV::PseudoAtomicLoadNand32:
88 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, false, 32,
89 NextMBBI);
90 case RISCV::PseudoMaskedAtomicSwap32:
91 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xchg, true, 32,
92 NextMBBI);
93 case RISCV::PseudoMaskedAtomicLoadAdd32:
94 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Add, true, 32, NextMBBI);
95 case RISCV::PseudoMaskedAtomicLoadSub32:
96 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Sub, true, 32, NextMBBI);
97 case RISCV::PseudoMaskedAtomicLoadNand32:
98 return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, true, 32,
99 NextMBBI);
100 case RISCV::PseudoMaskedAtomicLoadMax32:
101 return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::Max, true, 32,
102 NextMBBI);
103 case RISCV::PseudoMaskedAtomicLoadMin32:
104 return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::Min, true, 32,
105 NextMBBI);
106 case RISCV::PseudoMaskedAtomicLoadUMax32:
107 return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::UMax, true, 32,
108 NextMBBI);
109 case RISCV::PseudoMaskedAtomicLoadUMin32:
110 return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::UMin, true, 32,
111 NextMBBI);
Alex Bradbury66d9a752018-11-29 20:43:42 +0000112 case RISCV::PseudoCmpXchg32:
113 return expandAtomicCmpXchg(MBB, MBBI, false, 32, NextMBBI);
114 case RISCV::PseudoMaskedCmpXchg32:
115 return expandAtomicCmpXchg(MBB, MBBI, true, 32, NextMBBI);
Alex Bradbury21aea512018-09-19 10:54:22 +0000116 }
117
118 return false;
119}
120
121static unsigned getLRForRMW32(AtomicOrdering Ordering) {
122 switch (Ordering) {
123 default:
124 llvm_unreachable("Unexpected AtomicOrdering");
125 case AtomicOrdering::Monotonic:
126 return RISCV::LR_W;
127 case AtomicOrdering::Acquire:
128 return RISCV::LR_W_AQ;
129 case AtomicOrdering::Release:
130 return RISCV::LR_W;
131 case AtomicOrdering::AcquireRelease:
132 return RISCV::LR_W_AQ;
133 case AtomicOrdering::SequentiallyConsistent:
134 return RISCV::LR_W_AQ_RL;
135 }
136}
137
138static unsigned getSCForRMW32(AtomicOrdering Ordering) {
139 switch (Ordering) {
140 default:
141 llvm_unreachable("Unexpected AtomicOrdering");
142 case AtomicOrdering::Monotonic:
143 return RISCV::SC_W;
144 case AtomicOrdering::Acquire:
145 return RISCV::SC_W;
146 case AtomicOrdering::Release:
147 return RISCV::SC_W_RL;
148 case AtomicOrdering::AcquireRelease:
149 return RISCV::SC_W_RL;
150 case AtomicOrdering::SequentiallyConsistent:
151 return RISCV::SC_W_AQ_RL;
152 }
153}
154
155static void doAtomicBinOpExpansion(const RISCVInstrInfo *TII, MachineInstr &MI,
156 DebugLoc DL, MachineBasicBlock *ThisMBB,
157 MachineBasicBlock *LoopMBB,
158 MachineBasicBlock *DoneMBB,
159 AtomicRMWInst::BinOp BinOp, int Width) {
160 assert(Width == 32 && "RV64 atomic expansion currently unsupported");
161 unsigned DestReg = MI.getOperand(0).getReg();
162 unsigned ScratchReg = MI.getOperand(1).getReg();
163 unsigned AddrReg = MI.getOperand(2).getReg();
164 unsigned IncrReg = MI.getOperand(3).getReg();
165 AtomicOrdering Ordering =
166 static_cast<AtomicOrdering>(MI.getOperand(4).getImm());
167
168 // .loop:
169 // lr.w dest, (addr)
170 // binop scratch, dest, val
171 // sc.w scratch, scratch, (addr)
172 // bnez scratch, loop
173 BuildMI(LoopMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
174 .addReg(AddrReg);
175 switch (BinOp) {
176 default:
177 llvm_unreachable("Unexpected AtomicRMW BinOp");
178 case AtomicRMWInst::Nand:
179 BuildMI(LoopMBB, DL, TII->get(RISCV::AND), ScratchReg)
180 .addReg(DestReg)
181 .addReg(IncrReg);
182 BuildMI(LoopMBB, DL, TII->get(RISCV::XORI), ScratchReg)
183 .addReg(ScratchReg)
184 .addImm(-1);
185 break;
186 }
187 BuildMI(LoopMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
188 .addReg(AddrReg)
189 .addReg(ScratchReg);
190 BuildMI(LoopMBB, DL, TII->get(RISCV::BNE))
191 .addReg(ScratchReg)
192 .addReg(RISCV::X0)
193 .addMBB(LoopMBB);
194}
195
196static void insertMaskedMerge(const RISCVInstrInfo *TII, DebugLoc DL,
197 MachineBasicBlock *MBB, unsigned DestReg,
198 unsigned OldValReg, unsigned NewValReg,
199 unsigned MaskReg, unsigned ScratchReg) {
200 assert(OldValReg != ScratchReg && "OldValReg and ScratchReg must be unique");
201 assert(OldValReg != MaskReg && "OldValReg and MaskReg must be unique");
202 assert(ScratchReg != MaskReg && "ScratchReg and MaskReg must be unique");
203
204 // We select bits from newval and oldval using:
205 // https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge
206 // r = oldval ^ ((oldval ^ newval) & masktargetdata);
207 BuildMI(MBB, DL, TII->get(RISCV::XOR), ScratchReg)
208 .addReg(OldValReg)
209 .addReg(NewValReg);
210 BuildMI(MBB, DL, TII->get(RISCV::AND), ScratchReg)
211 .addReg(ScratchReg)
212 .addReg(MaskReg);
213 BuildMI(MBB, DL, TII->get(RISCV::XOR), DestReg)
214 .addReg(OldValReg)
215 .addReg(ScratchReg);
216}
217
218static void doMaskedAtomicBinOpExpansion(
219 const RISCVInstrInfo *TII, MachineInstr &MI, DebugLoc DL,
220 MachineBasicBlock *ThisMBB, MachineBasicBlock *LoopMBB,
221 MachineBasicBlock *DoneMBB, AtomicRMWInst::BinOp BinOp, int Width) {
222 assert(Width == 32 && "RV64 atomic expansion currently unsupported");
223 unsigned DestReg = MI.getOperand(0).getReg();
224 unsigned ScratchReg = MI.getOperand(1).getReg();
225 unsigned AddrReg = MI.getOperand(2).getReg();
226 unsigned IncrReg = MI.getOperand(3).getReg();
227 unsigned MaskReg = MI.getOperand(4).getReg();
228 AtomicOrdering Ordering =
229 static_cast<AtomicOrdering>(MI.getOperand(5).getImm());
230
231 // .loop:
232 // lr.w destreg, (alignedaddr)
233 // binop scratch, destreg, incr
234 // xor scratch, destreg, scratch
235 // and scratch, scratch, masktargetdata
236 // xor scratch, destreg, scratch
237 // sc.w scratch, scratch, (alignedaddr)
238 // bnez scratch, loop
239 BuildMI(LoopMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
240 .addReg(AddrReg);
241 switch (BinOp) {
242 default:
243 llvm_unreachable("Unexpected AtomicRMW BinOp");
244 case AtomicRMWInst::Xchg:
245 BuildMI(LoopMBB, DL, TII->get(RISCV::ADD), ScratchReg)
246 .addReg(RISCV::X0)
247 .addReg(IncrReg);
248 break;
249 case AtomicRMWInst::Add:
250 BuildMI(LoopMBB, DL, TII->get(RISCV::ADD), ScratchReg)
251 .addReg(DestReg)
252 .addReg(IncrReg);
253 break;
254 case AtomicRMWInst::Sub:
255 BuildMI(LoopMBB, DL, TII->get(RISCV::SUB), ScratchReg)
256 .addReg(DestReg)
257 .addReg(IncrReg);
258 break;
259 case AtomicRMWInst::Nand:
260 BuildMI(LoopMBB, DL, TII->get(RISCV::AND), ScratchReg)
261 .addReg(DestReg)
262 .addReg(IncrReg);
263 BuildMI(LoopMBB, DL, TII->get(RISCV::XORI), ScratchReg)
264 .addReg(ScratchReg)
265 .addImm(-1);
266 break;
267 }
268
269 insertMaskedMerge(TII, DL, LoopMBB, ScratchReg, DestReg, ScratchReg, MaskReg,
270 ScratchReg);
271
272 BuildMI(LoopMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
273 .addReg(AddrReg)
274 .addReg(ScratchReg);
275 BuildMI(LoopMBB, DL, TII->get(RISCV::BNE))
276 .addReg(ScratchReg)
277 .addReg(RISCV::X0)
278 .addMBB(LoopMBB);
279}
280
281bool RISCVExpandPseudo::expandAtomicBinOp(
282 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
283 AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width,
284 MachineBasicBlock::iterator &NextMBBI) {
285 MachineInstr &MI = *MBBI;
286 DebugLoc DL = MI.getDebugLoc();
287
288 MachineFunction *MF = MBB.getParent();
289 auto LoopMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
290 auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
291
292 // Insert new MBBs.
293 MF->insert(++MBB.getIterator(), LoopMBB);
294 MF->insert(++LoopMBB->getIterator(), DoneMBB);
295
296 // Set up successors and transfer remaining instructions to DoneMBB.
297 LoopMBB->addSuccessor(LoopMBB);
298 LoopMBB->addSuccessor(DoneMBB);
299 DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end());
300 DoneMBB->transferSuccessors(&MBB);
301 MBB.addSuccessor(LoopMBB);
302
303 if (!IsMasked)
304 doAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, Width);
305 else
306 doMaskedAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp,
307 Width);
308
309 NextMBBI = MBB.end();
310 MI.eraseFromParent();
311
312 LivePhysRegs LiveRegs;
313 computeAndAddLiveIns(LiveRegs, *LoopMBB);
314 computeAndAddLiveIns(LiveRegs, *DoneMBB);
315
316 return true;
317}
318
319static void insertSext(const RISCVInstrInfo *TII, DebugLoc DL,
320 MachineBasicBlock *MBB, unsigned ValReg,
321 unsigned ShamtReg) {
322 BuildMI(MBB, DL, TII->get(RISCV::SLL), ValReg)
323 .addReg(ValReg)
324 .addReg(ShamtReg);
325 BuildMI(MBB, DL, TII->get(RISCV::SRA), ValReg)
326 .addReg(ValReg)
327 .addReg(ShamtReg);
328}
329
330bool RISCVExpandPseudo::expandAtomicMinMaxOp(
331 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
332 AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width,
333 MachineBasicBlock::iterator &NextMBBI) {
334 assert(IsMasked == true &&
335 "Should only need to expand masked atomic max/min");
336 assert(Width == 32 && "RV64 atomic expansion currently unsupported");
337
338 MachineInstr &MI = *MBBI;
339 DebugLoc DL = MI.getDebugLoc();
340 MachineFunction *MF = MBB.getParent();
341 auto LoopHeadMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
342 auto LoopIfBodyMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
343 auto LoopTailMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
344 auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
345
346 // Insert new MBBs.
347 MF->insert(++MBB.getIterator(), LoopHeadMBB);
348 MF->insert(++LoopHeadMBB->getIterator(), LoopIfBodyMBB);
349 MF->insert(++LoopIfBodyMBB->getIterator(), LoopTailMBB);
350 MF->insert(++LoopTailMBB->getIterator(), DoneMBB);
351
352 // Set up successors and transfer remaining instructions to DoneMBB.
353 LoopHeadMBB->addSuccessor(LoopIfBodyMBB);
354 LoopHeadMBB->addSuccessor(LoopTailMBB);
355 LoopIfBodyMBB->addSuccessor(LoopTailMBB);
356 LoopTailMBB->addSuccessor(LoopHeadMBB);
357 LoopTailMBB->addSuccessor(DoneMBB);
358 DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end());
359 DoneMBB->transferSuccessors(&MBB);
360 MBB.addSuccessor(LoopHeadMBB);
361
362 unsigned DestReg = MI.getOperand(0).getReg();
363 unsigned Scratch1Reg = MI.getOperand(1).getReg();
364 unsigned Scratch2Reg = MI.getOperand(2).getReg();
365 unsigned AddrReg = MI.getOperand(3).getReg();
366 unsigned IncrReg = MI.getOperand(4).getReg();
367 unsigned MaskReg = MI.getOperand(5).getReg();
368 bool IsSigned = BinOp == AtomicRMWInst::Min || BinOp == AtomicRMWInst::Max;
369 AtomicOrdering Ordering =
370 static_cast<AtomicOrdering>(MI.getOperand(IsSigned ? 7 : 6).getImm());
371
372 //
373 // .loophead:
374 // lr.w destreg, (alignedaddr)
375 // and scratch2, destreg, mask
376 // mv scratch1, destreg
377 // [sext scratch2 if signed min/max]
378 // ifnochangeneeded scratch2, incr, .looptail
379 BuildMI(LoopHeadMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
380 .addReg(AddrReg);
381 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::AND), Scratch2Reg)
382 .addReg(DestReg)
383 .addReg(MaskReg);
384 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::ADDI), Scratch1Reg)
385 .addReg(DestReg)
386 .addImm(0);
387
388 switch (BinOp) {
389 default:
390 llvm_unreachable("Unexpected AtomicRMW BinOp");
391 case AtomicRMWInst::Max: {
392 insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getReg());
393 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGE))
394 .addReg(Scratch2Reg)
395 .addReg(IncrReg)
396 .addMBB(LoopTailMBB);
397 break;
398 }
399 case AtomicRMWInst::Min: {
400 insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getReg());
401 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGE))
402 .addReg(IncrReg)
403 .addReg(Scratch2Reg)
404 .addMBB(LoopTailMBB);
405 break;
406 }
407 case AtomicRMWInst::UMax:
408 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGEU))
409 .addReg(Scratch2Reg)
410 .addReg(IncrReg)
411 .addMBB(LoopTailMBB);
412 break;
413 case AtomicRMWInst::UMin:
414 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGEU))
415 .addReg(IncrReg)
416 .addReg(Scratch2Reg)
417 .addMBB(LoopTailMBB);
418 break;
419 }
420
421 // .loopifbody:
422 // xor scratch1, destreg, incr
423 // and scratch1, scratch1, mask
424 // xor scratch1, destreg, scratch1
425 insertMaskedMerge(TII, DL, LoopIfBodyMBB, Scratch1Reg, DestReg, IncrReg,
426 MaskReg, Scratch1Reg);
427
428 // .looptail:
429 // sc.w scratch1, scratch1, (addr)
430 // bnez scratch1, loop
431 BuildMI(LoopTailMBB, DL, TII->get(getSCForRMW32(Ordering)), Scratch1Reg)
432 .addReg(AddrReg)
433 .addReg(Scratch1Reg);
434 BuildMI(LoopTailMBB, DL, TII->get(RISCV::BNE))
435 .addReg(Scratch1Reg)
436 .addReg(RISCV::X0)
437 .addMBB(LoopHeadMBB);
438
439 NextMBBI = MBB.end();
440 MI.eraseFromParent();
441
442 LivePhysRegs LiveRegs;
443 computeAndAddLiveIns(LiveRegs, *LoopHeadMBB);
444 computeAndAddLiveIns(LiveRegs, *LoopIfBodyMBB);
445 computeAndAddLiveIns(LiveRegs, *LoopTailMBB);
446 computeAndAddLiveIns(LiveRegs, *DoneMBB);
447
448 return true;
449}
450
Alex Bradbury66d9a752018-11-29 20:43:42 +0000451bool RISCVExpandPseudo::expandAtomicCmpXchg(
452 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, bool IsMasked,
453 int Width, MachineBasicBlock::iterator &NextMBBI) {
454 assert(Width == 32 && "RV64 atomic expansion currently unsupported");
455 MachineInstr &MI = *MBBI;
456 DebugLoc DL = MI.getDebugLoc();
457 MachineFunction *MF = MBB.getParent();
458 auto LoopHeadMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
459 auto LoopTailMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
460 auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
461
462 // Insert new MBBs.
463 MF->insert(++MBB.getIterator(), LoopHeadMBB);
464 MF->insert(++LoopHeadMBB->getIterator(), LoopTailMBB);
465 MF->insert(++LoopTailMBB->getIterator(), DoneMBB);
466
467 // Set up successors and transfer remaining instructions to DoneMBB.
468 LoopHeadMBB->addSuccessor(LoopTailMBB);
469 LoopHeadMBB->addSuccessor(DoneMBB);
470 LoopTailMBB->addSuccessor(DoneMBB);
471 LoopTailMBB->addSuccessor(LoopHeadMBB);
472 DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end());
473 DoneMBB->transferSuccessors(&MBB);
474 MBB.addSuccessor(LoopHeadMBB);
475
476 unsigned DestReg = MI.getOperand(0).getReg();
477 unsigned ScratchReg = MI.getOperand(1).getReg();
478 unsigned AddrReg = MI.getOperand(2).getReg();
479 unsigned CmpValReg = MI.getOperand(3).getReg();
480 unsigned NewValReg = MI.getOperand(4).getReg();
481 AtomicOrdering Ordering =
482 static_cast<AtomicOrdering>(MI.getOperand(IsMasked ? 6 : 5).getImm());
483
484 if (!IsMasked) {
485 // .loophead:
486 // lr.w dest, (addr)
487 // bne dest, cmpval, done
488 BuildMI(LoopHeadMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
489 .addReg(AddrReg);
490 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BNE))
491 .addReg(DestReg)
492 .addReg(CmpValReg)
493 .addMBB(DoneMBB);
494 // .looptail:
495 // sc.w scratch, newval, (addr)
496 // bnez scratch, loophead
497 BuildMI(LoopTailMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
498 .addReg(AddrReg)
499 .addReg(NewValReg);
500 BuildMI(LoopTailMBB, DL, TII->get(RISCV::BNE))
501 .addReg(ScratchReg)
502 .addReg(RISCV::X0)
503 .addMBB(LoopHeadMBB);
504 } else {
505 // .loophead:
506 // lr.w dest, (addr)
507 // and scratch, dest, mask
508 // bne scratch, cmpval, done
509 unsigned MaskReg = MI.getOperand(5).getReg();
510 BuildMI(LoopHeadMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
511 .addReg(AddrReg);
512 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::AND), ScratchReg)
513 .addReg(DestReg)
514 .addReg(MaskReg);
515 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BNE))
516 .addReg(ScratchReg)
517 .addReg(CmpValReg)
518 .addMBB(DoneMBB);
519
520 // .looptail:
521 // xor scratch, dest, newval
522 // and scratch, scratch, mask
523 // xor scratch, dest, scratch
524 // sc.w scratch, scratch, (adrr)
525 // bnez scratch, loophead
526 insertMaskedMerge(TII, DL, LoopTailMBB, ScratchReg, DestReg, NewValReg,
527 MaskReg, ScratchReg);
528 BuildMI(LoopTailMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
529 .addReg(AddrReg)
530 .addReg(ScratchReg);
531 BuildMI(LoopTailMBB, DL, TII->get(RISCV::BNE))
532 .addReg(ScratchReg)
533 .addReg(RISCV::X0)
534 .addMBB(LoopHeadMBB);
535 }
536
537 NextMBBI = MBB.end();
538 MI.eraseFromParent();
539
540 LivePhysRegs LiveRegs;
541 computeAndAddLiveIns(LiveRegs, *LoopHeadMBB);
542 computeAndAddLiveIns(LiveRegs, *LoopTailMBB);
543 computeAndAddLiveIns(LiveRegs, *DoneMBB);
544
545 return true;
546}
547
Alex Bradbury21aea512018-09-19 10:54:22 +0000548} // end of anonymous namespace
549
550INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo",
551 RISCV_EXPAND_PSEUDO_NAME, false, false)
552namespace llvm {
553
554FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); }
555
556} // end of namespace llvm