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