xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MIRVRegNamerUtils.h (revision e25152834cdf3b353892835a4f3b157e066a8ed4)
18bcb0991SDimitry Andric 
28bcb0991SDimitry Andric //===------------ MIRVRegNamerUtils.h - MIR VReg Renaming Utilities -------===//
38bcb0991SDimitry Andric //
48bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
58bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
68bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
78bcb0991SDimitry Andric //
88bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
98bcb0991SDimitry Andric //
108bcb0991SDimitry Andric // The purpose of these utilities is to abstract out parts of the MIRCanon pass
118bcb0991SDimitry Andric // that are responsible for renaming virtual registers with the purpose of
128bcb0991SDimitry Andric // sharing code with a MIRVRegNamer pass that could be the analog of the
138bcb0991SDimitry Andric // opt -instnamer pass.
148bcb0991SDimitry Andric //
158bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
168bcb0991SDimitry Andric 
178bcb0991SDimitry Andric #ifndef LLVM_LIB_CODEGEN_MIRVREGNAMERUTILS_H
188bcb0991SDimitry Andric #define LLVM_LIB_CODEGEN_MIRVREGNAMERUTILS_H
198bcb0991SDimitry Andric 
20*5ffd83dbSDimitry Andric #include "llvm/CodeGen/Register.h"
21*5ffd83dbSDimitry Andric #include <map>
22*5ffd83dbSDimitry Andric #include <vector>
23*5ffd83dbSDimitry Andric #include <string>
248bcb0991SDimitry Andric 
258bcb0991SDimitry Andric namespace llvm {
26*5ffd83dbSDimitry Andric 
27*5ffd83dbSDimitry Andric class MachineBasicBlock;
28*5ffd83dbSDimitry Andric class MachineInstr;
29*5ffd83dbSDimitry Andric class MachineRegisterInfo;
30*5ffd83dbSDimitry Andric class StringRef;
31*5ffd83dbSDimitry Andric 
32480093f4SDimitry Andric /// VRegRenamer - This class is used for renaming vregs in a machine basic
33480093f4SDimitry Andric /// block according to semantics of the instruction.
34480093f4SDimitry Andric class VRegRenamer {
35480093f4SDimitry Andric   class NamedVReg {
36480093f4SDimitry Andric     Register Reg;
37480093f4SDimitry Andric     std::string Name;
388bcb0991SDimitry Andric 
398bcb0991SDimitry Andric   public:
Reg(Reg)40480093f4SDimitry Andric     NamedVReg(Register Reg, std::string Name = "") : Reg(Reg), Name(Name) {}
41480093f4SDimitry Andric     NamedVReg(std::string Name = "") : Reg(~0U), Name(Name) {}
428bcb0991SDimitry Andric 
getName()43480093f4SDimitry Andric     const std::string &getName() const { return Name; }
448bcb0991SDimitry Andric 
getReg()45480093f4SDimitry Andric     Register getReg() const { return Reg; }
46480093f4SDimitry Andric   };
478bcb0991SDimitry Andric 
48480093f4SDimitry Andric   MachineRegisterInfo &MRI;
49480093f4SDimitry Andric 
50480093f4SDimitry Andric   unsigned CurrentBBNumber = 0;
51480093f4SDimitry Andric 
52480093f4SDimitry Andric   /// Given an Instruction, construct a hash of the operands
53480093f4SDimitry Andric   /// of the instructions along with the opcode.
54480093f4SDimitry Andric   /// When dealing with virtual registers, just hash the opcode of
55480093f4SDimitry Andric   /// the instruction defining that vreg.
56480093f4SDimitry Andric   /// Handle immediates, registers (physical and virtual) explicitly,
57480093f4SDimitry Andric   /// and return a common value for the other cases.
58480093f4SDimitry Andric   /// Instruction will be named in the following scheme
59480093f4SDimitry Andric   /// bb<block_no>_hash_<collission_count>.
60480093f4SDimitry Andric   std::string getInstructionOpcodeHash(MachineInstr &MI);
61480093f4SDimitry Andric 
62480093f4SDimitry Andric   /// For all the VRegs that are candidates for renaming,
63480093f4SDimitry Andric   /// return a mapping from old vregs to new vregs with names.
64480093f4SDimitry Andric   std::map<unsigned, unsigned>
65480093f4SDimitry Andric   getVRegRenameMap(const std::vector<NamedVReg> &VRegs);
66480093f4SDimitry Andric 
67480093f4SDimitry Andric   /// Perform replacing of registers based on the <old,new> vreg map.
68480093f4SDimitry Andric   bool doVRegRenaming(const std::map<unsigned, unsigned> &VRegRenameMap);
698bcb0991SDimitry Andric 
708bcb0991SDimitry Andric   /// createVirtualRegister - Given an existing vreg, create a named vreg to
71480093f4SDimitry Andric   /// take its place. The name is determined by calling
72480093f4SDimitry Andric   /// getInstructionOpcodeHash.
738bcb0991SDimitry Andric   unsigned createVirtualRegister(unsigned VReg);
748bcb0991SDimitry Andric 
75480093f4SDimitry Andric   /// Create a vreg with name and return it.
76480093f4SDimitry Andric   unsigned createVirtualRegisterWithLowerName(unsigned VReg, StringRef Name);
77*5ffd83dbSDimitry Andric 
78480093f4SDimitry Andric   /// Linearly traverse the MachineBasicBlock and rename each instruction's
79480093f4SDimitry Andric   /// vreg definition based on the semantics of the instruction.
80480093f4SDimitry Andric   /// Names are as follows bb<BBNum>_hash_[0-9]+
81480093f4SDimitry Andric   bool renameInstsInMBB(MachineBasicBlock *MBB);
82480093f4SDimitry Andric 
83480093f4SDimitry Andric public:
84480093f4SDimitry Andric   VRegRenamer() = delete;
VRegRenamer(MachineRegisterInfo & MRI)85480093f4SDimitry Andric   VRegRenamer(MachineRegisterInfo &MRI) : MRI(MRI) {}
86480093f4SDimitry Andric 
87480093f4SDimitry Andric   /// Same as the above, but sets a BBNum depending on BB traversal that
88480093f4SDimitry Andric   /// will be used as prefix for the vreg names.
renameVRegs(MachineBasicBlock * MBB,unsigned BBNum)89480093f4SDimitry Andric   bool renameVRegs(MachineBasicBlock *MBB, unsigned BBNum) {
90480093f4SDimitry Andric     CurrentBBNumber = BBNum;
91480093f4SDimitry Andric     return renameInstsInMBB(MBB);
92480093f4SDimitry Andric   }
938bcb0991SDimitry Andric };
948bcb0991SDimitry Andric 
958bcb0991SDimitry Andric } // namespace llvm
968bcb0991SDimitry Andric 
978bcb0991SDimitry Andric #endif
98