1//===-- ExpandPostRAPseudos.cpp - Pseudo instruction expansion pass -------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a pass that expands COPY and SUBREG_TO_REG pseudo
11// instructions after register allocation.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/CodeGen/Passes.h"
16#include "llvm/CodeGen/MachineFunctionPass.h"
17#include "llvm/CodeGen/MachineInstr.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/CodeGen/MachineRegisterInfo.h"
20#include "llvm/Support/Debug.h"
21#include "llvm/Support/raw_ostream.h"
22#include "llvm/Target/TargetInstrInfo.h"
23#include "llvm/Target/TargetMachine.h"
24#include "llvm/Target/TargetRegisterInfo.h"
25using namespace llvm;
26
27#define DEBUG_TYPE "postrapseudos"
28
29namespace {
30struct ExpandPostRA : public MachineFunctionPass {
31private:
32  const TargetRegisterInfo *TRI;
33  const TargetInstrInfo *TII;
34
35public:
36  static char ID; // Pass identification, replacement for typeid
37  ExpandPostRA() : MachineFunctionPass(ID) {}
38
39  void getAnalysisUsage(AnalysisUsage &AU) const override {
40    AU.setPreservesCFG();
41    AU.addPreservedID(MachineLoopInfoID);
42    AU.addPreservedID(MachineDominatorsID);
43    MachineFunctionPass::getAnalysisUsage(AU);
44  }
45
46  /// runOnMachineFunction - pass entry point
47  bool runOnMachineFunction(MachineFunction&) override;
48
49private:
50  bool LowerSubregToReg(MachineInstr *MI);
51  bool LowerCopy(MachineInstr *MI);
52
53  void TransferImplicitDefs(MachineInstr *MI);
54};
55} // end anonymous namespace
56
57char ExpandPostRA::ID = 0;
58char &llvm::ExpandPostRAPseudosID = ExpandPostRA::ID;
59
60INITIALIZE_PASS(ExpandPostRA, "postrapseudos",
61                "Post-RA pseudo instruction expansion pass", false, false)
62
63/// TransferImplicitDefs - MI is a pseudo-instruction, and the lowered
64/// replacement instructions immediately precede it.  Copy any implicit-def
65/// operands from MI to the replacement instruction.
66void
67ExpandPostRA::TransferImplicitDefs(MachineInstr *MI) {
68  MachineBasicBlock::iterator CopyMI = MI;
69  --CopyMI;
70
71  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
72    MachineOperand &MO = MI->getOperand(i);
73    if (!MO.isReg() || !MO.isImplicit() || MO.isUse())
74      continue;
75    CopyMI->addOperand(MachineOperand::CreateReg(MO.getReg(), true, true));
76  }
77}
78
79bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) {
80  MachineBasicBlock *MBB = MI->getParent();
81  assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) &&
82         MI->getOperand(1).isImm() &&
83         (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) &&
84          MI->getOperand(3).isImm() && "Invalid subreg_to_reg");
85
86  unsigned DstReg  = MI->getOperand(0).getReg();
87  unsigned InsReg  = MI->getOperand(2).getReg();
88  assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?");
89  unsigned SubIdx  = MI->getOperand(3).getImm();
90
91  assert(SubIdx != 0 && "Invalid index for insert_subreg");
92  unsigned DstSubReg = TRI->getSubReg(DstReg, SubIdx);
93
94  assert(TargetRegisterInfo::isPhysicalRegister(DstReg) &&
95         "Insert destination must be in a physical register");
96  assert(TargetRegisterInfo::isPhysicalRegister(InsReg) &&
97         "Inserted value must be in a physical register");
98
99  DEBUG(dbgs() << "subreg: CONVERTING: " << *MI);
100
101  if (MI->allDefsAreDead()) {
102    MI->setDesc(TII->get(TargetOpcode::KILL));
103    DEBUG(dbgs() << "subreg: replaced by: " << *MI);
104    return true;
105  }
106
107  if (DstSubReg == InsReg) {
108    // No need to insert an identity copy instruction.
109    // Watch out for case like this:
110    // %RAX<def> = SUBREG_TO_REG 0, %EAX<kill>, 3
111    // We must leave %RAX live.
112    if (DstReg != InsReg) {
113      MI->setDesc(TII->get(TargetOpcode::KILL));
114      MI->RemoveOperand(3);     // SubIdx
115      MI->RemoveOperand(1);     // Imm
116      DEBUG(dbgs() << "subreg: replace by: " << *MI);
117      return true;
118    }
119    DEBUG(dbgs() << "subreg: eliminated!");
120  } else {
121    TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg,
122                     MI->getOperand(2).isKill());
123
124    // Implicitly define DstReg for subsequent uses.
125    MachineBasicBlock::iterator CopyMI = MI;
126    --CopyMI;
127    CopyMI->addRegisterDefined(DstReg);
128    DEBUG(dbgs() << "subreg: " << *CopyMI);
129  }
130
131  DEBUG(dbgs() << '\n');
132  MBB->erase(MI);
133  return true;
134}
135
136bool ExpandPostRA::LowerCopy(MachineInstr *MI) {
137
138  if (MI->allDefsAreDead()) {
139    DEBUG(dbgs() << "dead copy: " << *MI);
140    MI->setDesc(TII->get(TargetOpcode::KILL));
141    DEBUG(dbgs() << "replaced by: " << *MI);
142    return true;
143  }
144
145  MachineOperand &DstMO = MI->getOperand(0);
146  MachineOperand &SrcMO = MI->getOperand(1);
147
148  if (SrcMO.getReg() == DstMO.getReg()) {
149    DEBUG(dbgs() << "identity copy: " << *MI);
150    // No need to insert an identity copy instruction, but replace with a KILL
151    // if liveness is changed.
152    if (SrcMO.isUndef() || MI->getNumOperands() > 2) {
153      // We must make sure the super-register gets killed. Replace the
154      // instruction with KILL.
155      MI->setDesc(TII->get(TargetOpcode::KILL));
156      DEBUG(dbgs() << "replaced by:   " << *MI);
157      return true;
158    }
159    // Vanilla identity copy.
160    MI->eraseFromParent();
161    return true;
162  }
163
164  DEBUG(dbgs() << "real copy:   " << *MI);
165  TII->copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(),
166                   DstMO.getReg(), SrcMO.getReg(), SrcMO.isKill());
167
168  if (MI->getNumOperands() > 2)
169    TransferImplicitDefs(MI);
170  DEBUG({
171    MachineBasicBlock::iterator dMI = MI;
172    dbgs() << "replaced by: " << *(--dMI);
173  });
174  MI->eraseFromParent();
175  return true;
176}
177
178/// runOnMachineFunction - Reduce subregister inserts and extracts to register
179/// copies.
180///
181bool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) {
182  DEBUG(dbgs() << "Machine Function\n"
183               << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n"
184               << "********** Function: " << MF.getName() << '\n');
185  TRI = MF.getTarget().getRegisterInfo();
186  TII = MF.getTarget().getInstrInfo();
187
188  bool MadeChange = false;
189
190  for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end();
191       mbbi != mbbe; ++mbbi) {
192    for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end();
193         mi != me;) {
194      MachineInstr *MI = mi;
195      // Advance iterator here because MI may be erased.
196      ++mi;
197
198      // Only expand pseudos.
199      if (!MI->isPseudo())
200        continue;
201
202      // Give targets a chance to expand even standard pseudos.
203      if (TII->expandPostRAPseudo(MI)) {
204        MadeChange = true;
205        continue;
206      }
207
208      // Expand standard pseudos.
209      switch (MI->getOpcode()) {
210      case TargetOpcode::SUBREG_TO_REG:
211        MadeChange |= LowerSubregToReg(MI);
212        break;
213      case TargetOpcode::COPY:
214        MadeChange |= LowerCopy(MI);
215        break;
216      case TargetOpcode::DBG_VALUE:
217        continue;
218      case TargetOpcode::INSERT_SUBREG:
219      case TargetOpcode::EXTRACT_SUBREG:
220        llvm_unreachable("Sub-register pseudos should have been eliminated.");
221      }
222    }
223  }
224
225  return MadeChange;
226}
227