LLVM 19.0.0git
LoongArchExpandPseudoInsts.cpp
Go to the documentation of this file.
1//===-- LoongArchExpandPseudoInsts.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.
11//
12//===----------------------------------------------------------------------===//
13
14#include "LoongArch.h"
15#include "LoongArchInstrInfo.h"
24#include "llvm/MC/MCContext.h"
27
28using namespace llvm;
29
30#define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME \
31 "LoongArch Pre-RA pseudo instruction expansion pass"
32#define LOONGARCH_EXPAND_PSEUDO_NAME \
33 "LoongArch pseudo instruction expansion pass"
34
35namespace {
36
37class LoongArchPreRAExpandPseudo : public MachineFunctionPass {
38public:
40 static char ID;
41
42 LoongArchPreRAExpandPseudo() : MachineFunctionPass(ID) {
44 }
45
46 bool runOnMachineFunction(MachineFunction &MF) override;
47
48 void getAnalysisUsage(AnalysisUsage &AU) const override {
49 AU.setPreservesCFG();
51 }
52 StringRef getPassName() const override {
54 }
55
56private:
57 bool expandMBB(MachineBasicBlock &MBB);
60 bool expandPcalau12iInstPair(MachineBasicBlock &MBB,
63 unsigned FlagsHi, unsigned SecondOpcode,
64 unsigned FlagsLo);
65 bool expandLoadAddressPcrel(MachineBasicBlock &MBB,
68 bool expandLoadAddressGot(MachineBasicBlock &MBB,
71 bool expandLoadAddressTLSLE(MachineBasicBlock &MBB,
74 bool expandLoadAddressTLSIE(MachineBasicBlock &MBB,
77 bool expandLoadAddressTLSLD(MachineBasicBlock &MBB,
80 bool expandLoadAddressTLSGD(MachineBasicBlock &MBB,
83};
84
85char LoongArchPreRAExpandPseudo::ID = 0;
86
87bool LoongArchPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
88 TII =
89 static_cast<const LoongArchInstrInfo *>(MF.getSubtarget().getInstrInfo());
90 bool Modified = false;
91 for (auto &MBB : MF)
92 Modified |= expandMBB(MBB);
93 return Modified;
94}
95
96bool LoongArchPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
97 bool Modified = false;
98
100 while (MBBI != E) {
101 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
102 Modified |= expandMI(MBB, MBBI, NMBBI);
103 MBBI = NMBBI;
104 }
105
106 return Modified;
107}
108
109bool LoongArchPreRAExpandPseudo::expandMI(
111 MachineBasicBlock::iterator &NextMBBI) {
112 switch (MBBI->getOpcode()) {
113 case LoongArch::PseudoLA_PCREL:
114 return expandLoadAddressPcrel(MBB, MBBI, NextMBBI);
115 case LoongArch::PseudoLA_GOT:
116 return expandLoadAddressGot(MBB, MBBI, NextMBBI);
117 case LoongArch::PseudoLA_TLS_LE:
118 return expandLoadAddressTLSLE(MBB, MBBI, NextMBBI);
119 case LoongArch::PseudoLA_TLS_IE:
120 return expandLoadAddressTLSIE(MBB, MBBI, NextMBBI);
121 case LoongArch::PseudoLA_TLS_LD:
122 return expandLoadAddressTLSLD(MBB, MBBI, NextMBBI);
123 case LoongArch::PseudoLA_TLS_GD:
124 return expandLoadAddressTLSGD(MBB, MBBI, NextMBBI);
125 }
126 return false;
127}
128
129bool LoongArchPreRAExpandPseudo::expandPcalau12iInstPair(
131 MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi,
132 unsigned SecondOpcode, unsigned FlagsLo) {
134 MachineInstr &MI = *MBBI;
135 DebugLoc DL = MI.getDebugLoc();
136
137 Register DestReg = MI.getOperand(0).getReg();
138 Register ScratchReg =
139 MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
140 MachineOperand &Symbol = MI.getOperand(1);
141
142 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), ScratchReg)
143 .addDisp(Symbol, 0, FlagsHi);
144
145 MachineInstr *SecondMI =
146 BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg)
147 .addReg(ScratchReg)
148 .addDisp(Symbol, 0, FlagsLo);
149
150 if (MI.hasOneMemOperand())
151 SecondMI->addMemOperand(*MF, *MI.memoperands_begin());
152
153 MI.eraseFromParent();
154 return true;
155}
156
157bool LoongArchPreRAExpandPseudo::expandLoadAddressPcrel(
159 MachineBasicBlock::iterator &NextMBBI) {
160 // Code Sequence:
161 // pcalau12i $rd, %pc_hi20(sym)
162 // addi.w/d $rd, $rd, %pc_lo12(sym)
164 const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
165 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
166 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_PCREL_HI,
167 SecondOpcode, LoongArchII::MO_PCREL_LO);
168}
169
170bool LoongArchPreRAExpandPseudo::expandLoadAddressGot(
172 MachineBasicBlock::iterator &NextMBBI) {
173 // Code Sequence:
174 // pcalau12i $rd, %got_pc_hi20(sym)
175 // ld.w/d $rd, $rd, %got_pc_lo12(sym)
177 const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
178 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
179 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_GOT_PC_HI,
180 SecondOpcode, LoongArchII::MO_GOT_PC_LO);
181}
182
183bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE(
185 MachineBasicBlock::iterator &NextMBBI) {
186 // Code Sequence:
187 // lu12i.w $rd, %le_hi20(sym)
188 // ori $rd, $rd, %le_lo12(sym)
189 //
190 // And additionally if generating code using the large code model:
191 //
192 // lu32i.d $rd, %le64_lo20(sym)
193 // lu52i.d $rd, $rd, %le64_hi12(sym)
195 MachineInstr &MI = *MBBI;
196 DebugLoc DL = MI.getDebugLoc();
197
198 bool Large = MF->getTarget().getCodeModel() == CodeModel::Large;
199 Register DestReg = MI.getOperand(0).getReg();
200 Register Parts01 =
201 Large ? MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass)
202 : DestReg;
203 Register Part1 =
204 MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
205 MachineOperand &Symbol = MI.getOperand(1);
206
207 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU12I_W), Part1)
208 .addDisp(Symbol, 0, LoongArchII::MO_LE_HI);
209
210 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ORI), Parts01)
211 .addReg(Part1, RegState::Kill)
212 .addDisp(Symbol, 0, LoongArchII::MO_LE_LO);
213
214 if (Large) {
215 Register Parts012 =
216 MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
217
218 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU32I_D), Parts012)
219 // "rj" is needed due to InstrInfo pattern requirement.
220 .addReg(Parts01, RegState::Kill)
221 .addDisp(Symbol, 0, LoongArchII::MO_LE64_LO);
222 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU52I_D), DestReg)
223 .addReg(Parts012, RegState::Kill)
224 .addDisp(Symbol, 0, LoongArchII::MO_LE64_HI);
225 }
226
227 MI.eraseFromParent();
228 return true;
229}
230
231bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSIE(
233 MachineBasicBlock::iterator &NextMBBI) {
234 // Code Sequence:
235 // pcalau12i $rd, %ie_pc_hi20(sym)
236 // ld.w/d $rd, $rd, %ie_pc_lo12(sym)
238 const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
239 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
240 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_IE_PC_HI,
241 SecondOpcode, LoongArchII::MO_IE_PC_LO);
242}
243
244bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLD(
246 MachineBasicBlock::iterator &NextMBBI) {
247 // Code Sequence:
248 // pcalau12i $rd, %ld_pc_hi20(sym)
249 // addi.w/d $rd, $rd, %got_pc_lo12(sym)
251 const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
252 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
253 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_LD_PC_HI,
254 SecondOpcode, LoongArchII::MO_GOT_PC_LO);
255}
256
257bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD(
259 MachineBasicBlock::iterator &NextMBBI) {
260 // Code Sequence:
261 // pcalau12i $rd, %gd_pc_hi20(sym)
262 // addi.w/d $rd, $rd, %got_pc_lo12(sym)
264 const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
265 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
266 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_GD_PC_HI,
267 SecondOpcode, LoongArchII::MO_GOT_PC_LO);
268}
269
270class LoongArchExpandPseudo : public MachineFunctionPass {
271public:
272 const LoongArchInstrInfo *TII;
273 static char ID;
274
275 LoongArchExpandPseudo() : MachineFunctionPass(ID) {
277 }
278
279 bool runOnMachineFunction(MachineFunction &MF) override;
280
281 StringRef getPassName() const override {
283 }
284
285private:
286 bool expandMBB(MachineBasicBlock &MBB);
291 bool expandLargeAddressLoad(MachineBasicBlock &MBB,
294 unsigned LastOpcode, unsigned IdentifyingMO);
295 bool expandLargeAddressLoad(MachineBasicBlock &MBB,
298 unsigned LastOpcode, unsigned IdentifyingMO,
299 const MachineOperand &Symbol, Register DestReg,
300 bool EraseFromParent);
301 bool expandLoadAddressPcrelLarge(MachineBasicBlock &MBB,
304 bool expandLoadAddressGotLarge(MachineBasicBlock &MBB,
307 bool expandLoadAddressTLSIELarge(MachineBasicBlock &MBB,
310 bool expandLoadAddressTLSLDLarge(MachineBasicBlock &MBB,
313 bool expandLoadAddressTLSGDLarge(MachineBasicBlock &MBB,
316 bool expandFunctionCALL(MachineBasicBlock &MBB,
319 bool IsTailCall);
320};
321
322char LoongArchExpandPseudo::ID = 0;
323
324bool LoongArchExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
325 TII =
326 static_cast<const LoongArchInstrInfo *>(MF.getSubtarget().getInstrInfo());
327
328 bool Modified = false;
329 for (auto &MBB : MF)
330 Modified |= expandMBB(MBB);
331
332 return Modified;
333}
334
335bool LoongArchExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
336 bool Modified = false;
337
339 while (MBBI != E) {
340 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
341 Modified |= expandMI(MBB, MBBI, NMBBI);
342 MBBI = NMBBI;
343 }
344
345 return Modified;
346}
347
348bool LoongArchExpandPseudo::expandMI(MachineBasicBlock &MBB,
350 MachineBasicBlock::iterator &NextMBBI) {
351 switch (MBBI->getOpcode()) {
352 case LoongArch::PseudoCopyCFR:
353 return expandCopyCFR(MBB, MBBI, NextMBBI);
354 case LoongArch::PseudoLA_PCREL_LARGE:
355 return expandLoadAddressPcrelLarge(MBB, MBBI, NextMBBI);
356 case LoongArch::PseudoLA_GOT_LARGE:
357 return expandLoadAddressGotLarge(MBB, MBBI, NextMBBI);
358 case LoongArch::PseudoLA_TLS_IE_LARGE:
359 return expandLoadAddressTLSIELarge(MBB, MBBI, NextMBBI);
360 case LoongArch::PseudoLA_TLS_LD_LARGE:
361 return expandLoadAddressTLSLDLarge(MBB, MBBI, NextMBBI);
362 case LoongArch::PseudoLA_TLS_GD_LARGE:
363 return expandLoadAddressTLSGDLarge(MBB, MBBI, NextMBBI);
364 case LoongArch::PseudoCALL:
365 case LoongArch::PseudoCALL_MEDIUM:
366 case LoongArch::PseudoCALL_LARGE:
367 return expandFunctionCALL(MBB, MBBI, NextMBBI, /*IsTailCall=*/false);
368 case LoongArch::PseudoTAIL:
369 case LoongArch::PseudoTAIL_MEDIUM:
370 case LoongArch::PseudoTAIL_LARGE:
371 return expandFunctionCALL(MBB, MBBI, NextMBBI, /*IsTailCall=*/true);
372 }
373
374 return false;
375}
376
377bool LoongArchExpandPseudo::expandCopyCFR(
379 MachineBasicBlock::iterator &NextMBBI) {
381 MachineInstr &MI = *MBBI;
382 DebugLoc DL = MI.getDebugLoc();
383
384 // Expand:
385 // MBB:
386 // fcmp.caf.s $dst, $fa0, $fa0 # set $dst 0(false)
387 // bceqz $src, SinkBB
388 // FalseBB:
389 // fcmp.cueq.s $dst, $fa0, $fa0 # set $dst 1(true)
390 // SinkBB:
391 // fallthrough
392
393 const BasicBlock *LLVM_BB = MBB.getBasicBlock();
394 auto *FalseBB = MF->CreateMachineBasicBlock(LLVM_BB);
395 auto *SinkBB = MF->CreateMachineBasicBlock(LLVM_BB);
396
397 MF->insert(++MBB.getIterator(), FalseBB);
398 MF->insert(++FalseBB->getIterator(), SinkBB);
399
400 Register DestReg = MI.getOperand(0).getReg();
401 Register SrcReg = MI.getOperand(1).getReg();
402 // DestReg = 0
403 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::SET_CFR_FALSE), DestReg);
404 // Insert branch instruction.
405 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::BCEQZ))
406 .addReg(SrcReg)
407 .addMBB(SinkBB);
408 // DestReg = 1
409 BuildMI(FalseBB, DL, TII->get(LoongArch::SET_CFR_TRUE), DestReg);
410
411 FalseBB->addSuccessor(SinkBB);
412
413 SinkBB->splice(SinkBB->end(), &MBB, MI, MBB.end());
414 SinkBB->transferSuccessors(&MBB);
415
416 MBB.addSuccessor(FalseBB);
417 MBB.addSuccessor(SinkBB);
418
419 NextMBBI = MBB.end();
420 MI.eraseFromParent();
421
422 // Make sure live-ins are correctly attached to this new basic block.
423 LivePhysRegs LiveRegs;
424 computeAndAddLiveIns(LiveRegs, *FalseBB);
425 computeAndAddLiveIns(LiveRegs, *SinkBB);
426
427 return true;
428}
429
430bool LoongArchExpandPseudo::expandLargeAddressLoad(
432 MachineBasicBlock::iterator &NextMBBI, unsigned LastOpcode,
433 unsigned IdentifyingMO) {
434 MachineInstr &MI = *MBBI;
435 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LastOpcode, IdentifyingMO,
436 MI.getOperand(2), MI.getOperand(0).getReg(),
437 true);
438}
439
440bool LoongArchExpandPseudo::expandLargeAddressLoad(
442 MachineBasicBlock::iterator &NextMBBI, unsigned LastOpcode,
443 unsigned IdentifyingMO, const MachineOperand &Symbol, Register DestReg,
444 bool EraseFromParent) {
445 // Code Sequence:
446 //
447 // Part1: pcalau12i $dst, %MO1(sym)
448 // Part0: addi.d $t8, $zero, %MO0(sym)
449 // Part2: lu32i.d $t8, %MO2(sym)
450 // Part3: lu52i.d $t8, $t8, %MO3(sym)
451 // Fin: LastOpcode $dst, $t8, $dst
452
453 unsigned MO0, MO1, MO2, MO3;
454 switch (IdentifyingMO) {
455 default:
456 llvm_unreachable("unsupported identifying MO");
458 MO0 = IdentifyingMO;
462 break;
466 // These cases relocate just like the GOT case, except for Part1.
468 MO1 = IdentifyingMO;
471 break;
473 MO0 = IdentifyingMO;
477 break;
478 }
479
480 MachineInstr &MI = *MBBI;
481 DebugLoc DL = MI.getDebugLoc();
482 Register ScratchReg = LoongArch::R20; // $t8
483
485 "Large code model requires LA64");
486
487 auto Part1 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), DestReg);
488 auto Part0 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ADDI_D), ScratchReg)
489 .addReg(LoongArch::R0);
490 auto Part2 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU32I_D), ScratchReg)
491 // "rj" is needed due to InstrInfo pattern requirement.
492 .addReg(ScratchReg);
493 auto Part3 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU52I_D), ScratchReg)
494 .addReg(ScratchReg);
495 BuildMI(MBB, MBBI, DL, TII->get(LastOpcode), DestReg)
496 .addReg(ScratchReg)
497 .addReg(DestReg);
498
499 if (Symbol.getType() == MachineOperand::MO_ExternalSymbol) {
500 const char *SymName = Symbol.getSymbolName();
501 Part0.addExternalSymbol(SymName, MO0);
502 Part1.addExternalSymbol(SymName, MO1);
503 Part2.addExternalSymbol(SymName, MO2);
504 Part3.addExternalSymbol(SymName, MO3);
505 } else {
506 Part0.addDisp(Symbol, 0, MO0);
507 Part1.addDisp(Symbol, 0, MO1);
508 Part2.addDisp(Symbol, 0, MO2);
509 Part3.addDisp(Symbol, 0, MO3);
510 }
511
512 if (EraseFromParent)
513 MI.eraseFromParent();
514
515 return true;
516}
517
518bool LoongArchExpandPseudo::expandLoadAddressPcrelLarge(
520 MachineBasicBlock::iterator &NextMBBI) {
521 // Emit the 5-insn large address load sequence with the `%pc` family of
522 // relocs.
523 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::ADD_D,
525}
526
527bool LoongArchExpandPseudo::expandLoadAddressGotLarge(
529 MachineBasicBlock::iterator &NextMBBI) {
530 // Emit the 5-insn large address load sequence with the `%got_pc` family
531 // of relocs, loading the result from GOT with `ldx.d` in the end.
532 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::LDX_D,
534}
535
536bool LoongArchExpandPseudo::expandLoadAddressTLSIELarge(
538 MachineBasicBlock::iterator &NextMBBI) {
539 // Emit the 5-insn large address load sequence with the `%ie_pc` family
540 // of relocs, loading the result with `ldx.d` in the end.
541 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::LDX_D,
543}
544
545bool LoongArchExpandPseudo::expandLoadAddressTLSLDLarge(
547 MachineBasicBlock::iterator &NextMBBI) {
548 // Emit the 5-insn large address load sequence with the `%got_pc` family
549 // of relocs, with the `pcalau12i` insn relocated with `%ld_pc_hi20`.
550 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::ADD_D,
552}
553
554bool LoongArchExpandPseudo::expandLoadAddressTLSGDLarge(
556 MachineBasicBlock::iterator &NextMBBI) {
557 // Emit the 5-insn large address load sequence with the `%got_pc` family
558 // of relocs, with the `pcalau12i` insn relocated with `%gd_pc_hi20`.
559 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::ADD_D,
561}
562
563bool LoongArchExpandPseudo::expandFunctionCALL(
565 MachineBasicBlock::iterator &NextMBBI, bool IsTailCall) {
567 MachineInstr &MI = *MBBI;
568 DebugLoc DL = MI.getDebugLoc();
569 const MachineOperand &Func = MI.getOperand(0);
571 unsigned Opcode;
572
573 switch (MF->getTarget().getCodeModel()) {
574 default:
575 report_fatal_error("Unsupported code model");
576 break;
577 case CodeModel::Small: {
578 // CALL:
579 // bl func
580 // TAIL:
581 // b func
582 Opcode = IsTailCall ? LoongArch::PseudoB_TAIL : LoongArch::BL;
583 CALL = BuildMI(MBB, MBBI, DL, TII->get(Opcode)).add(Func);
584 break;
585 }
586 case CodeModel::Medium: {
587 // CALL:
588 // pcaddu18i $ra, %call36(func)
589 // jirl $ra, $ra, 0
590 // TAIL:
591 // pcaddu18i $t8, %call36(func)
592 // jr $t8
593 Opcode =
594 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
595 Register ScratchReg = IsTailCall ? LoongArch::R20 : LoongArch::R1;
597 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCADDU18I), ScratchReg);
598
599 CALL =
600 BuildMI(MBB, MBBI, DL, TII->get(Opcode)).addReg(ScratchReg).addImm(0);
601
602 if (Func.isSymbol())
603 MIB.addExternalSymbol(Func.getSymbolName(), LoongArchII::MO_CALL36);
604 else
605 MIB.addDisp(Func, 0, LoongArchII::MO_CALL36);
606 break;
607 }
608 case CodeModel::Large: {
609 // Emit the 5-insn large address load sequence, either directly or
610 // indirectly in case of going through the GOT, then JIRL_TAIL or
611 // JIRL_CALL to $addr.
612 Opcode =
613 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL;
614 Register AddrReg = IsTailCall ? LoongArch::R19 : LoongArch::R1;
615
616 bool UseGOT = Func.isGlobal() && !Func.getGlobal()->isDSOLocal();
618 unsigned LAOpcode = UseGOT ? LoongArch::LDX_D : LoongArch::ADD_D;
619 expandLargeAddressLoad(MBB, MBBI, NextMBBI, LAOpcode, MO, Func, AddrReg,
620 false);
621 CALL = BuildMI(MBB, MBBI, DL, TII->get(Opcode)).addReg(AddrReg).addImm(0);
622 break;
623 }
624 }
625
626 // Transfer implicit operands.
627 CALL.copyImplicitOps(MI);
628
629 // Transfer MI flags.
630 CALL.setMIFlags(MI.getFlags());
631
632 MI.eraseFromParent();
633 return true;
634}
635
636} // end namespace
637
638INITIALIZE_PASS(LoongArchPreRAExpandPseudo, "loongarch-prera-expand-pseudo",
640
641INITIALIZE_PASS(LoongArchExpandPseudo, "loongarch-expand-pseudo",
643
644namespace llvm {
645
647 return new LoongArchPreRAExpandPseudo();
648}
650 return new LoongArchExpandPseudo();
651}
652
653} // end namespace llvm
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Expected< BitVector > expand(StringRef S, StringRef Original)
Definition: GlobPattern.cpp:21
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
loongarch expand pseudo
#define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME
#define LOONGARCH_EXPAND_PSEUDO_NAME
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:269
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
A debug info location.
Definition: DebugLoc.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Definition: LivePhysRegs.h:50
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
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.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDisp(const MachineOperand &Disp, int64_t off, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Definition: MachineInstr.h:68
void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
MachineOperand class - Representation of each machine instruction operand.
@ MO_ExternalSymbol
Name of external global symbol.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
CodeModel::Model getCodeModel() const
Returns the code model.
virtual const TargetInstrInfo * getInstrInfo() const
self_iterator getIterator()
Definition: ilist_node.h:109
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
TargetPassConfig.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &)
void initializeLoongArchExpandPseudoPass(PassRegistry &)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
FunctionPass * createLoongArchPreRAExpandPseudoPass()
FunctionPass * createLoongArchExpandPseudoPass()
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().