blob: fa36a110664b1801d8c2c21c37b74d99d78f6635 [file] [log] [blame]
Puyan Lotfi028061d2019-09-04 21:29:10 +00001//===---------- MIRVRegNamerUtils.cpp - MIR VReg Renaming Utilities -------===//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8
9#include "MIRVRegNamerUtils.h"
Reid Kleckner1d7b4132019-10-19 00:22:07 +000010#include "llvm/Support/Debug.h"
Puyan Lotfi028061d2019-09-04 21:29:10 +000011
12using namespace llvm;
13
14#define DEBUG_TYPE "mir-vregnamer-utils"
15
Puyan Lotfi479e3b82019-12-09 14:54:09 -050016using VRegRenameMap = std::map<unsigned, unsigned>;
17
18bool VRegRenamer::doVRegRenaming(const VRegRenameMap &VRM) {
Puyan Lotfi028061d2019-09-04 21:29:10 +000019 bool Changed = false;
Puyan Lotfi028061d2019-09-04 21:29:10 +000020
Puyan Lotfi479e3b82019-12-09 14:54:09 -050021 for (const auto &E : VRM) {
22 Changed = Changed || !MRI.reg_empty(E.first);
23 MRI.replaceRegWith(E.first, E.second);
Puyan Lotfi028061d2019-09-04 21:29:10 +000024 }
25
26 return Changed;
27}
28
Puyan Lotfi479e3b82019-12-09 14:54:09 -050029VRegRenameMap
Aditya Nandakumar72768682019-11-15 08:23:32 -080030VRegRenamer::getVRegRenameMap(const std::vector<NamedVReg> &VRegs) {
Puyan Lotfi028061d2019-09-04 21:29:10 +000031
Puyan Lotfi479e3b82019-12-09 14:54:09 -050032 StringMap<unsigned> VRegNameCollisionMap;
Puyan Lotfi028061d2019-09-04 21:29:10 +000033
Puyan Lotfi479e3b82019-12-09 14:54:09 -050034 auto GetUniqueVRegName = [&VRegNameCollisionMap](const NamedVReg &Reg) {
35 if (VRegNameCollisionMap.find(Reg.getName()) == VRegNameCollisionMap.end())
36 VRegNameCollisionMap[Reg.getName()] = 0;
37 const unsigned Counter = ++VRegNameCollisionMap[Reg.getName()];
Aditya Nandakumar72768682019-11-15 08:23:32 -080038 return Reg.getName() + "__" + std::to_string(Counter);
39 };
Puyan Lotfi028061d2019-09-04 21:29:10 +000040
Puyan Lotfi479e3b82019-12-09 14:54:09 -050041 VRegRenameMap VRM;
42 for (const auto &VReg : VRegs) {
43 const unsigned Reg = VReg.getReg();
44 VRM[Reg] = createVirtualRegisterWithLowerName(Reg, GetUniqueVRegName(VReg));
Aditya Nandakumar72768682019-11-15 08:23:32 -080045 }
Puyan Lotfi479e3b82019-12-09 14:54:09 -050046 return VRM;
Aditya Nandakumar72768682019-11-15 08:23:32 -080047}
Puyan Lotfi028061d2019-09-04 21:29:10 +000048
Aditya Nandakumar72768682019-11-15 08:23:32 -080049std::string VRegRenamer::getInstructionOpcodeHash(MachineInstr &MI) {
50 std::string S;
51 raw_string_ostream OS(S);
Puyan Lotfi479e3b82019-12-09 14:54:09 -050052
53 // Gets a hashable artifact from a given MachineOperand (ie an unsigned).
54 auto GetHashableMO = [this](const MachineOperand &MO) -> unsigned {
Puyan Lotfi816985c2019-12-14 00:58:44 -050055 switch (MO.getType()) {
56 case MachineOperand::MO_Immediate:
Aditya Nandakumar72768682019-11-15 08:23:32 -080057 return MO.getImm();
Puyan Lotfi816985c2019-12-14 00:58:44 -050058 case MachineOperand::MO_TargetIndex:
Aditya Nandakumar72768682019-11-15 08:23:32 -080059 return MO.getOffset() | (MO.getTargetFlags() << 16);
Puyan Lotfi816985c2019-12-14 00:58:44 -050060 case MachineOperand::MO_Register:
61 if (Register::isVirtualRegister(MO.getReg()))
62 return MRI.getVRegDef(MO.getReg())->getOpcode();
Puyan Lotfi479e3b82019-12-09 14:54:09 -050063 return MO.getReg();
Puyan Lotfi816985c2019-12-14 00:58:44 -050064
Aditya Nandakumar72768682019-11-15 08:23:32 -080065 // We could explicitly handle all the types of the MachineOperand,
66 // here but we can just return a common number until we find a
67 // compelling test case where this is bad. The only side effect here
Puyan Lotfi479e3b82019-12-09 14:54:09 -050068 // is contributing to a hash collision but there's enough information
Aditya Nandakumar72768682019-11-15 08:23:32 -080069 // (Opcodes,other registers etc) that this will likely not be a problem.
Puyan Lotfi816985c2019-12-14 00:58:44 -050070
71 // TODO: Handle the following Immediate/Index/ID/Predicate cases. They can
72 // be hashed on in a stable manner.
73 case MachineOperand::MO_CImmediate:
74 case MachineOperand::MO_FPImmediate:
75 case MachineOperand::MO_FrameIndex:
76 case MachineOperand::MO_ConstantPoolIndex:
77 case MachineOperand::MO_JumpTableIndex:
78 case MachineOperand::MO_CFIIndex:
79 case MachineOperand::MO_IntrinsicID:
80 case MachineOperand::MO_Predicate:
81
82 // In the cases below we havn't found a way to produce an artifact that will
83 // result in a stable hash, in most cases because they are pointers. We want
84 // stable hashes because we want the hash to be the same run to run.
85 case MachineOperand::MO_MachineBasicBlock:
86 case MachineOperand::MO_ExternalSymbol:
87 case MachineOperand::MO_GlobalAddress:
88 case MachineOperand::MO_BlockAddress:
89 case MachineOperand::MO_RegisterMask:
90 case MachineOperand::MO_RegisterLiveOut:
91 case MachineOperand::MO_Metadata:
92 case MachineOperand::MO_MCSymbol:
93 case MachineOperand::MO_ShuffleMask:
94 return 0;
95 }
96 llvm_unreachable("Unexpected MachineOperandType.");
Aditya Nandakumar72768682019-11-15 08:23:32 -080097 };
Puyan Lotfi479e3b82019-12-09 14:54:09 -050098
Puyan Lotfif3646862019-12-10 04:40:36 -050099 SmallVector<unsigned, 16> MIOperands = {MI.getOpcode(), MI.getFlags()};
Puyan Lotfi479e3b82019-12-09 14:54:09 -0500100 llvm::transform(MI.uses(), std::back_inserter(MIOperands), GetHashableMO);
101
Puyan Lotfif5b7a462019-12-11 01:39:17 -0500102 for (const auto *Op : MI.memoperands()) {
103 MIOperands.push_back((unsigned)Op->getSize());
104 MIOperands.push_back((unsigned)Op->getFlags());
105 MIOperands.push_back((unsigned)Op->getOffset());
106 MIOperands.push_back((unsigned)Op->getOrdering());
107 MIOperands.push_back((unsigned)Op->getAddrSpace());
108 MIOperands.push_back((unsigned)Op->getSyncScopeID());
109 MIOperands.push_back((unsigned)Op->getBaseAlignment());
110 MIOperands.push_back((unsigned)Op->getFailureOrdering());
111 }
112
Aditya Nandakumar72768682019-11-15 08:23:32 -0800113 auto HashMI = hash_combine_range(MIOperands.begin(), MIOperands.end());
114 return std::to_string(HashMI).substr(0, 5);
115}
Puyan Lotfi028061d2019-09-04 21:29:10 +0000116
Aditya Nandakumar72768682019-11-15 08:23:32 -0800117unsigned VRegRenamer::createVirtualRegister(unsigned VReg) {
Puyan Lotfi479e3b82019-12-09 14:54:09 -0500118 assert(Register::isVirtualRegister(VReg) && "Expected Virtual Registers");
119 std::string Name = getInstructionOpcodeHash(*MRI.getVRegDef(VReg));
120 return createVirtualRegisterWithLowerName(VReg, Name);
Aditya Nandakumar72768682019-11-15 08:23:32 -0800121}
122
123bool VRegRenamer::renameInstsInMBB(MachineBasicBlock *MBB) {
124 std::vector<NamedVReg> VRegs;
Puyan Lotfi756db632019-12-12 03:27:47 -0500125 std::string Prefix = "bb" + std::to_string(CurrentBBNumber) + "_";
Puyan Lotfi479e3b82019-12-09 14:54:09 -0500126 for (MachineInstr &Candidate : *MBB) {
Aditya Nandakumar72768682019-11-15 08:23:32 -0800127 // Don't rename stores/branches.
128 if (Candidate.mayStore() || Candidate.isBranch())
129 continue;
130 if (!Candidate.getNumOperands())
131 continue;
132 // Look for instructions that define VRegs in operand 0.
133 MachineOperand &MO = Candidate.getOperand(0);
134 // Avoid non regs, instructions defining physical regs.
135 if (!MO.isReg() || !Register::isVirtualRegister(MO.getReg()))
136 continue;
137 VRegs.push_back(
138 NamedVReg(MO.getReg(), Prefix + getInstructionOpcodeHash(Candidate)));
Puyan Lotfi028061d2019-09-04 21:29:10 +0000139 }
140
Puyan Lotfi479e3b82019-12-09 14:54:09 -0500141 return VRegs.size() ? doVRegRenaming(getVRegRenameMap(VRegs)) : false;
Puyan Lotfi028061d2019-09-04 21:29:10 +0000142}
143
Puyan Lotfi479e3b82019-12-09 14:54:09 -0500144unsigned VRegRenamer::createVirtualRegisterWithLowerName(unsigned VReg,
145 StringRef Name) {
146 std::string LowerName = Name.lower();
147 const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg);
148 return RC ? MRI.createVirtualRegister(RC, LowerName)
149 : MRI.createGenericVirtualRegister(MRI.getType(VReg), LowerName);
Puyan Lotfi028061d2019-09-04 21:29:10 +0000150}