1 //===- llvm/MC/CodePadder.h - MC Code Padder --------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_MC_MCCODEPADDER_H
11 #define LLVM_MC_MCCODEPADDER_H
13 #include "MCFragment.h"
14 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/ADT/SmallPtrSet.h"
16 #include "llvm/ADT/SmallVector.h"
21 class MCCodePaddingPolicy;
24 class MCObjectStreamer;
27 typedef SmallVector<const MCPaddingFragment *, 8> MCPFRange;
29 struct MCCodePaddingContext {
31 bool IsBasicBlockInsideInnermostLoop;
32 bool IsBasicBlockReachableViaFallthrough;
33 bool IsBasicBlockReachableViaBranch;
36 /// Target-independent base class incharge of all code padding decisions for a
37 /// target. During encoding it determines if and where MCPaddingFragments will
38 /// be located, as later on, when layout information is available, it determines
41 MCCodePadder(const MCCodePadder &) = delete;
42 void operator=(const MCCodePadder &) = delete;
44 /// Determines if the MCCodePaddingPolicies are active.
45 bool ArePoliciesActive;
47 /// All the supported MCCodePaddingPolicies.
48 SmallPtrSet<MCCodePaddingPolicy *, 4> CodePaddingPolicies;
50 /// A pointer to the fragment of the instruction whose padding is currently
52 MCPaddingFragment *CurrHandledInstFragment;
54 /// A map holding the jurisdiction for each padding fragment. Key: padding
55 /// fragment. Value: The fragment's jurisdiction. A jurisdiction is a vector
56 /// of padding fragments whose conditions are being controlled by another
57 /// fragment, the key fragment.
58 DenseMap<MCPaddingFragment *, MCPFRange> FragmentToJurisdiction;
59 MCPFRange &getJurisdiction(MCPaddingFragment *Fragment, MCAsmLayout &Layout);
61 /// A map holding the maximal instruction window size relevant for a padding
63 DenseMap<MCPaddingFragment *, uint64_t> FragmentToMaxWindowSize;
64 uint64_t getMaxWindowSize(MCPaddingFragment *Fragment, MCAsmLayout &Layout);
67 /// The current streamer, used to stream code padding.
70 bool addPolicy(MCCodePaddingPolicy *Policy);
73 basicBlockRequiresInsertionPoint(const MCCodePaddingContext &Context) {
77 virtual bool instructionRequiresInsertionPoint(const MCInst &Inst) {
81 virtual bool usePoliciesForBasicBlock(const MCCodePaddingContext &Context) {
82 return Context.IsPaddingActive;
87 : ArePoliciesActive(false), CurrHandledInstFragment(nullptr),
89 virtual ~MCCodePadder();
91 /// Handles all target related code padding when starting to write a new
92 /// basic block to an object file.
94 /// \param OS The streamer used for writing the padding data and function.
95 /// \param Context the context of the padding, Embeds the basic block's
97 void handleBasicBlockStart(MCObjectStreamer *OS,
98 const MCCodePaddingContext &Context);
99 /// Handles all target related code padding when done writing a block to an
102 /// \param Context the context of the padding, Embeds the basic block's
104 void handleBasicBlockEnd(const MCCodePaddingContext &Context);
105 /// Handles all target related code padding before writing a new instruction
106 /// to an object file.
108 /// \param Inst the instruction.
109 void handleInstructionBegin(const MCInst &Inst);
110 /// Handles all target related code padding after writing an instruction to an
113 /// \param Inst the instruction.
114 void handleInstructionEnd(const MCInst &Inst);
116 /// Relaxes a fragment (changes the size of the padding) according to target
117 /// requirements. The new size computation is done w.r.t a layout.
119 /// \param Fragment The fragment to relax.
120 /// \param Layout Code layout information.
122 /// \returns true iff any relaxation occured.
123 bool relaxFragment(MCPaddingFragment *Fragment, MCAsmLayout &Layout);
126 /// The base class for all padding policies, i.e. a rule or set of rules to pad
127 /// the generated code.
128 class MCCodePaddingPolicy {
129 MCCodePaddingPolicy() = delete;
130 MCCodePaddingPolicy(const MCCodePaddingPolicy &) = delete;
131 void operator=(const MCCodePaddingPolicy &) = delete;
134 /// A mask holding the kind of this policy, i.e. only the i'th bit will be set
135 /// where i is the kind number.
136 const uint64_t KindMask;
137 /// Instruction window size relevant to this policy.
138 const uint64_t WindowSize;
139 /// A boolean indicating which byte of the instruction determies its
140 /// instruction window. If true - the last byte of the instructions, o.w. -
141 /// the first byte of the instruction.
142 const bool InstByteIsLastByte;
144 MCCodePaddingPolicy(uint64_t Kind, uint64_t WindowSize,
145 bool InstByteIsLastByte)
146 : KindMask(UINT64_C(1) << Kind), WindowSize(WindowSize),
147 InstByteIsLastByte(InstByteIsLastByte) {}
149 /// Computes and returns the offset of the consecutive fragment of a given
152 /// \param Fragment The fragment whose consecutive offset will be computed.
153 /// \param Layout Code layout information.
155 /// \returns the offset of the consecutive fragment of \p Fragment.
156 static uint64_t getNextFragmentOffset(const MCFragment *Fragment,
157 const MCAsmLayout &Layout);
158 /// Returns the instruction byte of an instruction pointed by a given
159 /// MCPaddingFragment. An instruction byte is the address of the byte of an
160 /// instruction which determines its instruction window.
162 /// \param Fragment The fragment pointing to the instruction.
163 /// \param Layout Code layout information.
165 /// \returns the instruction byte of an instruction pointed by \p Fragment.
166 uint64_t getFragmentInstByte(const MCPaddingFragment *Fragment,
167 MCAsmLayout &Layout) const;
168 uint64_t computeWindowEndAddress(const MCPaddingFragment *Fragment,
169 uint64_t Offset, MCAsmLayout &Layout) const;
171 /// Computes and returns the penalty weight of a first instruction window in a
172 /// range. This requires a special function since the first window does not
173 /// contain all the padding fragments in that window. It only contains all the
174 /// padding fragments starting from the relevant insertion point.
176 /// \param Window The first window.
177 /// \param Offset The offset of the parent section relative to the beginning
178 /// of the file, mod the window size.
179 /// \param Layout Code layout information.
181 /// \returns the penalty weight of a first instruction window in a range, \p
183 double computeFirstWindowPenaltyWeight(const MCPFRange &Window,
185 MCAsmLayout &Layout) const;
186 /// Computes and returns the penalty caused by an instruction window.
188 /// \param Window The instruction window.
189 /// \param Offset The offset of the parent section relative to the beginning
190 /// of the file, mod the window size.
191 /// \param Layout Code layout information.
193 /// \returns the penalty caused by \p Window.
194 virtual double computeWindowPenaltyWeight(const MCPFRange &Window,
196 MCAsmLayout &Layout) const = 0;
199 virtual ~MCCodePaddingPolicy() {}
201 /// Returns the kind mask of this policy - A mask holding the kind of this
202 /// policy, i.e. only the i'th bit will be set where i is the kind number.
203 uint64_t getKindMask() const { return KindMask; }
204 /// Returns the instruction window size relevant to this policy.
205 uint64_t getWindowSize() const { return WindowSize; }
206 /// Returns true if the last byte of an instruction determines its instruction
207 /// window, or false if the first of an instruction determines it.
208 bool isInstByteLastByte() const { return InstByteIsLastByte; }
210 /// Returns true iff this policy needs padding for a given basic block.
212 /// \param Context the context of the padding, Embeds the basic block's
215 /// \returns true iff this policy needs padding for the basic block.
217 basicBlockRequiresPaddingFragment(const MCCodePaddingContext &Context) const {
220 /// Returns true iff this policy needs padding for a given instruction.
222 /// \param Inst The given instruction.
224 /// \returns true iff this policy needs padding for \p Inst.
225 virtual bool instructionRequiresPaddingFragment(const MCInst &Inst) const {
228 /// Computes and returns the penalty caused by a range of instruction windows.
229 /// The weight is computed for each window separelty and then accumulated.
231 /// \param Range The range.
232 /// \param Offset The offset of the parent section relative to the beginning
233 /// of the file, mod the window size.
234 /// \param Layout Code layout information.
236 /// \returns the penalty caused by \p Range.
237 double computeRangePenaltyWeight(const MCPFRange &Range, uint64_t Offset,
238 MCAsmLayout &Layout) const;
243 #endif // LLVM_MC_MCCODEPADDER_H