1 //===- MipsRegisterBankInfo.h -----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 /// This file declares the targeting of the RegisterBankInfo class for Mips.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H
14 #define LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H
16 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
18 #define GET_REGBANK_DECLARATIONS
19 #include "MipsGenRegisterBank.inc"
23 class TargetRegisterInfo
;
25 class MipsGenRegisterBankInfo
: public RegisterBankInfo
{
26 #define GET_TARGET_REGBANK_CLASS
27 #include "MipsGenRegisterBank.inc"
30 /// This class provides the information for the target register banks.
31 class MipsRegisterBankInfo final
: public MipsGenRegisterBankInfo
{
33 MipsRegisterBankInfo(const TargetRegisterInfo
&TRI
);
36 getRegBankFromRegClass(const TargetRegisterClass
&RC
) const override
;
38 const InstructionMapping
&
39 getInstrMapping(const MachineInstr
&MI
) const override
;
41 void applyMappingImpl(const OperandsMapper
&OpdMapper
) const override
;
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.
48 /// Temporary type, when visit(..., nullptr) finishes will convert to one of
49 /// the remaining types: Integer, FloatingPoint or Ambiguous.
51 /// Connected with instruction that interprets 'bags of bits' as integers.
52 /// Select gprb to avoid cross bank copies.
54 /// Connected with instruction that interprets 'bags of bits' as floating
55 /// point numbers. Select fprb to avoid cross bank copies.
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.
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
;
73 void addDefUses(Register Reg
, const MachineRegisterInfo
&MRI
);
74 void addUseDef(Register Reg
, const MachineRegisterInfo
&MRI
);
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.
80 /// $v0 = COPY %6 <- we want this one.
81 MachineInstr
*skipCopiesOutgoing(MachineInstr
*MI
) const;
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.
88 MachineInstr
*skipCopiesIncoming(MachineInstr
*MI
) const;
91 AmbiguousRegDefUseContainer(const MachineInstr
*MI
);
92 SmallVectorImpl
<MachineInstr
*> &getDefUses() { return DefUses
; }
93 SmallVectorImpl
<MachineInstr
*> &getUseDefs() { return UseDefs
; }
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>>
103 /// Recorded InstTypes for visited instructions.
104 DenseMap
<const MachineInstr
*, InstType
> Types
;
106 /// Recursively visit MI's adjacent instructions and find MI's InstType.
107 bool visit(const MachineInstr
*MI
, const MachineInstr
*WaitingForTypeOfMI
);
109 /// Visit MI's adjacent UseDefs or DefUses.
110 bool visitAdjacentInstrs(const MachineInstr
*MI
,
111 SmallVectorImpl
<MachineInstr
*> &AdjacentInstrs
,
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
);
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
,
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
);
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
); };
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();
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
;
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();
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
);
161 InstType
determineInstType(const MachineInstr
*MI
);
163 void cleanupIfNewFunction(llvm::StringRef FunctionName
);
166 } // end namespace llvm