]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/MC/MCCodePadder.h
MFV r353630: 10809 Performance optimization of AVL tree comparator functions
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / MC / MCCodePadder.h
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   basicBlockRequiresInsertionPoint(const MCCodePaddingContext &Context) {
72     return false;
73   }
74
75   virtual bool instructionRequiresInsertionPoint(const MCInst &Inst) {
76     return false;
77   }
78
79   virtual bool usePoliciesForBasicBlock(const MCCodePaddingContext &Context) {
80     return Context.IsPaddingActive;
81   }
82
83 public:
84   MCCodePadder()
85       : ArePoliciesActive(false), CurrHandledInstFragment(nullptr),
86         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   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; }
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   basicBlockRequiresPaddingFragment(const MCCodePaddingContext &Context) const {
216     return false;
217   }
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   virtual bool instructionRequiresPaddingFragment(const MCInst &Inst) const {
224     return false;
225   }
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