blob: 7a64d674ecac013fec6d3e91ed675645eb8d2305 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- llvm/CodeGen/VirtRegMap.h - Virtual Register Map ---------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements a virtual register map. This maps virtual registers to
10// physical registers and virtual registers to stack slots. It is created and
11// updated by a register allocator and then used by a machine code rewriter that
12// adds spill code and rewrites virtual into physical register references.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CODEGEN_VIRTREGMAP_H
17#define LLVM_CODEGEN_VIRTREGMAP_H
18
19#include "llvm/ADT/IndexedMap.h"
20#include "llvm/CodeGen/MachineFunctionPass.h"
21#include "llvm/CodeGen/TargetRegisterInfo.h"
22#include "llvm/MC/MCRegisterInfo.h"
23#include "llvm/Pass.h"
24#include <cassert>
25
26namespace llvm {
27
28class MachineFunction;
29class MachineRegisterInfo;
30class raw_ostream;
31class TargetInstrInfo;
32
33 class VirtRegMap : public MachineFunctionPass {
34 public:
35 enum {
36 NO_PHYS_REG = 0,
37 NO_STACK_SLOT = (1L << 30)-1,
38 MAX_STACK_SLOT = (1L << 18)-1
39 };
40
41 private:
42 MachineRegisterInfo *MRI;
43 const TargetInstrInfo *TII;
44 const TargetRegisterInfo *TRI;
45 MachineFunction *MF;
46
47 /// Virt2PhysMap - This is a virtual to physical register
48 /// mapping. Each virtual register is required to have an entry in
49 /// it; even spilled virtual registers (the register mapped to a
50 /// spilled register is the temporary used to load it from the
51 /// stack).
52 IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap;
53
54 /// Virt2StackSlotMap - This is virtual register to stack slot
55 /// mapping. Each spilled virtual register has an entry in it
56 /// which corresponds to the stack slot this register is spilled
57 /// at.
58 IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
59
60 /// Virt2SplitMap - This is virtual register to splitted virtual register
61 /// mapping.
62 IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap;
63
64 /// createSpillSlot - Allocate a spill slot for RC from MFI.
65 unsigned createSpillSlot(const TargetRegisterClass *RC);
66
67 public:
68 static char ID;
69
70 VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG),
71 Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) {}
72 VirtRegMap(const VirtRegMap &) = delete;
73 VirtRegMap &operator=(const VirtRegMap &) = delete;
74
75 bool runOnMachineFunction(MachineFunction &MF) override;
76
77 void getAnalysisUsage(AnalysisUsage &AU) const override {
78 AU.setPreservesAll();
79 MachineFunctionPass::getAnalysisUsage(AU);
80 }
81
82 MachineFunction &getMachineFunction() const {
83 assert(MF && "getMachineFunction called before runOnMachineFunction");
84 return *MF;
85 }
86
87 MachineRegisterInfo &getRegInfo() const { return *MRI; }
88 const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; }
89
90 void grow();
91
Andrew Scullcdfcccc2018-10-05 20:58:37 +010092 /// returns true if the specified virtual register is
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010093 /// mapped to a physical register
94 bool hasPhys(unsigned virtReg) const {
95 return getPhys(virtReg) != NO_PHYS_REG;
96 }
97
Andrew Scullcdfcccc2018-10-05 20:58:37 +010098 /// returns the physical register mapped to the specified
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010099 /// virtual register
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100100 Register getPhys(Register virtReg) const {
101 assert(virtReg.isVirtual());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100102 return Virt2PhysMap[virtReg];
103 }
104
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100105 /// creates a mapping for the specified virtual register to
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100106 /// the specified physical register
107 void assignVirt2Phys(unsigned virtReg, MCPhysReg physReg);
108
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100109 /// clears the specified virtual register's, physical
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100110 /// register mapping
111 void clearVirt(unsigned virtReg) {
112 assert(TargetRegisterInfo::isVirtualRegister(virtReg));
113 assert(Virt2PhysMap[virtReg] != NO_PHYS_REG &&
114 "attempt to clear a not assigned virtual register");
115 Virt2PhysMap[virtReg] = NO_PHYS_REG;
116 }
117
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100118 /// clears all virtual to physical register mappings
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100119 void clearAllVirt() {
120 Virt2PhysMap.clear();
121 grow();
122 }
123
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100124 /// returns true if VirtReg is assigned to its preferred physreg.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100125 bool hasPreferredPhys(unsigned VirtReg);
126
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100127 /// returns true if VirtReg has a known preferred register.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100128 /// This returns false if VirtReg has a preference that is a virtual
129 /// register that hasn't been assigned yet.
130 bool hasKnownPreference(unsigned VirtReg);
131
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100132 /// records virtReg is a split live interval from SReg.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100133 void setIsSplitFromReg(unsigned virtReg, unsigned SReg) {
134 Virt2SplitMap[virtReg] = SReg;
135 }
136
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100137 /// returns the live interval virtReg is split from.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100138 unsigned getPreSplitReg(unsigned virtReg) const {
139 return Virt2SplitMap[virtReg];
140 }
141
142 /// getOriginal - Return the original virtual register that VirtReg descends
143 /// from through splitting.
144 /// A register that was not created by splitting is its own original.
145 /// This operation is idempotent.
146 unsigned getOriginal(unsigned VirtReg) const {
147 unsigned Orig = getPreSplitReg(VirtReg);
148 return Orig ? Orig : VirtReg;
149 }
150
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100151 /// returns true if the specified virtual register is not
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100152 /// mapped to a stack slot or rematerialized.
153 bool isAssignedReg(unsigned virtReg) const {
154 if (getStackSlot(virtReg) == NO_STACK_SLOT)
155 return true;
156 // Split register can be assigned a physical register as well as a
157 // stack slot or remat id.
158 return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG);
159 }
160
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100161 /// returns the stack slot mapped to the specified virtual
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100162 /// register
163 int getStackSlot(unsigned virtReg) const {
164 assert(TargetRegisterInfo::isVirtualRegister(virtReg));
165 return Virt2StackSlotMap[virtReg];
166 }
167
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100168 /// create a mapping for the specifed virtual register to
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100169 /// the next available stack slot
170 int assignVirt2StackSlot(unsigned virtReg);
171
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100172 /// create a mapping for the specified virtual register to
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100173 /// the specified stack slot
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100174 void assignVirt2StackSlot(unsigned virtReg, int SS);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100175
176 void print(raw_ostream &OS, const Module* M = nullptr) const override;
177 void dump() const;
178 };
179
180 inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) {
181 VRM.print(OS);
182 return OS;
183 }
184
185} // end llvm namespace
186
187#endif // LLVM_CODEGEN_VIRTREGMAP_H