1218885Sdim//===-- PHIEliminationUtils.cpp - Helper functions for PHI elimination ----===//
2218885Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6218885Sdim//
7218885Sdim//===----------------------------------------------------------------------===//
8218885Sdim
9218885Sdim#include "PHIEliminationUtils.h"
10249423Sdim#include "llvm/ADT/SmallPtrSet.h"
11218885Sdim#include "llvm/CodeGen/MachineBasicBlock.h"
12218885Sdim#include "llvm/CodeGen/MachineFunction.h"
13218885Sdim#include "llvm/CodeGen/MachineRegisterInfo.h"
14218885Sdimusing namespace llvm;
15218885Sdim
16218885Sdim// findCopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg
17218885Sdim// when following the CFG edge to SuccMBB. This needs to be after any def of
18218885Sdim// SrcReg, but before any subsequent point where control flow might jump out of
19218885Sdim// the basic block.
20218885SdimMachineBasicBlock::iterator
21218885Sdimllvm::findPHICopyInsertPoint(MachineBasicBlock* MBB, MachineBasicBlock* SuccMBB,
22218885Sdim                             unsigned SrcReg) {
23218885Sdim  // Handle the trivial case trivially.
24218885Sdim  if (MBB->empty())
25218885Sdim    return MBB->begin();
26218885Sdim
27218885Sdim  // Usually, we just want to insert the copy before the first terminator
28218885Sdim  // instruction. However, for the edge going to a landing pad, we must insert
29218885Sdim  // the copy before the call/invoke instruction.
30296417Sdim  if (!SuccMBB->isEHPad())
31218885Sdim    return MBB->getFirstTerminator();
32218885Sdim
33218885Sdim  // Discover any defs/uses in this basic block.
34218885Sdim  SmallPtrSet<MachineInstr*, 8> DefUsesInMBB;
35218885Sdim  MachineRegisterInfo& MRI = MBB->getParent()->getRegInfo();
36276479Sdim  for (MachineInstr &RI : MRI.reg_instructions(SrcReg)) {
37276479Sdim    if (RI.getParent() == MBB)
38276479Sdim      DefUsesInMBB.insert(&RI);
39218885Sdim  }
40218885Sdim
41218885Sdim  MachineBasicBlock::iterator InsertPoint;
42218885Sdim  if (DefUsesInMBB.empty()) {
43218885Sdim    // No defs.  Insert the copy at the start of the basic block.
44218885Sdim    InsertPoint = MBB->begin();
45218885Sdim  } else if (DefUsesInMBB.size() == 1) {
46218885Sdim    // Insert the copy immediately after the def/use.
47218885Sdim    InsertPoint = *DefUsesInMBB.begin();
48218885Sdim    ++InsertPoint;
49218885Sdim  } else {
50218885Sdim    // Insert the copy immediately after the last def/use.
51218885Sdim    InsertPoint = MBB->end();
52218885Sdim    while (!DefUsesInMBB.count(&*--InsertPoint)) {}
53218885Sdim    ++InsertPoint;
54218885Sdim  }
55218885Sdim
56314564Sdim  // Make sure the copy goes after any phi nodes but before
57314564Sdim  // any debug nodes.
58218885Sdim  return MBB->SkipPHIsAndLabels(InsertPoint);
59218885Sdim}
60