| //===------------ MIRVRegNamerUtils.h - MIR VReg Renaming Utilities -------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // The purpose of these utilities is to abstract out parts of the MIRCanon pass | |
| // that are responsible for renaming virtual registers with the purpose of | |
| // sharing code with a MIRVRegNamer pass that could be the analog of the | |
| // opt -instnamer pass. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLVM_LIB_CODEGEN_MIRVREGNAMERUTILS_H | |
| #define LLVM_LIB_CODEGEN_MIRVREGNAMERUTILS_H | |
| #include "llvm/ADT/PostOrderIterator.h" | |
| #include "llvm/ADT/STLExtras.h" | |
| #include "llvm/CodeGen/MachineFunctionPass.h" | |
| #include "llvm/CodeGen/MachineInstrBuilder.h" | |
| #include "llvm/CodeGen/MachineRegisterInfo.h" | |
| #include "llvm/CodeGen/Passes.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| namespace llvm { | |
| /// VRegRenamer - This class is used for renaming vregs in a machine basic | |
| /// block according to semantics of the instruction. | |
| class VRegRenamer { | |
| class NamedVReg { | |
| Register Reg; | |
| std::string Name; | |
| public: | |
| NamedVReg(Register Reg, std::string Name = "") : Reg(Reg), Name(Name) {} | |
| NamedVReg(std::string Name = "") : Reg(~0U), Name(Name) {} | |
| const std::string &getName() const { return Name; } | |
| Register getReg() const { return Reg; } | |
| }; | |
| MachineRegisterInfo &MRI; | |
| unsigned CurrentBBNumber = 0; | |
| /// Given an Instruction, construct a hash of the operands | |
| /// of the instructions along with the opcode. | |
| /// When dealing with virtual registers, just hash the opcode of | |
| /// the instruction defining that vreg. | |
| /// Handle immediates, registers (physical and virtual) explicitly, | |
| /// and return a common value for the other cases. | |
| /// Instruction will be named in the following scheme | |
| /// bb<block_no>_hash_<collission_count>. | |
| std::string getInstructionOpcodeHash(MachineInstr &MI); | |
| /// For all the VRegs that are candidates for renaming, | |
| /// return a mapping from old vregs to new vregs with names. | |
| std::map<unsigned, unsigned> | |
| getVRegRenameMap(const std::vector<NamedVReg> &VRegs); | |
| /// Perform replacing of registers based on the <old,new> vreg map. | |
| bool doVRegRenaming(const std::map<unsigned, unsigned> &VRegRenameMap); | |
| /// createVirtualRegister - Given an existing vreg, create a named vreg to | |
| /// take its place. The name is determined by calling | |
| /// getInstructionOpcodeHash. | |
| unsigned createVirtualRegister(unsigned VReg); | |
| /// Create a vreg with name and return it. | |
| unsigned createVirtualRegisterWithLowerName(unsigned VReg, StringRef Name); | |
| /// Linearly traverse the MachineBasicBlock and rename each instruction's | |
| /// vreg definition based on the semantics of the instruction. | |
| /// Names are as follows bb<BBNum>_hash_[0-9]+ | |
| bool renameInstsInMBB(MachineBasicBlock *MBB); | |
| public: | |
| VRegRenamer() = delete; | |
| VRegRenamer(MachineRegisterInfo &MRI) : MRI(MRI) {} | |
| /// Same as the above, but sets a BBNum depending on BB traversal that | |
| /// will be used as prefix for the vreg names. | |
| bool renameVRegs(MachineBasicBlock *MBB, unsigned BBNum) { | |
| CurrentBBNumber = BBNum; | |
| return renameInstsInMBB(MBB); | |
| } | |
| }; | |
| } // namespace llvm | |
| #endif |