Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
Line
Count
Source
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
417
    SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; }
93
249
    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
417
    void startVisit(const MachineInstr *MI) {
126
417
      Types.try_emplace(MI, InstType::NotDetermined);
127
417
      WaitingQueues.try_emplace(MI);
128
417
    }
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
1.18k
    bool wasVisited(const MachineInstr *MI) const { return Types.count(MI); };
133
134
    /// Returns recorded type for instruction.
135
799
    const InstType &getRecordedTypeForInstr(const MachineInstr *MI) const {
136
799
      assert(wasVisited(MI) && "Instruction was not visited!");
137
799
      return Types.find(MI)->getSecond();
138
799
    };
139
140
    /// Change recorded type for instruction.
141
417
    void changeRecordedTypeForInstr(const MachineInstr *MI, InstType InstTy) {
142
417
      assert(wasVisited(MI) && "Instruction was not visited!");
143
417
      Types.find(MI)->getSecond() = InstTy;
144
417
    };
145
146
    /// Returns WaitingQueue for instruction.
147
    const SmallVectorImpl<const MachineInstr *> &
148
417
    getWaitingQueueFor(const MachineInstr *MI) const {
149
417
      assert(WaitingQueues.count(MI) && "Instruction was not visited!");
150
417
      return WaitingQueues.find(MI)->getSecond();
151
417
    };
152
153
    /// Add WaitingForMI to MI's WaitingQueue.
154
    void addToWaitingQueue(const MachineInstr *MI,
155
164
                           const MachineInstr *WaitingForMI) {
156
164
      assert(WaitingQueues.count(MI) && "Instruction was not visited!");
157
164
      WaitingQueues.find(MI)->getSecond().push_back(WaitingForMI);
158
164
    };
159
160
  public:
161
    InstType determineInstType(const MachineInstr *MI);
162
163
    void cleanupIfNewFunction(llvm::StringRef FunctionName);
164
  };
165
};
166
} // end namespace llvm
167
#endif