@@ -29,6 +29,8 @@ using namespace llvm;
2929
3030#define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME \
3131 " LoongArch Pre-RA pseudo instruction expansion pass"
32+ #define LOONGARCH_EXPAND_PSEUDO_NAME \
33+ " LoongArch pseudo instruction expansion pass"
3234
3335namespace {
3436
@@ -513,15 +515,134 @@ bool LoongArchPreRAExpandPseudo::expandFunctionCALL(
513515 return true ;
514516}
515517
518+ class LoongArchExpandPseudo : public MachineFunctionPass {
519+ public:
520+ const LoongArchInstrInfo *TII;
521+ static char ID;
522+
523+ LoongArchExpandPseudo () : MachineFunctionPass(ID) {
524+ initializeLoongArchExpandPseudoPass (*PassRegistry::getPassRegistry ());
525+ }
526+
527+ bool runOnMachineFunction (MachineFunction &MF) override ;
528+
529+ StringRef getPassName () const override {
530+ return LOONGARCH_EXPAND_PSEUDO_NAME;
531+ }
532+
533+ private:
534+ bool expandMBB (MachineBasicBlock &MBB);
535+ bool expandMI (MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
536+ MachineBasicBlock::iterator &NextMBBI);
537+ bool expandCopyCFR (MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
538+ MachineBasicBlock::iterator &NextMBBI);
539+ };
540+
541+ char LoongArchExpandPseudo::ID = 0 ;
542+
543+ bool LoongArchExpandPseudo::runOnMachineFunction (MachineFunction &MF) {
544+ TII =
545+ static_cast <const LoongArchInstrInfo *>(MF.getSubtarget ().getInstrInfo ());
546+
547+ bool Modified = false ;
548+ for (auto &MBB : MF)
549+ Modified |= expandMBB (MBB);
550+
551+ return Modified;
552+ }
553+
554+ bool LoongArchExpandPseudo::expandMBB (MachineBasicBlock &MBB) {
555+ bool Modified = false ;
556+
557+ MachineBasicBlock::iterator MBBI = MBB.begin (), E = MBB.end ();
558+ while (MBBI != E) {
559+ MachineBasicBlock::iterator NMBBI = std::next (MBBI);
560+ Modified |= expandMI (MBB, MBBI, NMBBI);
561+ MBBI = NMBBI;
562+ }
563+
564+ return Modified;
565+ }
566+
567+ bool LoongArchExpandPseudo::expandMI (MachineBasicBlock &MBB,
568+ MachineBasicBlock::iterator MBBI,
569+ MachineBasicBlock::iterator &NextMBBI) {
570+ switch (MBBI->getOpcode ()) {
571+ case LoongArch::PseudoCopyCFR:
572+ return expandCopyCFR (MBB, MBBI, NextMBBI);
573+ }
574+
575+ return false ;
576+ }
577+
578+ bool LoongArchExpandPseudo::expandCopyCFR (
579+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
580+ MachineBasicBlock::iterator &NextMBBI) {
581+ MachineFunction *MF = MBB.getParent ();
582+ MachineInstr &MI = *MBBI;
583+ DebugLoc DL = MI.getDebugLoc ();
584+
585+ // Expand:
586+ // MBB:
587+ // fcmp.caf.s $dst, $fa0, $fa0 # set $dst 0(false)
588+ // bceqz $src, SinkBB
589+ // FalseBB:
590+ // fcmp.cueq.s $dst, $fa0, $fa0 # set $dst 1(true)
591+ // SinkBB:
592+ // fallthrough
593+
594+ const BasicBlock *LLVM_BB = MBB.getBasicBlock ();
595+ auto *FalseBB = MF->CreateMachineBasicBlock (LLVM_BB);
596+ auto *SinkBB = MF->CreateMachineBasicBlock (LLVM_BB);
597+
598+ MF->insert (++MBB.getIterator (), FalseBB);
599+ MF->insert (++FalseBB->getIterator (), SinkBB);
600+
601+ Register DestReg = MI.getOperand (0 ).getReg ();
602+ Register SrcReg = MI.getOperand (1 ).getReg ();
603+ // DestReg = 0
604+ BuildMI (MBB, MBBI, DL, TII->get (LoongArch::SET_CFR_FALSE), DestReg);
605+ // Insert branch instruction.
606+ BuildMI (MBB, MBBI, DL, TII->get (LoongArch::BCEQZ))
607+ .addReg (SrcReg)
608+ .addMBB (SinkBB);
609+ // DestReg = 1
610+ BuildMI (FalseBB, DL, TII->get (LoongArch::SET_CFR_TRUE), DestReg);
611+
612+ FalseBB->addSuccessor (SinkBB);
613+
614+ SinkBB->splice (SinkBB->end (), &MBB, MI, MBB.end ());
615+ SinkBB->transferSuccessors (&MBB);
616+
617+ MBB.addSuccessor (FalseBB);
618+ MBB.addSuccessor (SinkBB);
619+
620+ NextMBBI = MBB.end ();
621+ MI.eraseFromParent ();
622+
623+ // Make sure live-ins are correctly attached to this new basic block.
624+ LivePhysRegs LiveRegs;
625+ computeAndAddLiveIns (LiveRegs, *FalseBB);
626+ computeAndAddLiveIns (LiveRegs, *SinkBB);
627+
628+ return true ;
629+ }
630+
516631} // end namespace
517632
518633INITIALIZE_PASS (LoongArchPreRAExpandPseudo, " loongarch-prera-expand-pseudo" ,
519634 LOONGARCH_PRERA_EXPAND_PSEUDO_NAME, false , false )
520635
636+ INITIALIZE_PASS(LoongArchExpandPseudo, " loongarch-expand-pseudo" ,
637+ LOONGARCH_EXPAND_PSEUDO_NAME, false , false )
638+
521639namespace llvm {
522640
523641FunctionPass *createLoongArchPreRAExpandPseudoPass () {
524642 return new LoongArchPreRAExpandPseudo ();
525643}
644+ FunctionPass *createLoongArchExpandPseudoPass () {
645+ return new LoongArchExpandPseudo ();
646+ }
526647
527648} // end namespace llvm
0 commit comments