1//===- RegisterCoalescer.h - Register Coalescing Interface ------*- 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 the abstract interface for register coalescers,
10// allowing them to interact with and query register allocators.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_CODEGEN_REGISTERCOALESCER_H
15#define LLVM_LIB_CODEGEN_REGISTERCOALESCER_H
16
17namespace llvm {
18
19class MachineInstr;
20class TargetRegisterClass;
21class TargetRegisterInfo;
22
23  /// A helper class for register coalescers. When deciding if
24  /// two registers can be coalesced, CoalescerPair can determine if a copy
25  /// instruction would become an identity copy after coalescing.
26  class CoalescerPair {
27    const TargetRegisterInfo &TRI;
28
29    /// The register that will be left after coalescing. It can be a
30    /// virtual or physical register.
31    unsigned DstReg = 0;
32
33    /// The virtual register that will be coalesced into dstReg.
34    unsigned SrcReg = 0;
35
36    /// The sub-register index of the old DstReg in the new coalesced register.
37    unsigned DstIdx = 0;
38
39    /// The sub-register index of the old SrcReg in the new coalesced register.
40    unsigned SrcIdx = 0;
41
42    /// True when the original copy was a partial subregister copy.
43    bool Partial = false;
44
45    /// True when both regs are virtual and newRC is constrained.
46    bool CrossClass = false;
47
48    /// True when DstReg and SrcReg are reversed from the original
49    /// copy instruction.
50    bool Flipped = false;
51
52    /// The register class of the coalesced register, or NULL if DstReg
53    /// is a physreg. This register class may be a super-register of both
54    /// SrcReg and DstReg.
55    const TargetRegisterClass *NewRC = nullptr;
56
57  public:
58    CoalescerPair(const TargetRegisterInfo &tri) : TRI(tri) {}
59
60    /// Create a CoalescerPair representing a virtreg-to-physreg copy.
61    /// No need to call setRegisters().
62    CoalescerPair(unsigned VirtReg, unsigned PhysReg,
63                  const TargetRegisterInfo &tri)
64      : TRI(tri), DstReg(PhysReg), SrcReg(VirtReg) {}
65
66    /// Set registers to match the copy instruction MI. Return
67    /// false if MI is not a coalescable copy instruction.
68    bool setRegisters(const MachineInstr*);
69
70    /// Swap SrcReg and DstReg. Return false if swapping is impossible
71    /// because DstReg is a physical register, or SubIdx is set.
72    bool flip();
73
74    /// Return true if MI is a copy instruction that will become
75    /// an identity copy after coalescing.
76    bool isCoalescable(const MachineInstr*) const;
77
78    /// Return true if DstReg is a physical register.
79    bool isPhys() const { return !NewRC; }
80
81    /// Return true if the original copy instruction did not copy
82    /// the full register, but was a subreg operation.
83    bool isPartial() const { return Partial; }
84
85    /// Return true if DstReg is virtual and NewRC is a smaller
86    /// register class than DstReg's.
87    bool isCrossClass() const { return CrossClass; }
88
89    /// Return true when getSrcReg is the register being defined by
90    /// the original copy instruction.
91    bool isFlipped() const { return Flipped; }
92
93    /// Return the register (virtual or physical) that will remain
94    /// after coalescing.
95    unsigned getDstReg() const { return DstReg; }
96
97    /// Return the virtual register that will be coalesced away.
98    unsigned getSrcReg() const { return SrcReg; }
99
100    /// Return the subregister index that DstReg will be coalesced into, or 0.
101    unsigned getDstIdx() const { return DstIdx; }
102
103    /// Return the subregister index that SrcReg will be coalesced into, or 0.
104    unsigned getSrcIdx() const { return SrcIdx; }
105
106    /// Return the register class of the coalesced register.
107    const TargetRegisterClass *getNewRC() const { return NewRC; }
108  };
109
110} // end namespace llvm
111
112#endif // LLVM_LIB_CODEGEN_REGISTERCOALESCER_H
113