LLVM  10.0.0svn
MipsRegisterBankInfo.h
Go to the documentation of this file.
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 
17 
18 #define GET_REGBANK_DECLARATIONS
19 #include "MipsGenRegisterBank.inc"
20 
21 namespace llvm {
22 
23 class TargetRegisterInfo;
24 
26 #define GET_TARGET_REGBANK_CLASS
27 #include "MipsGenRegisterBank.inc"
28 };
29 
30 /// This class provides the information for the target register banks.
32 public:
34 
35  const RegisterBank &
36  getRegBankFromRegClass(const TargetRegisterClass &RC) const override;
37 
38  const InstructionMapping &
39  getInstrMapping(const MachineInstr &MI) const override;
40 
41  /// Here we have to narrowScalar s64 operands to s32, combine away G_MERGE or
42  /// G_UNMERGE and erase instructions that became dead in the process. We
43  /// manually assign bank to def operand of all new instructions that were
44  /// created in the process since they will not end up in RegBankSelect loop.
45  void applyMappingImpl(const OperandsMapper &OpdMapper) const override;
46 
47  /// RegBankSelect determined that s64 operand is better to be split into two
48  /// s32 operands in gprb. Here we manually set register banks of def operands
49  /// of newly created instructions since they will not get regbankselected.
50  void setRegBank(MachineInstr &MI, MachineRegisterInfo &MRI) const;
51 
52 private:
53  /// Some instructions are used with both floating point and integer operands.
54  /// We assign InstType to such instructions as it helps us to avoid cross bank
55  /// copies. InstType deppends on context.
56  enum InstType {
57  /// Temporary type, when visit(..., nullptr) finishes will convert to one of
58  /// the remaining types: Integer, FloatingPoint or Ambiguous.
59  NotDetermined,
60  /// Connected with instruction that interprets 'bags of bits' as integers.
61  /// Select gprb to avoid cross bank copies.
62  Integer,
63  /// Connected with instruction that interprets 'bags of bits' as floating
64  /// point numbers. Select fprb to avoid cross bank copies.
65  FloatingPoint,
66  /// Represents moving 'bags of bits' around. Select same bank for entire
67  /// chain to avoid cross bank copies. Currently we select fprb for s64 and
68  /// gprb for s32 Ambiguous operands.
69  Ambiguous
70  };
71 
72  /// Some generic instructions have operands that can be mapped to either fprb
73  /// or gprb e.g. for G_LOAD we consider only operand 0 as ambiguous, operand 1
74  /// is always gprb since it is a pointer.
75  /// This class provides containers for MI's ambiguous:
76  /// DefUses : MachineInstrs that use one of MI's ambiguous def operands.
77  /// UseDefs : MachineInstrs that define MI's ambiguous use operands.
78  class AmbiguousRegDefUseContainer {
81 
82  void addDefUses(Register Reg, const MachineRegisterInfo &MRI);
83  void addUseDef(Register Reg, const MachineRegisterInfo &MRI);
84 
85  /// Skip copy instructions until we get to a non-copy instruction or to a
86  /// copy with phys register as def. Used during search for DefUses.
87  /// MI : %5 = COPY %4
88  /// %6 = COPY %5
89  /// $v0 = COPY %6 <- we want this one.
90  MachineInstr *skipCopiesOutgoing(MachineInstr *MI) const;
91 
92  /// Skip copy instructions until we get to a non-copy instruction or to a
93  /// copy with phys register as use. Used during search for UseDefs.
94  /// %1 = COPY $a1 <- we want this one.
95  /// %2 = COPY %1
96  /// MI = %3 = COPY %2
97  MachineInstr *skipCopiesIncoming(MachineInstr *MI) const;
98 
99  public:
100  AmbiguousRegDefUseContainer(const MachineInstr *MI);
101  SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; }
102  SmallVectorImpl<MachineInstr *> &getUseDefs() { return UseDefs; }
103  };
104 
105  class TypeInfoForMF {
106  /// MachineFunction name is used to recognise when MF changes.
107  std::string MFName = "";
108  /// <key, value> : value is vector of all MachineInstrs that are waiting for
109  /// key to figure out type of some of its ambiguous operands.
111  WaitingQueues;
112  /// Recorded InstTypes for visited instructions.
114 
115  /// Recursively visit MI's adjacent instructions and find MI's InstType.
116  bool visit(const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI);
117 
118  /// Visit MI's adjacent UseDefs or DefUses.
119  bool visitAdjacentInstrs(const MachineInstr *MI,
120  SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
121  bool isDefUse);
122 
123  /// Set type for MI, and recursively for all instructions that are
124  /// waiting for MI's type.
125  void setTypes(const MachineInstr *MI, InstType ITy);
126 
127  /// InstType for MI is determined, set it to InstType that corresponds to
128  /// physical regisiter that is operand number Op in CopyInst.
129  void setTypesAccordingToPhysicalRegister(const MachineInstr *MI,
130  const MachineInstr *CopyInst,
131  unsigned Op);
132 
133  /// Set default values for MI in order to start visit.
134  void startVisit(const MachineInstr *MI) {
135  Types.try_emplace(MI, InstType::NotDetermined);
136  WaitingQueues.try_emplace(MI);
137  }
138 
139  /// Returns true if instruction was already visited. Type might not be
140  /// determined at this point but will be when visit(..., nullptr) finishes.
141  bool wasVisited(const MachineInstr *MI) const { return Types.count(MI); };
142 
143  /// Returns recorded type for instruction.
144  const InstType &getRecordedTypeForInstr(const MachineInstr *MI) const {
145  assert(wasVisited(MI) && "Instruction was not visited!");
146  return Types.find(MI)->getSecond();
147  };
148 
149  /// Change recorded type for instruction.
150  void changeRecordedTypeForInstr(const MachineInstr *MI, InstType InstTy) {
151  assert(wasVisited(MI) && "Instruction was not visited!");
152  Types.find(MI)->getSecond() = InstTy;
153  };
154 
155  /// Returns WaitingQueue for instruction.
157  getWaitingQueueFor(const MachineInstr *MI) const {
158  assert(WaitingQueues.count(MI) && "Instruction was not visited!");
159  return WaitingQueues.find(MI)->getSecond();
160  };
161 
162  /// Add WaitingForMI to MI's WaitingQueue.
163  void addToWaitingQueue(const MachineInstr *MI,
164  const MachineInstr *WaitingForMI) {
165  assert(WaitingQueues.count(MI) && "Instruction was not visited!");
166  WaitingQueues.find(MI)->getSecond().push_back(WaitingForMI);
167  };
168 
169  public:
170  InstType determineInstType(const MachineInstr *MI);
171 
172  void cleanupIfNewFunction(llvm::StringRef FunctionName);
173  };
174 };
175 } // end namespace llvm
176 #endif
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Helper class that represents how the value of an instruction may be mapped and what is the related co...
unsigned Reg
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
unsigned const TargetRegisterInfo * TRI
Holds all the information related to register banks.
unsigned const MachineRegisterInfo * MRI
virtual const InstructionMapping & getInstrMapping(const MachineInstr &MI) const
Get the mapping of the different operands of MI on the register bank.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
This class provides the information for the target register banks.
This class implements the register bank concept.
Definition: RegisterBank.h:28
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:63
virtual void applyMappingImpl(const OperandsMapper &OpdMapper) const
See applyMapping.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:145
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
virtual const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC) const
Get a register bank that covers RC.