blob: deef4b90279a0b5c944a5abf984a5a977bf502b7 [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"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020022#include "llvm/CodeGen/TileShapeInfo.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010023#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).
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020052 IndexedMap<Register, VirtReg2IndexFunctor> Virt2PhysMap;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010053
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
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020064 /// Virt2ShapeMap - For X86 AMX register whose register is bound shape
65 /// information.
66 DenseMap<unsigned, ShapeT> Virt2ShapeMap;
67
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010068 /// createSpillSlot - Allocate a spill slot for RC from MFI.
69 unsigned createSpillSlot(const TargetRegisterClass *RC);
70
71 public:
72 static char ID;
73
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020074 VirtRegMap()
75 : MachineFunctionPass(ID), MRI(nullptr), TII(nullptr), TRI(nullptr),
76 MF(nullptr), Virt2PhysMap(NO_PHYS_REG),
77 Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010078 VirtRegMap(const VirtRegMap &) = delete;
79 VirtRegMap &operator=(const VirtRegMap &) = delete;
80
81 bool runOnMachineFunction(MachineFunction &MF) override;
82
83 void getAnalysisUsage(AnalysisUsage &AU) const override {
84 AU.setPreservesAll();
85 MachineFunctionPass::getAnalysisUsage(AU);
86 }
87
88 MachineFunction &getMachineFunction() const {
89 assert(MF && "getMachineFunction called before runOnMachineFunction");
90 return *MF;
91 }
92
93 MachineRegisterInfo &getRegInfo() const { return *MRI; }
94 const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; }
95
96 void grow();
97
Andrew Scullcdfcccc2018-10-05 20:58:37 +010098 /// returns true if the specified virtual register is
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010099 /// mapped to a physical register
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200100 bool hasPhys(Register virtReg) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100101 return getPhys(virtReg) != NO_PHYS_REG;
102 }
103
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100104 /// returns the physical register mapped to the specified
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100105 /// virtual register
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200106 MCRegister getPhys(Register virtReg) const {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100107 assert(virtReg.isVirtual());
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200108 return MCRegister::from(Virt2PhysMap[virtReg.id()]);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100109 }
110
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100111 /// creates a mapping for the specified virtual register to
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100112 /// the specified physical register
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200113 void assignVirt2Phys(Register virtReg, MCPhysReg physReg);
114
115 bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); }
116
117 bool hasShape(Register virtReg) const {
118 return getShape(virtReg).isValid();
119 }
120
121 ShapeT getShape(Register virtReg) const {
122 assert(virtReg.isVirtual());
123 return Virt2ShapeMap.lookup(virtReg);
124 }
125
126 void assignVirt2Shape(Register virtReg, ShapeT shape) {
127 Virt2ShapeMap[virtReg.id()] = shape;
128 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100129
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100130 /// clears the specified virtual register's, physical
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100131 /// register mapping
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200132 void clearVirt(Register virtReg) {
133 assert(virtReg.isVirtual());
134 assert(Virt2PhysMap[virtReg.id()] != NO_PHYS_REG &&
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100135 "attempt to clear a not assigned virtual register");
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200136 Virt2PhysMap[virtReg.id()] = NO_PHYS_REG;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100137 }
138
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100139 /// clears all virtual to physical register mappings
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100140 void clearAllVirt() {
141 Virt2PhysMap.clear();
142 grow();
143 }
144
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100145 /// returns true if VirtReg is assigned to its preferred physreg.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200146 bool hasPreferredPhys(Register VirtReg);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100147
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100148 /// returns true if VirtReg has a known preferred register.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100149 /// This returns false if VirtReg has a preference that is a virtual
150 /// register that hasn't been assigned yet.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200151 bool hasKnownPreference(Register VirtReg);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100152
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100153 /// records virtReg is a split live interval from SReg.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200154 void setIsSplitFromReg(Register virtReg, Register SReg) {
155 Virt2SplitMap[virtReg.id()] = SReg;
156 if (hasShape(SReg)) {
157 Virt2ShapeMap[virtReg.id()] = getShape(SReg);
158 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100159 }
160
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100161 /// returns the live interval virtReg is split from.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200162 Register getPreSplitReg(Register virtReg) const {
163 return Virt2SplitMap[virtReg.id()];
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100164 }
165
166 /// getOriginal - Return the original virtual register that VirtReg descends
167 /// from through splitting.
168 /// A register that was not created by splitting is its own original.
169 /// This operation is idempotent.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200170 Register getOriginal(Register VirtReg) const {
171 Register Orig = getPreSplitReg(VirtReg);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100172 return Orig ? Orig : VirtReg;
173 }
174
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100175 /// returns true if the specified virtual register is not
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100176 /// mapped to a stack slot or rematerialized.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200177 bool isAssignedReg(Register virtReg) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100178 if (getStackSlot(virtReg) == NO_STACK_SLOT)
179 return true;
180 // Split register can be assigned a physical register as well as a
181 // stack slot or remat id.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200182 return (Virt2SplitMap[virtReg.id()] &&
183 Virt2PhysMap[virtReg.id()] != NO_PHYS_REG);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100184 }
185
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100186 /// returns the stack slot mapped to the specified virtual
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100187 /// register
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200188 int getStackSlot(Register virtReg) const {
189 assert(virtReg.isVirtual());
190 return Virt2StackSlotMap[virtReg.id()];
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100191 }
192
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100193 /// create a mapping for the specifed virtual register to
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100194 /// the next available stack slot
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200195 int assignVirt2StackSlot(Register virtReg);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100196
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100197 /// create a mapping for the specified virtual register to
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100198 /// the specified stack slot
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200199 void assignVirt2StackSlot(Register virtReg, int SS);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100200
201 void print(raw_ostream &OS, const Module* M = nullptr) const override;
202 void dump() const;
203 };
204
205 inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) {
206 VRM.print(OS);
207 return OS;
208 }
209
210} // end llvm namespace
211
212#endif // LLVM_CODEGEN_VIRTREGMAP_H