ProcessImplicitDefs.cpp revision 355940
1251241Sdas//===---------------------- ProcessImplicitDefs.cpp -----------------------===//
2251241Sdas//
3251241Sdas// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4251241Sdas// See https://llvm.org/LICENSE.txt for license information.
5251241Sdas// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6251241Sdas//
7251241Sdas//===----------------------------------------------------------------------===//
8251241Sdas
9251241Sdas#include "llvm/ADT/SetVector.h"
10251241Sdas#include "llvm/Analysis/AliasAnalysis.h"
11251241Sdas#include "llvm/CodeGen/MachineFunctionPass.h"
12251241Sdas#include "llvm/CodeGen/MachineInstr.h"
13251241Sdas#include "llvm/CodeGen/MachineRegisterInfo.h"
14251241Sdas#include "llvm/CodeGen/Passes.h"
15251241Sdas#include "llvm/CodeGen/TargetInstrInfo.h"
16251241Sdas#include "llvm/CodeGen/TargetSubtargetInfo.h"
17251241Sdas#include "llvm/Support/Debug.h"
18251241Sdas#include "llvm/Support/raw_ostream.h"
19251241Sdas
20251241Sdasusing namespace llvm;
21251241Sdas
22251241Sdas#define DEBUG_TYPE "processimpdefs"
23251241Sdas
24251241Sdasnamespace {
25251241Sdas/// Process IMPLICIT_DEF instructions and make sure there is one implicit_def
26251241Sdas/// for each use. Add isUndef marker to implicit_def defs and their uses.
27251241Sdasclass ProcessImplicitDefs : public MachineFunctionPass {
28251241Sdas  const TargetInstrInfo *TII;
29251241Sdas  const TargetRegisterInfo *TRI;
30251241Sdas  MachineRegisterInfo *MRI;
31251241Sdas
32251241Sdas  SmallSetVector<MachineInstr*, 16> WorkList;
33251241Sdas
34251241Sdas  void processImplicitDef(MachineInstr *MI);
35251241Sdas  bool canTurnIntoImplicitDef(MachineInstr *MI);
36251241Sdas
37251241Sdaspublic:
38251241Sdas  static char ID;
39251241Sdas
40251241Sdas  ProcessImplicitDefs() : MachineFunctionPass(ID) {
41251241Sdas    initializeProcessImplicitDefsPass(*PassRegistry::getPassRegistry());
42251241Sdas  }
43251241Sdas
44251241Sdas  void getAnalysisUsage(AnalysisUsage &au) const override;
45251241Sdas
46251241Sdas  bool runOnMachineFunction(MachineFunction &MF) override;
47251241Sdas};
48251241Sdas} // end anonymous namespace
49251241Sdas
50251241Sdaschar ProcessImplicitDefs::ID = 0;
51251241Sdaschar &llvm::ProcessImplicitDefsID = ProcessImplicitDefs::ID;
52251241Sdas
53251241SdasINITIALIZE_PASS(ProcessImplicitDefs, DEBUG_TYPE,
54251241Sdas                "Process Implicit Definitions", false, false)
55251241Sdas
56251241Sdasvoid ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const {
57251241Sdas  AU.setPreservesCFG();
58251241Sdas  AU.addPreserved<AAResultsWrapperPass>();
59251241Sdas  MachineFunctionPass::getAnalysisUsage(AU);
60251241Sdas}
61251241Sdas
62251241Sdasbool ProcessImplicitDefs::canTurnIntoImplicitDef(MachineInstr *MI) {
63251241Sdas  if (!MI->isCopyLike() &&
64251241Sdas      !MI->isInsertSubreg() &&
65251241Sdas      !MI->isRegSequence() &&
66251241Sdas      !MI->isPHI())
67251241Sdas    return false;
68251241Sdas  for (const MachineOperand &MO : MI->operands())
69251241Sdas    if (MO.isReg() && MO.isUse() && MO.readsReg())
70251241Sdas      return false;
71251241Sdas  return true;
72251241Sdas}
73251241Sdas
74251241Sdasvoid ProcessImplicitDefs::processImplicitDef(MachineInstr *MI) {
75251241Sdas  LLVM_DEBUG(dbgs() << "Processing " << *MI);
76251241Sdas  unsigned Reg = MI->getOperand(0).getReg();
77251241Sdas
78251241Sdas  if (TargetRegisterInfo::isVirtualRegister(Reg)) {
79251241Sdas    // For virtual registers, mark all uses as <undef>, and convert users to
80251241Sdas    // implicit-def when possible.
81251241Sdas    for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
82251241Sdas      MO.setIsUndef();
83251241Sdas      MachineInstr *UserMI = MO.getParent();
84251241Sdas      if (!canTurnIntoImplicitDef(UserMI))
85251241Sdas        continue;
86251241Sdas      LLVM_DEBUG(dbgs() << "Converting to IMPLICIT_DEF: " << *UserMI);
87251241Sdas      UserMI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF));
88251241Sdas      WorkList.insert(UserMI);
89251241Sdas    }
90251241Sdas    MI->eraseFromParent();
91251241Sdas    return;
92251241Sdas  }
93251241Sdas
94251241Sdas  // This is a physreg implicit-def.
95251241Sdas  // Look for the first instruction to use or define an alias.
96251241Sdas  MachineBasicBlock::instr_iterator UserMI = MI->getIterator();
97251241Sdas  MachineBasicBlock::instr_iterator UserE = MI->getParent()->instr_end();
98251241Sdas  bool Found = false;
99251241Sdas  for (++UserMI; UserMI != UserE; ++UserMI) {
100251241Sdas    for (MachineOperand &MO : UserMI->operands()) {
101251241Sdas      if (!MO.isReg())
102251241Sdas        continue;
103251241Sdas      unsigned UserReg = MO.getReg();
104251241Sdas      if (!TargetRegisterInfo::isPhysicalRegister(UserReg) ||
105251241Sdas          !TRI->regsOverlap(Reg, UserReg))
106251241Sdas        continue;
107251241Sdas      // UserMI uses or redefines Reg. Set <undef> flags on all uses.
108251241Sdas      Found = true;
109251241Sdas      if (MO.isUse())
110251241Sdas        MO.setIsUndef();
111251241Sdas    }
112251241Sdas    if (Found)
113251241Sdas      break;
114251241Sdas  }
115251241Sdas
116251241Sdas  // If we found the using MI, we can erase the IMPLICIT_DEF.
117251241Sdas  if (Found) {
118251241Sdas    LLVM_DEBUG(dbgs() << "Physreg user: " << *UserMI);
119251241Sdas    MI->eraseFromParent();
120251241Sdas    return;
121251241Sdas  }
122251241Sdas
123251241Sdas  // Using instr wasn't found, it could be in another block.
124251241Sdas  // Leave the physreg IMPLICIT_DEF, but trim any extra operands.
125251241Sdas  for (unsigned i = MI->getNumOperands() - 1; i; --i)
126251241Sdas    MI->RemoveOperand(i);
127251241Sdas  LLVM_DEBUG(dbgs() << "Keeping physreg: " << *MI);
128251241Sdas}
129251241Sdas
130251241Sdas/// processImplicitDefs - Process IMPLICIT_DEF instructions and turn them into
131251241Sdas/// <undef> operands.
132251241Sdasbool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &MF) {
133251241Sdas
134251241Sdas  LLVM_DEBUG(dbgs() << "********** PROCESS IMPLICIT DEFS **********\n"
135251241Sdas                    << "********** Function: " << MF.getName() << '\n');
136251241Sdas
137251241Sdas  bool Changed = false;
138251241Sdas
139251241Sdas  TII = MF.getSubtarget().getInstrInfo();
140251241Sdas  TRI = MF.getSubtarget().getRegisterInfo();
141251241Sdas  MRI = &MF.getRegInfo();
142251241Sdas  assert(MRI->isSSA() && "ProcessImplicitDefs only works on SSA form.");
143251241Sdas  assert(WorkList.empty() && "Inconsistent worklist state");
144251241Sdas
145251241Sdas  for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end();
146251241Sdas       MFI != MFE; ++MFI) {
147251241Sdas    // Scan the basic block for implicit defs.
148251241Sdas    for (MachineBasicBlock::instr_iterator MBBI = MFI->instr_begin(),
149251241Sdas         MBBE = MFI->instr_end(); MBBI != MBBE; ++MBBI)
150251241Sdas      if (MBBI->isImplicitDef())
151251241Sdas        WorkList.insert(&*MBBI);
152251241Sdas
153251241Sdas    if (WorkList.empty())
154251241Sdas      continue;
155251241Sdas
156251241Sdas    LLVM_DEBUG(dbgs() << printMBBReference(*MFI) << " has " << WorkList.size()
157251241Sdas                      << " implicit defs.\n");
158251241Sdas    Changed = true;
159251241Sdas
160251241Sdas    // Drain the WorkList to recursively process any new implicit defs.
161251241Sdas    do processImplicitDef(WorkList.pop_back_val());
162251241Sdas    while (!WorkList.empty());
163251241Sdas  }
164251241Sdas  return Changed;
165251241Sdas}
166251241Sdas