xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZPostRewrite.cpp (revision 2f513db72b034fd5ef7f080b11be5c711c15186a)
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