1 //==---- SystemZPostRewrite.cpp - Select pseudos after RegAlloc ---*- C++ -*-=// 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 is run immediately after VirtRegRewriter 10 // but before MachineCopyPropagation. The purpose is to lower pseudos to 11 // target instructions before any later pass might substitute a register for 12 // another. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "SystemZ.h" 17 #include "SystemZInstrInfo.h" 18 #include "SystemZSubtarget.h" 19 #include "llvm/ADT/Statistic.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/CodeGen/MachineInstrBuilder.h" 22 using namespace llvm; 23 24 #define SYSTEMZ_POSTREWRITE_NAME "SystemZ Post Rewrite pass" 25 26 #define DEBUG_TYPE "systemz-postrewrite" 27 STATISTIC(MemFoldCopies, "Number of copies inserted before folded mem ops."); 28 29 namespace llvm { 30 void initializeSystemZPostRewritePass(PassRegistry&); 31 } 32 33 namespace { 34 35 class SystemZPostRewrite : public MachineFunctionPass { 36 public: 37 static char ID; 38 SystemZPostRewrite() : MachineFunctionPass(ID) { 39 initializeSystemZPostRewritePass(*PassRegistry::getPassRegistry()); 40 } 41 42 const SystemZInstrInfo *TII; 43 44 bool runOnMachineFunction(MachineFunction &Fn) override; 45 46 StringRef getPassName() const override { return SYSTEMZ_POSTREWRITE_NAME; } 47 48 void getAnalysisUsage(AnalysisUsage &AU) const override { 49 AU.setPreservesAll(); 50 MachineFunctionPass::getAnalysisUsage(AU); 51 } 52 53 private: 54 bool selectMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 55 MachineBasicBlock::iterator &NextMBBI); 56 bool selectMBB(MachineBasicBlock &MBB); 57 }; 58 59 char SystemZPostRewrite::ID = 0; 60 61 } // end anonymous namespace 62 63 INITIALIZE_PASS(SystemZPostRewrite, "systemz-post-rewrite", 64 SYSTEMZ_POSTREWRITE_NAME, false, false) 65 66 /// Returns an instance of the Post Rewrite pass. 67 FunctionPass *llvm::createSystemZPostRewritePass(SystemZTargetMachine &TM) { 68 return new SystemZPostRewrite(); 69 } 70 71 /// If MBBI references a pseudo instruction that should be selected here, 72 /// do it and return true. Otherwise return false. 73 bool SystemZPostRewrite::selectMI(MachineBasicBlock &MBB, 74 MachineBasicBlock::iterator MBBI, 75 MachineBasicBlock::iterator &NextMBBI) { 76 MachineInstr &MI = *MBBI; 77 unsigned Opcode = MI.getOpcode(); 78 79 // Note: If this could be done during regalloc in foldMemoryOperandImpl() 80 // while also updating the LiveIntervals, there would be no need for the 81 // MemFoldPseudo to begin with. 82 int TargetMemOpcode = SystemZ::getTargetMemOpcode(Opcode); 83 if (TargetMemOpcode != -1) { 84 MI.setDesc(TII->get(TargetMemOpcode)); 85 MI.tieOperands(0, 1); 86 unsigned DstReg = MI.getOperand(0).getReg(); 87 MachineOperand &SrcMO = MI.getOperand(1); 88 if (DstReg != SrcMO.getReg()) { 89 BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(SystemZ::COPY), DstReg) 90 .addReg(SrcMO.getReg()); 91 SrcMO.setReg(DstReg); 92 MemFoldCopies++; 93 } 94 return true; 95 } 96 97 return false; 98 } 99 100 /// Iterate over the instructions in basic block MBB and select any 101 /// pseudo instructions. Return true if anything was modified. 102 bool SystemZPostRewrite::selectMBB(MachineBasicBlock &MBB) { 103 bool Modified = false; 104 105 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 106 while (MBBI != E) { 107 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 108 Modified |= selectMI(MBB, MBBI, NMBBI); 109 MBBI = NMBBI; 110 } 111 112 return Modified; 113 } 114 115 bool SystemZPostRewrite::runOnMachineFunction(MachineFunction &MF) { 116 TII = static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo()); 117 118 bool Modified = false; 119 for (auto &MBB : MF) 120 Modified |= selectMBB(MBB); 121 122 return Modified; 123 } 124 125