Coverage Report

Created: 2019-02-23 12:57

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/TargetSchedule.h
Line
Count
Source
1
//===- llvm/CodeGen/TargetSchedule.h - Sched Machine Model ------*- 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
//
9
// This file defines a wrapper around MCSchedModel that allows the interface to
10
// benefit from information currently only available in TargetInstrInfo.
11
// Ideally, the scheduling interface would be fully defined in the MC layer.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CODEGEN_TARGETSCHEDULE_H
16
#define LLVM_CODEGEN_TARGETSCHEDULE_H
17
18
#include "llvm/ADT/Optional.h"
19
#include "llvm/ADT/SmallVector.h"
20
#include "llvm/CodeGen/TargetSubtargetInfo.h"
21
#include "llvm/Config/llvm-config.h"
22
#include "llvm/MC/MCInstrItineraries.h"
23
#include "llvm/MC/MCSchedule.h"
24
25
namespace llvm {
26
27
class MachineInstr;
28
class TargetInstrInfo;
29
30
/// Provide an instruction scheduling machine model to CodeGen passes.
31
class TargetSchedModel {
32
  // For efficiency, hold a copy of the statically defined MCSchedModel for this
33
  // processor.
34
  MCSchedModel SchedModel;
35
  InstrItineraryData InstrItins;
36
  const TargetSubtargetInfo *STI = nullptr;
37
  const TargetInstrInfo *TII = nullptr;
38
39
  SmallVector<unsigned, 16> ResourceFactors;
40
  unsigned MicroOpFactor; // Multiply to normalize microops to resource units.
41
  unsigned ResourceLCM;   // Resource units per cycle. Latency normalization factor.
42
43
  unsigned computeInstrLatency(const MCSchedClassDesc &SCDesc) const;
44
45
public:
46
679k
  TargetSchedModel() : SchedModel(MCSchedModel::GetDefaultSchedModel()) {}
47
48
  /// Initialize the machine model for instruction scheduling.
49
  ///
50
  /// The machine model API keeps a copy of the top-level MCSchedModel table
51
  /// indices and may query TargetSubtargetInfo and TargetInstrInfo to resolve
52
  /// dynamic properties.
53
  void init(const TargetSubtargetInfo *TSInfo);
54
55
  /// Return the MCSchedClassDesc for this instruction.
56
  const MCSchedClassDesc *resolveSchedClass(const MachineInstr *MI) const;
57
58
  /// TargetSubtargetInfo getter.
59
606k
  const TargetSubtargetInfo *getSubtargetInfo() const { return STI; }
60
61
  /// TargetInstrInfo getter.
62
36.4M
  const TargetInstrInfo *getInstrInfo() const { return TII; }
63
64
  /// Return true if this machine model includes an instruction-level
65
  /// scheduling model.
66
  ///
67
  /// This is more detailed than the course grain IssueWidth and default
68
  /// latency properties, but separate from the per-cycle itinerary data.
69
  bool hasInstrSchedModel() const;
70
71
778k
  const MCSchedModel *getMCSchedModel() const { return &SchedModel; }
72
73
  /// Return true if this machine model includes cycle-to-cycle itinerary
74
  /// data.
75
  ///
76
  /// This models scheduling at each stage in the processor pipeline.
77
  bool hasInstrItineraries() const;
78
79
2.79M
  const InstrItineraryData *getInstrItineraries() const {
80
2.79M
    if (hasInstrItineraries())
81
27.1k
      return &InstrItins;
82
2.76M
    return nullptr;
83
2.76M
  }
84
85
  /// Return true if this machine model includes an instruction-level
86
  /// scheduling model or cycle-to-cycle itinerary data.
87
102k
  bool hasInstrSchedModelOrItineraries() const {
88
102k
    return hasInstrSchedModel() || 
hasInstrItineraries()1.80k
;
89
102k
  }
90
91
  /// Identify the processor corresponding to the current subtarget.
92
36.9M
  unsigned getProcessorID() const { return SchedModel.getProcessorID(); }
93
94
  /// Maximum number of micro-ops that may be scheduled per cycle.
95
66.1M
  unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
96
97
  /// Return true if new group must begin.
98
  bool mustBeginGroup(const MachineInstr *MI,
99
                          const MCSchedClassDesc *SC = nullptr) const;
100
  /// Return true if current group must end.
101
  bool mustEndGroup(const MachineInstr *MI,
102
                          const MCSchedClassDesc *SC = nullptr) const;
103
104
  /// Return the number of issue slots required for this MI.
105
  unsigned getNumMicroOps(const MachineInstr *MI,
106
                          const MCSchedClassDesc *SC = nullptr) const;
107
108
  /// Get the number of kinds of resources for this target.
109
32.5M
  unsigned getNumProcResourceKinds() const {
110
32.5M
    return SchedModel.getNumProcResourceKinds();
111
32.5M
  }
112
113
  /// Get a processor resource by ID for convenience.
114
11.4M
  const MCProcResourceDesc *getProcResource(unsigned PIdx) const {
115
11.4M
    return SchedModel.getProcResource(PIdx);
116
11.4M
  }
117
118
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
119
  const char *getResourceName(unsigned PIdx) const {
120
    if (!PIdx)
121
      return "MOps";
122
    return SchedModel.getProcResource(PIdx)->Name;
123
  }
124
#endif
125
126
  using ProcResIter = const MCWriteProcResEntry *;
127
128
  // Get an iterator into the processor resources consumed by this
129
  // scheduling class.
130
56.7M
  ProcResIter getWriteProcResBegin(const MCSchedClassDesc *SC) const {
131
56.7M
    // The subtarget holds a single resource table for all processors.
132
56.7M
    return STI->getWriteProcResBegin(SC);
133
56.7M
  }
134
56.7M
  ProcResIter getWriteProcResEnd(const MCSchedClassDesc *SC) const {
135
56.7M
    return STI->getWriteProcResEnd(SC);
136
56.7M
  }
137
138
  /// Multiply the number of units consumed for a resource by this factor
139
  /// to normalize it relative to other resources.
140
35.1M
  unsigned getResourceFactor(unsigned ResIdx) const {
141
35.1M
    return ResourceFactors[ResIdx];
142
35.1M
  }
143
144
  /// Multiply number of micro-ops by this factor to normalize it
145
  /// relative to other resources.
146
47.9M
  unsigned getMicroOpFactor() const {
147
47.9M
    return MicroOpFactor;
148
47.9M
  }
149
150
  /// Multiply cycle count by this factor to normalize it relative to
151
  /// other resources. This is the number of resource units per cycle.
152
31.6M
  unsigned getLatencyFactor() const {
153
31.6M
    return ResourceLCM;
154
31.6M
  }
155
156
  /// Number of micro-ops that may be buffered for OOO execution.
157
37.2M
  unsigned getMicroOpBufferSize() const { return SchedModel.MicroOpBufferSize; }
158
159
  /// Number of resource units that may be buffered for OOO execution.
160
  /// \return The buffer size in resource units or -1 for unlimited.
161
  int getResourceBufferSize(unsigned PIdx) const {
162
    return SchedModel.getProcResource(PIdx)->BufferSize;
163
  }
164
165
  /// Compute operand latency based on the available machine model.
166
  ///
167
  /// Compute and return the latency of the given data dependent def and use
168
  /// when the operand indices are already known. UseMI may be NULL for an
169
  /// unknown user.
170
  unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx,
171
                                 const MachineInstr *UseMI, unsigned UseOperIdx)
172
    const;
173
174
  /// Compute the instruction latency based on the available machine
175
  /// model.
176
  ///
177
  /// Compute and return the expected latency of this instruction independent of
178
  /// a particular use. computeOperandLatency is the preferred API, but this is
179
  /// occasionally useful to help estimate instruction cost.
180
  ///
181
  /// If UseDefaultDefLatency is false and no new machine sched model is
182
  /// present this method falls back to TII->getInstrLatency with an empty
183
  /// instruction itinerary (this is so we preserve the previous behavior of the
184
  /// if converter after moving it to TargetSchedModel).
185
  unsigned computeInstrLatency(const MachineInstr *MI,
186
                               bool UseDefaultDefLatency = true) const;
187
  unsigned computeInstrLatency(const MCInst &Inst) const;
188
  unsigned computeInstrLatency(unsigned Opcode) const;
189
190
191
  /// Output dependency latency of a pair of defs of the same register.
192
  ///
193
  /// This is typically one cycle.
194
  unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefOperIdx,
195
                                const MachineInstr *DepMI) const;
196
197
  /// Compute the reciprocal throughput of the given instruction.
198
  double computeReciprocalThroughput(const MachineInstr *MI) const;
199
  double computeReciprocalThroughput(const MCInst &MI) const;
200
  double computeReciprocalThroughput(unsigned Opcode) const;
201
};
202
203
} // end namespace llvm
204
205
#endif // LLVM_CODEGEN_TARGETSCHEDULE_H