Utils.cpp revision 327952
1//===- llvm/CodeGen/GlobalISel/Utils.cpp -------------------------*- C++ -*-==//
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/// \file This file implements the utility functions used by the GlobalISel
10/// pipeline.
11//===----------------------------------------------------------------------===//
12
13#include "llvm/CodeGen/GlobalISel/Utils.h"
14#include "llvm/ADT/Twine.h"
15#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
16#include "llvm/CodeGen/MachineInstr.h"
17#include "llvm/CodeGen/MachineInstrBuilder.h"
18#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
19#include "llvm/CodeGen/MachineRegisterInfo.h"
20#include "llvm/CodeGen/TargetInstrInfo.h"
21#include "llvm/CodeGen/TargetPassConfig.h"
22#include "llvm/CodeGen/TargetRegisterInfo.h"
23#include "llvm/IR/Constants.h"
24
25#define DEBUG_TYPE "globalisel-utils"
26
27using namespace llvm;
28
29unsigned llvm::constrainRegToClass(MachineRegisterInfo &MRI,
30                                   const TargetInstrInfo &TII,
31                                   const RegisterBankInfo &RBI,
32                                   MachineInstr &InsertPt, unsigned Reg,
33                                   const TargetRegisterClass &RegClass) {
34  if (!RBI.constrainGenericRegister(Reg, RegClass, MRI)) {
35    unsigned NewReg = MRI.createVirtualRegister(&RegClass);
36    BuildMI(*InsertPt.getParent(), InsertPt, InsertPt.getDebugLoc(),
37            TII.get(TargetOpcode::COPY), NewReg)
38        .addReg(Reg);
39    return NewReg;
40  }
41
42  return Reg;
43}
44
45
46unsigned llvm::constrainOperandRegClass(
47    const MachineFunction &MF, const TargetRegisterInfo &TRI,
48    MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
49    const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II,
50    unsigned Reg, unsigned OpIdx) {
51  // Assume physical registers are properly constrained.
52  assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
53         "PhysReg not implemented");
54
55  const TargetRegisterClass *RegClass = TII.getRegClass(II, OpIdx, &TRI, MF);
56  return constrainRegToClass(MRI, TII, RBI, InsertPt, Reg, *RegClass);
57}
58
59bool llvm::isTriviallyDead(const MachineInstr &MI,
60                           const MachineRegisterInfo &MRI) {
61  // If we can move an instruction, we can remove it.  Otherwise, it has
62  // a side-effect of some sort.
63  bool SawStore = false;
64  if (!MI.isSafeToMove(/*AA=*/nullptr, SawStore))
65    return false;
66
67  // Instructions without side-effects are dead iff they only define dead vregs.
68  for (auto &MO : MI.operands()) {
69    if (!MO.isReg() || !MO.isDef())
70      continue;
71
72    unsigned Reg = MO.getReg();
73    if (TargetRegisterInfo::isPhysicalRegister(Reg) ||
74        !MRI.use_nodbg_empty(Reg))
75      return false;
76  }
77  return true;
78}
79
80void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
81                              MachineOptimizationRemarkEmitter &MORE,
82                              MachineOptimizationRemarkMissed &R) {
83  MF.getProperties().set(MachineFunctionProperties::Property::FailedISel);
84
85  // Print the function name explicitly if we don't have a debug location (which
86  // makes the diagnostic less useful) or if we're going to emit a raw error.
87  if (!R.getLocation().isValid() || TPC.isGlobalISelAbortEnabled())
88    R << (" (in function: " + MF.getName() + ")").str();
89
90  if (TPC.isGlobalISelAbortEnabled())
91    report_fatal_error(R.getMsg());
92  else
93    MORE.emit(R);
94}
95
96void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
97                              MachineOptimizationRemarkEmitter &MORE,
98                              const char *PassName, StringRef Msg,
99                              const MachineInstr &MI) {
100  MachineOptimizationRemarkMissed R(PassName, "GISelFailure: ",
101                                    MI.getDebugLoc(), MI.getParent());
102  R << Msg;
103  // Printing MI is expensive;  only do it if expensive remarks are enabled.
104  if (MORE.allowExtraAnalysis(PassName))
105    R << ": " << ore::MNV("Inst", MI);
106  reportGISelFailure(MF, TPC, MORE, R);
107}
108
109Optional<int64_t> llvm::getConstantVRegVal(unsigned VReg,
110                                           const MachineRegisterInfo &MRI) {
111  MachineInstr *MI = MRI.getVRegDef(VReg);
112  if (MI->getOpcode() != TargetOpcode::G_CONSTANT)
113    return None;
114
115  if (MI->getOperand(1).isImm())
116    return MI->getOperand(1).getImm();
117
118  if (MI->getOperand(1).isCImm() &&
119      MI->getOperand(1).getCImm()->getBitWidth() <= 64)
120    return MI->getOperand(1).getCImm()->getSExtValue();
121
122  return None;
123}
124
125const llvm::ConstantFP* llvm::getConstantFPVRegVal(unsigned VReg,
126                                       const MachineRegisterInfo &MRI) {
127  MachineInstr *MI = MRI.getVRegDef(VReg);
128  if (TargetOpcode::G_FCONSTANT != MI->getOpcode())
129    return nullptr;
130  return MI->getOperand(1).getFPImm();
131}
132
133llvm::MachineInstr *llvm::getOpcodeDef(unsigned Opcode, unsigned Reg,
134                                       const MachineRegisterInfo &MRI) {
135  auto *DefMI = MRI.getVRegDef(Reg);
136  auto DstTy = MRI.getType(DefMI->getOperand(0).getReg());
137  if (!DstTy.isValid())
138    return nullptr;
139  while (DefMI->getOpcode() == TargetOpcode::COPY) {
140    unsigned SrcReg = DefMI->getOperand(1).getReg();
141    auto SrcTy = MRI.getType(SrcReg);
142    if (!SrcTy.isValid() || SrcTy != DstTy)
143      break;
144    DefMI = MRI.getVRegDef(SrcReg);
145  }
146  return DefMI->getOpcode() == Opcode ? DefMI : nullptr;
147}
148