24 for (
auto *Policy : CodePaddingPolicies)
29 assert(Policy &&
"Policy must be valid");
30 return CodePaddingPolicies.insert(Policy).second;
35 assert(OS !=
nullptr &&
"OS must be valid");
36 assert(this->OS ==
nullptr &&
"Still handling another basic block");
44 "Cannot insert padding nops right after an alignment fragment as it " 45 "will ruin the alignment");
48 if (ArePoliciesActive) {
49 PoliciesMask = std::accumulate(
50 CodePaddingPolicies.begin(), CodePaddingPolicies.end(),
54 return Policy->basicBlockRequiresPaddingFragment(Context)
55 ? (Mask | Policy->getKindMask())
70 assert(this->
OS !=
nullptr &&
"Not handling a basic block");
78 assert(CurrHandledInstFragment ==
nullptr &&
"Can't start handling an " 79 "instruction while still " 80 "handling another instruction");
85 "Cannot insert padding nops right after an alignment fragment as it " 86 "will ruin the alignment");
89 if (ArePoliciesActive) {
90 PoliciesMask = std::accumulate(
91 CodePaddingPolicies.begin(), CodePaddingPolicies.end(),
94 return Policy->instructionRequiresPaddingFragment(Inst)
95 ? (Mask | Policy->getKindMask())
103 bool needToUpdateCurrFragment =
104 CurrFragment !=
nullptr &&
107 needToUpdateCurrFragment) {
121 if (CurrHandledInstFragment ==
nullptr)
126 dyn_cast_or_null<MCDataFragment>(InstFragment))
132 Inst, InstDataFragment->getContents().
size());
134 dyn_cast_or_null<MCRelaxableFragment>(InstFragment))
139 InstRelaxableFragment);
142 "either a MCDataFragment or a MCRelaxableFragment");
144 CurrHandledInstFragment =
nullptr;
149 auto JurisdictionLocation = FragmentToJurisdiction.find(Fragment);
150 if (JurisdictionLocation != FragmentToJurisdiction.end())
151 return JurisdictionLocation->second;
157 for (
MCFragment *CurrFragment = Fragment; CurrFragment !=
nullptr;
162 if (CurrPaddingFragment ==
nullptr)
165 if (CurrPaddingFragment != Fragment &&
169 for (
const auto *Policy : CodePaddingPolicies) {
171 Jurisdiction.push_back(CurrPaddingFragment);
177 auto InsertionResult =
178 FragmentToJurisdiction.insert(std::make_pair(Fragment, Jurisdiction));
179 assert(InsertionResult.second &&
180 "Insertion to FragmentToJurisdiction failed");
181 return InsertionResult.first->second;
186 auto MaxFragmentSizeLocation = FragmentToMaxWindowSize.find(Fragment);
187 if (MaxFragmentSizeLocation != FragmentToMaxWindowSize.end())
188 return MaxFragmentSizeLocation->second;
190 MCPFRange &Jurisdiction = getJurisdiction(Fragment, Layout);
192 for (
const auto *Protege : Jurisdiction)
193 JurisdictionMask |= Protege->getPaddingPoliciesMask();
195 uint64_t MaxFragmentSize = UINT64_C(0);
196 for (
const auto *Policy : CodePaddingPolicies)
197 if ((JurisdictionMask & Policy->getKindMask()) !=
199 MaxFragmentSize =
std::max(MaxFragmentSize, Policy->getWindowSize());
201 auto InsertionResult =
202 FragmentToMaxWindowSize.insert(std::make_pair(Fragment, MaxFragmentSize));
203 assert(InsertionResult.second &&
204 "Insertion to FragmentToMaxWindowSize failed");
205 return InsertionResult.first->second;
212 uint64_t OldSize = Fragment->
getSize();
214 uint64_t MaxWindowSize = getMaxWindowSize(Fragment, Layout);
215 if (MaxWindowSize == UINT64_C(0))
218 "MaxWindowSize must be an integer power of 2");
221 "SectionAlignment must be an integer power of 2");
223 MCPFRange &Jurisdiction = getJurisdiction(Fragment, Layout);
224 uint64_t OptimalSize = UINT64_C(0);
226 uint64_t MaxFragmentSize = MaxWindowSize - UINT16_C(1);
227 for (uint64_t
Size = UINT64_C(0);
Size <= MaxFragmentSize; ++
Size) {
230 double SizeWeight = 0.0;
238 for (uint64_t
Offset = UINT64_C(0);
Offset < MaxWindowSize;
239 Offset += SectionAlignment) {
240 double OffsetWeight = std::accumulate(
241 CodePaddingPolicies.begin(), CodePaddingPolicies.end(), 0.0,
242 [&Jurisdiction, &
Offset, &Layout](
244 double PolicyWeight =
245 Policy->computeRangePenaltyWeight(Jurisdiction, Offset, Layout);
246 assert(PolicyWeight >= 0.0 &&
"A penalty weight must be positive");
247 return Weight + PolicyWeight;
249 SizeWeight =
std::max(SizeWeight, OffsetWeight);
251 if (SizeWeight < OptimalWeight) {
252 OptimalWeight = SizeWeight;
255 if (OptimalWeight == 0.0)
259 Fragment->
setSize(OptimalSize);
261 return OldSize != OptimalSize;
270 assert(Fragment !=
nullptr &&
"Fragment cannot be null");
272 return NextFragment ==
nullptr 280 uint64_t InstByte = getNextFragmentOffset(Fragment, Layout);
281 if (InstByteIsLastByte)
290 uint64_t InstByte = getFragmentInstByte(Fragment, Layout);
291 return alignTo(InstByte + UINT64_C(1) + Offset, WindowSize) -
Offset;
302 uint64_t FragmentWindowEndAddress =
303 computeWindowEndAddress(Fragment, Offset, Layout);
304 if (CurrWindowLocation == Windows.
end() ||
305 FragmentWindowEndAddress !=
306 computeWindowEndAddress(*CurrWindowLocation->
begin(),
Offset,
310 CurrWindowLocation = Windows.
end() - 1;
318 double RangeWeight = 0.0;
320 RangeWeight += computeFirstWindowPenaltyWeight(*I, Offset, Layout);
322 RangeWeight += std::accumulate(
323 I, Windows.
end(), 0.0,
325 return Weight += computeWindowPenaltyWeight(Window, Offset, Layout);
334 uint64_t WindowEndAddress =
335 computeWindowEndAddress(*Window.
begin(),
Offset, Layout);
342 Fragment !=
nullptr; Fragment = Fragment->
getPrevNode()) {
345 if (PaddingNopFragment ==
nullptr ||
348 if (WindowEndAddress !=
349 computeWindowEndAddress(PaddingNopFragment, Offset, Layout))
352 FullWindowFirstPart.push_back(PaddingNopFragment);
355 std::reverse(FullWindowFirstPart.begin(), FullWindowFirstPart.end());
356 double FullWindowFirstPartWeight =
357 computeWindowPenaltyWeight(FullWindowFirstPart, Offset, Layout);
360 FullWindowFirstPart);
365 double FullWindowWeight =
366 computeWindowPenaltyWeight(FullWindow, Offset, Layout);
368 assert(FullWindowWeight >= FullWindowFirstPartWeight &&
369 "More fragments necessarily means bigger weight");
370 return FullWindowWeight - FullWindowFirstPartWeight;
Fragment for adding required padding.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This class represents lattice values for constants.
void handleBasicBlockStart(MCObjectStreamer *OS, const MCCodePaddingContext &Context)
Handles all target related code padding when starting to write a new basic block to an object file...
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
void push_back(const T &Elt)
bool relaxFragment(MCPaddingFragment *Fragment, MCAsmLayout &Layout)
Relaxes a fragment (changes the size of the padding) according to target requirements.
FragmentType getKind() const
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
SmallVector< const MCPaddingFragment *, 8 > MCPFRange
bool hasPaddingPolicy(uint64_t PolicyMask) const
MCObjectStreamer * OS
The current streamer, used to stream code padding.
unsigned getAlignment() const
uint64_t getFragmentInstByte(const MCPaddingFragment *Fragment, MCAsmLayout &Layout) const
Returns the instruction byte of an instruction pointed by a given MCPaddingFragment.
Encapsulates the layout of an assembly file at a particular point in time.
double computeRangePenaltyWeight(const MCPFRange &Range, uint64_t Offset, MCAsmLayout &Layout) const
Computes and returns the penalty caused by a range of instruction windows.
The base class for all padding policies, i.e.
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
virtual bool instructionRequiresInsertionPoint(const MCInst &Inst)
void setPaddingPoliciesMask(uint64_t Value)
static const uint64_t PFK_None
Streaming object file generation interface.
void setInstAndInstSize(const MCInst &Inst, size_t InstSize)
void setAsInsertionPoint()
Instances of this class represent a single low-level machine instruction.
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
uint64_t computeWindowEndAddress(const MCPaddingFragment *Fragment, uint64_t Offset, MCAsmLayout &Layout) const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
void invalidateFragmentsFrom(MCFragment *F)
Invalidate the fragments starting with F because it has been resized.
void handleInstructionBegin(const MCInst &Inst)
Handles all target related code padding before writing a new instruction to an object file...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
virtual bool basicBlockRequiresInsertionPoint(const MCCodePaddingContext &Context)
double computeFirstWindowPenaltyWeight(const MCPFRange &Window, uint64_t Offset, MCAsmLayout &Layout) const
Computes and returns the penalty weight of a first instruction window in a range. ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
MCPaddingFragment * getOrCreatePaddingFragment()
bool addPolicy(MCCodePaddingPolicy *Policy)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
uint64_t getPaddingPoliciesMask() const
MCSection * getParent() const
typename SuperClass::iterator iterator
void handleInstructionEnd(const MCInst &Inst)
Handles all target related code padding after writing an instruction to an object file...
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
void setSize(uint64_t Value)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void handleBasicBlockEnd(const MCCodePaddingContext &Context)
Handles all target related code padding when done writing a block to an object file.
LLVM_NODISCARD bool empty() const
size_t getInstSize() const
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
MCFragment * getCurrentFragment() const
Fragment for data and encoded instructions.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isInsertionPoint() const
void setInstAndInstFragment(const MCInst &Inst, MCRelaxableFragment *InstFragment)
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
virtual bool usePoliciesForBasicBlock(const MCCodePaddingContext &Context)
for(unsigned i=Desc.getNumOperands(), e=OldMI.getNumOperands();i !=e;++i)
static uint64_t getNextFragmentOffset(const MCFragment *Fragment, const MCAsmLayout &Layout)
Computes and returns the offset of the consecutive fragment of a given fragment.