1 //===- MipsRegisterBankInfo.h -----------------------------------*- C++ -*-===// 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 /// \file 9 /// This file declares the targeting of the RegisterBankInfo class for Mips. 10 /// \todo This should be generated by TableGen. 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H 14 #define LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H 15 16 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 17 18 #define GET_REGBANK_DECLARATIONS 19 #include "MipsGenRegisterBank.inc" 20 21 namespace llvm { 22 23 class TargetRegisterInfo; 24 25 class MipsGenRegisterBankInfo : public RegisterBankInfo { 26 #define GET_TARGET_REGBANK_CLASS 27 #include "MipsGenRegisterBank.inc" 28 }; 29 30 /// This class provides the information for the target register banks. 31 class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo { 32 public: 33 MipsRegisterBankInfo(const TargetRegisterInfo &TRI); 34 35 const RegisterBank & 36 getRegBankFromRegClass(const TargetRegisterClass &RC) const override; 37 38 const InstructionMapping & 39 getInstrMapping(const MachineInstr &MI) const override; 40 41 void applyMappingImpl(const OperandsMapper &OpdMapper) const override; 42 43 private: 44 /// Some instructions are used with both floating point and integer operands. 45 /// We assign InstType to such instructions as it helps us to avoid cross bank 46 /// copies. InstType deppends on context. 47 enum InstType { 48 /// Temporary type, when visit(..., nullptr) finishes will convert to one of 49 /// the remaining types: Integer, FloatingPoint or Ambiguous. 50 NotDetermined, 51 /// Connected with instruction that interprets 'bags of bits' as integers. 52 /// Select gprb to avoid cross bank copies. 53 Integer, 54 /// Connected with instruction that interprets 'bags of bits' as floating 55 /// point numbers. Select fprb to avoid cross bank copies. 56 FloatingPoint, 57 /// Represents moving 'bags of bits' around. Select same bank for entire 58 /// chain to avoid cross bank copies. Currently we select fprb for s64 and 59 /// gprb for s32 Ambiguous operands. 60 Ambiguous 61 }; 62 63 /// Some generic instructions have operands that can be mapped to either fprb 64 /// or gprb e.g. for G_LOAD we consider only operand 0 as ambiguous, operand 1 65 /// is always gprb since it is a pointer. 66 /// This class provides containers for MI's ambiguous: 67 /// DefUses : MachineInstrs that use one of MI's ambiguous def operands. 68 /// UseDefs : MachineInstrs that define MI's ambiguous use operands. 69 class AmbiguousRegDefUseContainer { 70 SmallVector<MachineInstr *, 2> DefUses; 71 SmallVector<MachineInstr *, 2> UseDefs; 72 73 void addDefUses(Register Reg, const MachineRegisterInfo &MRI); 74 void addUseDef(Register Reg, const MachineRegisterInfo &MRI); 75 76 /// Skip copy instructions until we get to a non-copy instruction or to a 77 /// copy with phys register as def. Used during search for DefUses. 78 /// MI : %5 = COPY %4 79 /// %6 = COPY %5 80 /// $v0 = COPY %6 <- we want this one. 81 MachineInstr *skipCopiesOutgoing(MachineInstr *MI) const; 82 83 /// Skip copy instructions until we get to a non-copy instruction or to a 84 /// copy with phys register as use. Used during search for UseDefs. 85 /// %1 = COPY $a1 <- we want this one. 86 /// %2 = COPY %1 87 /// MI = %3 = COPY %2 88 MachineInstr *skipCopiesIncoming(MachineInstr *MI) const; 89 90 public: 91 AmbiguousRegDefUseContainer(const MachineInstr *MI); 92 SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; } 93 SmallVectorImpl<MachineInstr *> &getUseDefs() { return UseDefs; } 94 }; 95 96 class TypeInfoForMF { 97 /// MachineFunction name is used to recognise when MF changes. 98 std::string MFName = ""; 99 /// <key, value> : value is vector of all MachineInstrs that are waiting for 100 /// key to figure out type of some of its ambiguous operands. 101 DenseMap<const MachineInstr *, SmallVector<const MachineInstr *, 2>> 102 WaitingQueues; 103 /// Recorded InstTypes for visited instructions. 104 DenseMap<const MachineInstr *, InstType> Types; 105 106 /// Recursively visit MI's adjacent instructions and find MI's InstType. 107 bool visit(const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI); 108 109 /// Visit MI's adjacent UseDefs or DefUses. 110 bool visitAdjacentInstrs(const MachineInstr *MI, 111 SmallVectorImpl<MachineInstr *> &AdjacentInstrs, 112 bool isDefUse); 113 114 /// Set type for MI, and recursively for all instructions that are 115 /// waiting for MI's type. 116 void setTypes(const MachineInstr *MI, InstType ITy); 117 118 /// InstType for MI is determined, set it to InstType that corresponds to 119 /// physical regisiter that is operand number Op in CopyInst. 120 void setTypesAccordingToPhysicalRegister(const MachineInstr *MI, 121 const MachineInstr *CopyInst, 122 unsigned Op); 123 124 /// Set default values for MI in order to start visit. 125 void startVisit(const MachineInstr *MI) { 126 Types.try_emplace(MI, InstType::NotDetermined); 127 WaitingQueues.try_emplace(MI); 128 } 129 130 /// Returns true if instruction was already visited. Type might not be 131 /// determined at this point but will be when visit(..., nullptr) finishes. 132 bool wasVisited(const MachineInstr *MI) const { return Types.count(MI); }; 133 134 /// Returns recorded type for instruction. 135 const InstType &getRecordedTypeForInstr(const MachineInstr *MI) const { 136 assert(wasVisited(MI) && "Instruction was not visited!"); 137 return Types.find(MI)->getSecond(); 138 }; 139 140 /// Change recorded type for instruction. 141 void changeRecordedTypeForInstr(const MachineInstr *MI, InstType InstTy) { 142 assert(wasVisited(MI) && "Instruction was not visited!"); 143 Types.find(MI)->getSecond() = InstTy; 144 }; 145 146 /// Returns WaitingQueue for instruction. 147 const SmallVectorImpl<const MachineInstr *> & 148 getWaitingQueueFor(const MachineInstr *MI) const { 149 assert(WaitingQueues.count(MI) && "Instruction was not visited!"); 150 return WaitingQueues.find(MI)->getSecond(); 151 }; 152 153 /// Add WaitingForMI to MI's WaitingQueue. 154 void addToWaitingQueue(const MachineInstr *MI, 155 const MachineInstr *WaitingForMI) { 156 assert(WaitingQueues.count(MI) && "Instruction was not visited!"); 157 WaitingQueues.find(MI)->getSecond().push_back(WaitingForMI); 158 }; 159 160 public: 161 InstType determineInstType(const MachineInstr *MI); 162 163 void cleanupIfNewFunction(llvm::StringRef FunctionName); 164 }; 165 }; 166 } // end namespace llvm 167 #endif 168