]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/SystemZ/SystemZPostRewrite.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / SystemZ / SystemZPostRewrite.cpp
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