• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
basicBlockRequiresInsertionPoint(const MCCodePaddingContext & Context)72   basicBlockRequiresInsertionPoint(const MCCodePaddingContext &Context) {
73     return false;
74   }
75 
instructionRequiresInsertionPoint(const MCInst & Inst)76   virtual bool instructionRequiresInsertionPoint(const MCInst &Inst) {
77     return false;
78   }
79 
usePoliciesForBasicBlock(const MCCodePaddingContext & Context)80   virtual bool usePoliciesForBasicBlock(const MCCodePaddingContext &Context) {
81     return Context.IsPaddingActive;
82   }
83 
84 public:
MCCodePadder()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.
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 
MCCodePaddingPolicy(uint64_t Kind,uint64_t WindowSize,bool InstByteIsLastByte)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:
~MCCodePaddingPolicy()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.
getKindMask()202   uint64_t getKindMask() const { return KindMask; }
203   /// Returns the instruction window size relevant to this policy.
getWindowSize()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.
isInstByteLastByte()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
basicBlockRequiresPaddingFragment(const MCCodePaddingContext & Context)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.
instructionRequiresPaddingFragment(const MCInst & 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
243