Line data Source code
1 : //===- 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 :
18 : namespace llvm {
19 :
20 : class MCAsmLayout;
21 : class MCCodePaddingPolicy;
22 : class MCFragment;
23 : class MCInst;
24 : class MCObjectStreamer;
25 : class MCSection;
26 :
27 : typedef SmallVector<const MCPaddingFragment *, 8> MCPFRange;
28 :
29 : struct MCCodePaddingContext {
30 : bool IsPaddingActive;
31 : 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.
39 : class 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 :
65 : protected:
66 : /// The current streamer, used to stream code padding.
67 : MCObjectStreamer *OS;
68 :
69 : bool addPolicy(MCCodePaddingPolicy *Policy);
70 :
71 : virtual bool
72 3047534 : basicBlockRequiresInsertionPoint(const MCCodePaddingContext &Context) {
73 3047534 : return false;
74 : }
75 :
76 30136953 : virtual bool instructionRequiresInsertionPoint(const MCInst &Inst) {
77 30136953 : return false;
78 : }
79 :
80 3047534 : virtual bool usePoliciesForBasicBlock(const MCCodePaddingContext &Context) {
81 3047534 : return Context.IsPaddingActive;
82 : }
83 :
84 : public:
85 35150 : MCCodePadder()
86 35150 : : ArePoliciesActive(false), CurrHandledInstFragment(nullptr),
87 70300 : 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.
127 : class MCCodePaddingPolicy {
128 : MCCodePaddingPolicy() = delete;
129 : MCCodePaddingPolicy(const MCCodePaddingPolicy &) = delete;
130 : void operator=(const MCCodePaddingPolicy &) = delete;
131 :
132 : protected:
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 :
197 : public:
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 0 : uint64_t getKindMask() const { return KindMask; }
203 : /// Returns the instruction window size relevant to this policy.
204 0 : 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 0 : basicBlockRequiresPaddingFragment(const MCCodePaddingContext &Context) const {
217 0 : 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 0 : virtual bool instructionRequiresPaddingFragment(const MCInst &Inst) const {
225 0 : 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
|