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