1 //===- llvm/MC/MCCodePadder.h - MC Code Padder ------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_MC_MCCODEPADDER_H
10 #define LLVM_MC_MCCODEPADDER_H
12 #include "MCFragment.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/SmallPtrSet.h"
15 #include "llvm/ADT/SmallVector.h"
20 class MCCodePaddingPolicy
;
23 class MCObjectStreamer
;
26 typedef SmallVector
<const MCPaddingFragment
*, 8> MCPFRange
;
28 struct MCCodePaddingContext
{
30 bool IsBasicBlockReachableViaFallthrough
;
31 bool IsBasicBlockReachableViaBranch
;
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
39 MCCodePadder(const MCCodePadder
&) = delete;
40 void operator=(const MCCodePadder
&) = delete;
42 /// Determines if the MCCodePaddingPolicies are active.
43 bool ArePoliciesActive
;
45 /// All the supported MCCodePaddingPolicies.
46 SmallPtrSet
<MCCodePaddingPolicy
*, 4> CodePaddingPolicies
;
48 /// A pointer to the fragment of the instruction whose padding is currently
50 MCPaddingFragment
*CurrHandledInstFragment
;
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
);
59 /// A map holding the maximal instruction window size relevant for a padding
61 DenseMap
<MCPaddingFragment
*, uint64_t> FragmentToMaxWindowSize
;
62 uint64_t getMaxWindowSize(MCPaddingFragment
*Fragment
, MCAsmLayout
&Layout
);
65 /// The current streamer, used to stream code padding.
68 bool addPolicy(MCCodePaddingPolicy
*Policy
);
71 basicBlockRequiresInsertionPoint(const MCCodePaddingContext
&Context
) {
75 virtual bool instructionRequiresInsertionPoint(const MCInst
&Inst
) {
79 virtual bool usePoliciesForBasicBlock(const MCCodePaddingContext
&Context
) {
80 return Context
.IsPaddingActive
;
85 : ArePoliciesActive(false), CurrHandledInstFragment(nullptr),
87 virtual ~MCCodePadder();
89 /// Handles all target related code padding when starting to write a new
90 /// basic block to an object file.
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
95 void handleBasicBlockStart(MCObjectStreamer
*OS
,
96 const MCCodePaddingContext
&Context
);
97 /// Handles all target related code padding when done writing a block to an
100 /// \param Context the context of the padding, Embeds the basic block's
102 void handleBasicBlockEnd(const MCCodePaddingContext
&Context
);
103 /// Handles all target related code padding before writing a new instruction
104 /// to an object file.
106 /// \param Inst the instruction.
107 void handleInstructionBegin(const MCInst
&Inst
);
108 /// Handles all target related code padding after writing an instruction to an
111 /// \param Inst the instruction.
112 void handleInstructionEnd(const MCInst
&Inst
);
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.
117 /// \param Fragment The fragment to relax.
118 /// \param Layout Code layout information.
120 /// \returns true iff any relaxation occurred.
121 bool relaxFragment(MCPaddingFragment
*Fragment
, MCAsmLayout
&Layout
);
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;
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
;
142 MCCodePaddingPolicy(uint64_t Kind
, uint64_t WindowSize
,
143 bool InstByteIsLastByte
)
144 : KindMask(UINT64_C(1) << Kind
), WindowSize(WindowSize
),
145 InstByteIsLastByte(InstByteIsLastByte
) {}
147 /// Computes and returns the offset of the consecutive fragment of a given
150 /// \param Fragment The fragment whose consecutive offset will be computed.
151 /// \param Layout Code layout information.
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.
160 /// \param Fragment The fragment pointing to the instruction.
161 /// \param Layout Code layout information.
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;
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.
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.
179 /// \returns the penalty weight of a first instruction window in a range, \p
181 double computeFirstWindowPenaltyWeight(const MCPFRange
&Window
,
183 MCAsmLayout
&Layout
) const;
184 /// Computes and returns the penalty caused by an instruction window.
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.
191 /// \returns the penalty caused by \p Window.
192 virtual double computeWindowPenaltyWeight(const MCPFRange
&Window
,
194 MCAsmLayout
&Layout
) const = 0;
197 virtual ~MCCodePaddingPolicy() {}
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 uint64_t getKindMask() const { return KindMask
; }
202 /// Returns the instruction window size relevant to this policy.
203 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 bool isInstByteLastByte() const { return InstByteIsLastByte
; }
208 /// Returns true iff this policy needs padding for a given basic block.
210 /// \param Context the context of the padding, Embeds the basic block's
213 /// \returns true iff this policy needs padding for the basic block.
215 basicBlockRequiresPaddingFragment(const MCCodePaddingContext
&Context
) const {
218 /// Returns true iff this policy needs padding for a given instruction.
220 /// \param Inst The given instruction.
222 /// \returns true iff this policy needs padding for \p Inst.
223 virtual bool instructionRequiresPaddingFragment(const MCInst
&Inst
) const {
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.
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.
234 /// \returns the penalty caused by \p Range.
235 double computeRangePenaltyWeight(const MCPFRange
&Range
, uint64_t Offset
,
236 MCAsmLayout
&Layout
) const;
241 #endif // LLVM_MC_MCCODEPADDER_H