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 208bcb0991SDimitry Andric #include "llvm/ADT/PostOrderIterator.h" 218bcb0991SDimitry Andric #include "llvm/ADT/STLExtras.h" 228bcb0991SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 238bcb0991SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 248bcb0991SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 258bcb0991SDimitry Andric #include "llvm/CodeGen/Passes.h" 268bcb0991SDimitry Andric #include "llvm/Support/raw_ostream.h" 278bcb0991SDimitry Andric 288bcb0991SDimitry Andric namespace llvm { 29*480093f4SDimitry Andric /// VRegRenamer - This class is used for renaming vregs in a machine basic 30*480093f4SDimitry Andric /// block according to semantics of the instruction. 31*480093f4SDimitry Andric class VRegRenamer { 32*480093f4SDimitry Andric class NamedVReg { 33*480093f4SDimitry Andric Register Reg; 34*480093f4SDimitry Andric std::string Name; 358bcb0991SDimitry Andric 368bcb0991SDimitry Andric public: 37*480093f4SDimitry Andric NamedVReg(Register Reg, std::string Name = "") : Reg(Reg), Name(Name) {} 38*480093f4SDimitry Andric NamedVReg(std::string Name = "") : Reg(~0U), Name(Name) {} 398bcb0991SDimitry Andric 40*480093f4SDimitry Andric const std::string &getName() const { return Name; } 418bcb0991SDimitry Andric 42*480093f4SDimitry Andric Register getReg() const { return Reg; } 43*480093f4SDimitry Andric }; 448bcb0991SDimitry Andric 45*480093f4SDimitry Andric MachineRegisterInfo &MRI; 46*480093f4SDimitry Andric 47*480093f4SDimitry Andric unsigned CurrentBBNumber = 0; 48*480093f4SDimitry Andric 49*480093f4SDimitry Andric /// Given an Instruction, construct a hash of the operands 50*480093f4SDimitry Andric /// of the instructions along with the opcode. 51*480093f4SDimitry Andric /// When dealing with virtual registers, just hash the opcode of 52*480093f4SDimitry Andric /// the instruction defining that vreg. 53*480093f4SDimitry Andric /// Handle immediates, registers (physical and virtual) explicitly, 54*480093f4SDimitry Andric /// and return a common value for the other cases. 55*480093f4SDimitry Andric /// Instruction will be named in the following scheme 56*480093f4SDimitry Andric /// bb<block_no>_hash_<collission_count>. 57*480093f4SDimitry Andric std::string getInstructionOpcodeHash(MachineInstr &MI); 58*480093f4SDimitry Andric 59*480093f4SDimitry Andric /// For all the VRegs that are candidates for renaming, 60*480093f4SDimitry Andric /// return a mapping from old vregs to new vregs with names. 61*480093f4SDimitry Andric std::map<unsigned, unsigned> 62*480093f4SDimitry Andric getVRegRenameMap(const std::vector<NamedVReg> &VRegs); 63*480093f4SDimitry Andric 64*480093f4SDimitry Andric /// Perform replacing of registers based on the <old,new> vreg map. 65*480093f4SDimitry Andric bool doVRegRenaming(const std::map<unsigned, unsigned> &VRegRenameMap); 668bcb0991SDimitry Andric 678bcb0991SDimitry Andric /// createVirtualRegister - Given an existing vreg, create a named vreg to 68*480093f4SDimitry Andric /// take its place. The name is determined by calling 69*480093f4SDimitry Andric /// getInstructionOpcodeHash. 708bcb0991SDimitry Andric unsigned createVirtualRegister(unsigned VReg); 718bcb0991SDimitry Andric 72*480093f4SDimitry Andric /// Create a vreg with name and return it. 73*480093f4SDimitry Andric unsigned createVirtualRegisterWithLowerName(unsigned VReg, StringRef Name); 74*480093f4SDimitry Andric /// Linearly traverse the MachineBasicBlock and rename each instruction's 75*480093f4SDimitry Andric /// vreg definition based on the semantics of the instruction. 76*480093f4SDimitry Andric /// Names are as follows bb<BBNum>_hash_[0-9]+ 77*480093f4SDimitry Andric bool renameInstsInMBB(MachineBasicBlock *MBB); 78*480093f4SDimitry Andric 79*480093f4SDimitry Andric public: 80*480093f4SDimitry Andric VRegRenamer() = delete; 81*480093f4SDimitry Andric VRegRenamer(MachineRegisterInfo &MRI) : MRI(MRI) {} 82*480093f4SDimitry Andric 83*480093f4SDimitry Andric /// Same as the above, but sets a BBNum depending on BB traversal that 84*480093f4SDimitry Andric /// will be used as prefix for the vreg names. 85*480093f4SDimitry Andric bool renameVRegs(MachineBasicBlock *MBB, unsigned BBNum) { 86*480093f4SDimitry Andric CurrentBBNumber = BBNum; 87*480093f4SDimitry Andric return renameInstsInMBB(MBB); 88*480093f4SDimitry Andric } 898bcb0991SDimitry Andric }; 908bcb0991SDimitry Andric 918bcb0991SDimitry Andric } // namespace llvm 928bcb0991SDimitry Andric 938bcb0991SDimitry Andric #endif 94