Coverage Report

Created: 2019-02-20 00:17

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/MC/MCCodePadder.h
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/MC/MCCodePadder.h - MC Code Padder ------------------*- 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
#ifndef LLVM_MC_MCCODEPADDER_H
10
#define LLVM_MC_MCCODEPADDER_H
11
12
#include "MCFragment.h"
13
#include "llvm/ADT/DenseMap.h"
14
#include "llvm/ADT/SmallPtrSet.h"
15
#include "llvm/ADT/SmallVector.h"
16
17
namespace llvm {
18
19
class MCAsmLayout;
20
class MCCodePaddingPolicy;
21
class MCFragment;
22
class MCInst;
23
class MCObjectStreamer;
24
class MCSection;
25
26
typedef SmallVector<const MCPaddingFragment *, 8> MCPFRange;
27
28
struct MCCodePaddingContext {
29
  bool IsPaddingActive;
30
  bool IsBasicBlockReachableViaFallthrough;
31
  bool IsBasicBlockReachableViaBranch;
32
};
33
34
/// Target-independent base class incharge of all code padding decisions for a
35
/// target. During encoding it determines if and where MCPaddingFragments will
36
/// be located, as later on, when layout information is available, it determines
37
/// their sizes.
38
class MCCodePadder {
39
  MCCodePadder(const MCCodePadder &) = delete;
40
  void operator=(const MCCodePadder &) = delete;
41
42
  /// Determines if the MCCodePaddingPolicies are active.
43
  bool ArePoliciesActive;
44
45
  /// All the supported MCCodePaddingPolicies.
46
  SmallPtrSet<MCCodePaddingPolicy *, 4> CodePaddingPolicies;
47
48
  /// A pointer to the fragment of the instruction whose padding is currently
49
  /// done for.
50
  MCPaddingFragment *CurrHandledInstFragment;
51
52
  /// A map holding the jurisdiction for each padding fragment. Key: padding
53
  /// fragment. Value: The fragment's jurisdiction. A jurisdiction is a vector
54
  /// of padding fragments whose conditions are being controlled by another
55
  /// fragment, the key fragment.
56
  DenseMap<MCPaddingFragment *, MCPFRange> FragmentToJurisdiction;
57
  MCPFRange &getJurisdiction(MCPaddingFragment *Fragment, MCAsmLayout &Layout);
58
59
  /// A map holding the maximal instruction window size relevant for a padding
60
  /// fragment.
61
  DenseMap<MCPaddingFragment *, uint64_t> FragmentToMaxWindowSize;
62
  uint64_t getMaxWindowSize(MCPaddingFragment *Fragment, MCAsmLayout &Layout);
63
64
protected:
65
  /// The current streamer, used to stream code padding.
66
  MCObjectStreamer *OS;
67
68
  bool addPolicy(MCCodePaddingPolicy *Policy);
69
70
  virtual bool
71
2.41M
  basicBlockRequiresInsertionPoint(const MCCodePaddingContext &Context) {
72
2.41M
    return false;
73
2.41M
  }
74
75
17.3M
  virtual bool instructionRequiresInsertionPoint(const MCInst &Inst) {
76
17.3M
    return false;
77
17.3M
  }
78
79
2.41M
  virtual bool usePoliciesForBasicBlock(const MCCodePaddingContext &Context) {
80
2.41M
    return Context.IsPaddingActive;
81
2.41M
  }
82
83
public:
84
  MCCodePadder()
85
      : ArePoliciesActive(false), CurrHandledInstFragment(nullptr),
86
42.8k
        OS(nullptr) {}
87
  virtual ~MCCodePadder();
88
89
  /// Handles all target related code padding when starting to write a new
90
  /// basic block to an object file.
91
  ///
92
  /// \param OS The streamer used for writing the padding data and function.
93
  /// \param Context the context of the padding, Embeds the basic block's
94
  /// parameters.
95
  void handleBasicBlockStart(MCObjectStreamer *OS,
96
                             const MCCodePaddingContext &Context);
97
  /// Handles all target related code padding when done writing a block to an
98
  /// object file.
99
  ///
100
  /// \param Context the context of the padding, Embeds the basic block's
101
  /// parameters.
102
  void handleBasicBlockEnd(const MCCodePaddingContext &Context);
103
  /// Handles all target related code padding before writing a new instruction
104
  /// to an object file.
105
  ///
106
  /// \param Inst the instruction.
107
  void handleInstructionBegin(const MCInst &Inst);
108
  /// Handles all target related code padding after writing an instruction to an
109
  /// object file.
110
  ///
111
  /// \param Inst the instruction.
112
  void handleInstructionEnd(const MCInst &Inst);
113
114
  /// Relaxes a fragment (changes the size of the padding) according to target
115
  /// requirements. The new size computation is done w.r.t a layout.
116
  ///
117
  /// \param Fragment The fragment to relax.
118
  /// \param Layout Code layout information.
119
  ///
120
  /// \returns true iff any relaxation occurred.
121
  bool relaxFragment(MCPaddingFragment *Fragment, MCAsmLayout &Layout);
122
};
123
124
/// The base class for all padding policies, i.e. a rule or set of rules to pad
125
/// the generated code.
126
class MCCodePaddingPolicy {
127
  MCCodePaddingPolicy() = delete;
128
  MCCodePaddingPolicy(const MCCodePaddingPolicy &) = delete;
129
  void operator=(const MCCodePaddingPolicy &) = delete;
130
131
protected:
132
  /// A mask holding the kind of this policy, i.e. only the i'th bit will be set
133
  /// where i is the kind number.
134
  const uint64_t KindMask;
135
  /// Instruction window size relevant to this policy.
136
  const uint64_t WindowSize;
137
  /// A boolean indicating which byte of the instruction determies its
138
  /// instruction window. If true - the last byte of the instructions, o.w. -
139
  /// the first byte of the instruction.
140
  const bool InstByteIsLastByte;
141
142
  MCCodePaddingPolicy(uint64_t Kind, uint64_t WindowSize,
143
                      bool InstByteIsLastByte)
144
      : KindMask(UINT64_C(1) << Kind), WindowSize(WindowSize),
145
        InstByteIsLastByte(InstByteIsLastByte) {}
146
147
  /// Computes and returns the offset of the consecutive fragment of a given
148
  /// fragment.
149
  ///
150
  /// \param Fragment The fragment whose consecutive offset will be computed.
151
  /// \param Layout Code layout information.
152
  ///
153
  /// \returns the offset of the consecutive fragment of \p Fragment.
154
  static uint64_t getNextFragmentOffset(const MCFragment *Fragment,
155
                                        const MCAsmLayout &Layout);
156
  /// Returns the instruction byte of an instruction pointed by a given
157
  /// MCPaddingFragment. An instruction byte is the address of the byte of an
158
  /// instruction which determines its instruction window.
159
  ///
160
  /// \param Fragment The fragment pointing to the instruction.
161
  /// \param Layout Code layout information.
162
  ///
163
  /// \returns the instruction byte of an instruction pointed by \p Fragment.
164
  uint64_t getFragmentInstByte(const MCPaddingFragment *Fragment,
165
                               MCAsmLayout &Layout) const;
166
  uint64_t computeWindowEndAddress(const MCPaddingFragment *Fragment,
167
                                   uint64_t Offset, MCAsmLayout &Layout) const;
168
169
  /// Computes and returns the penalty weight of a first instruction window in a
170
  /// range. This requires a special function since the first window does not
171
  /// contain all the padding fragments in that window. It only contains all the
172
  /// padding fragments starting from the relevant insertion point.
173
  ///
174
  /// \param Window The first window.
175
  /// \param Offset The offset of the parent section relative to the beginning
176
  /// of the file, mod the window size.
177
  /// \param Layout Code layout information.
178
  ///
179
  /// \returns the penalty weight of a first instruction window in a range, \p
180
  /// Window.
181
  double computeFirstWindowPenaltyWeight(const MCPFRange &Window,
182
                                         uint64_t Offset,
183
                                         MCAsmLayout &Layout) const;
184
  /// Computes and returns the penalty caused by an instruction window.
185
  ///
186
  /// \param Window The instruction window.
187
  /// \param Offset The offset of the parent section relative to the beginning
188
  /// of the file, mod the window size.
189
  /// \param Layout Code layout information.
190
  ///
191
  /// \returns the penalty caused by \p Window.
192
  virtual double computeWindowPenaltyWeight(const MCPFRange &Window,
193
                                            uint64_t Offset,
194
                                            MCAsmLayout &Layout) const = 0;
195
196
public:
197
  virtual ~MCCodePaddingPolicy() {}
198
199
  /// Returns the kind mask of this policy -  A mask holding the kind of this
200
  /// policy, i.e. only the i'th bit will be set where i is the kind number.
201
0
  uint64_t getKindMask() const { return KindMask; }
202
  /// Returns the instruction window size relevant to this policy.
203
0
  uint64_t getWindowSize() const { return WindowSize; }
204
  /// Returns true if the last byte of an instruction determines its instruction
205
  /// window, or false if the first of an instruction determines it.
206
0
  bool isInstByteLastByte() const { return InstByteIsLastByte; }
207
208
  /// Returns true iff this policy needs padding for a given basic block.
209
  ///
210
  /// \param Context the context of the padding, Embeds the basic block's
211
  /// parameters.
212
  ///
213
  /// \returns true iff this policy needs padding for the basic block.
214
  virtual bool
215
0
  basicBlockRequiresPaddingFragment(const MCCodePaddingContext &Context) const {
216
0
    return false;
217
0
  }
218
  /// Returns true iff this policy needs padding for a given instruction.
219
  ///
220
  /// \param Inst The given instruction.
221
  ///
222
  /// \returns true iff this policy needs padding for \p Inst.
223
0
  virtual bool instructionRequiresPaddingFragment(const MCInst &Inst) const {
224
0
    return false;
225
0
  }
226
  /// Computes and returns the penalty caused by a range of instruction windows.
227
  /// The weight is computed for each window separelty and then accumulated.
228
  ///
229
  /// \param Range The range.
230
  /// \param Offset The offset of the parent section relative to the beginning
231
  /// of the file, mod the window size.
232
  /// \param Layout Code layout information.
233
  ///
234
  /// \returns the penalty caused by \p Range.
235
  double computeRangePenaltyWeight(const MCPFRange &Range, uint64_t Offset,
236
                                   MCAsmLayout &Layout) const;
237
};
238
239
} // namespace llvm
240
241
#endif // LLVM_MC_MCCODEPADDER_H