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