[ARM] VQADD instructions
[llvm-complete.git] / lib / Target / Mips / MipsRegisterBankInfo.h
blob176813c031ed09551dd97a958d6e7d17564ff8e4
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 //===----------------------------------------------------------------------===//
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"
21 namespace llvm {
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 {
32 public:
33 MipsRegisterBankInfo(const TargetRegisterInfo &TRI);
35 const RegisterBank &
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;
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
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.
78 /// MI : %5 = COPY %4
79 /// %6 = COPY %5
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.
86 /// %2 = COPY %1
87 /// MI = %3 = COPY %2
88 MachineInstr *skipCopiesIncoming(MachineInstr *MI) const;
90 public:
91 AmbiguousRegDefUseContainer(const MachineInstr *MI);
92 SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; }
93 SmallVectorImpl<MachineInstr *> &getUseDefs() { return UseDefs; }
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;
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,
112 bool isDefUse);
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,
122 unsigned Op);
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);
160 public:
161 InstType determineInstType(const MachineInstr *MI);
163 void cleanupIfNewFunction(llvm::StringRef FunctionName);
166 } // end namespace llvm
167 #endif