13#include "llvm/Config/llvm-config.h"
35 if (!Sec.isVirtualSection())
36 SectionOrder.push_back(&Sec);
38 if (Sec.isVirtualSection())
39 SectionOrder.push_back(&Sec);
42bool MCAsmLayout::isFragmentValid(
const MCFragment *
F)
const {
44 const MCFragment *LastValid = LastValidFragment.lookup(Sec);
54 if (
MCFragment *LastValid = LastValidFragment[Sec]) {
64 if (FirstInvalidFragment->IsBeingLaidOut)
72 if (!isFragmentValid(
F))
77 LastValidFragment[
F->getParent()] =
F->getPrevNode();
80void MCAsmLayout::ensureValid(
const MCFragment *
F)
const {
89 while (!isFragmentValid(
F)) {
90 assert(
I != Sec->end() &&
"Layout bookkeeping error");
98 assert(
F->Offset != ~UINT64_C(0) &&
"Address not set!");
163 if (!Symbol.isVariable())
166 const MCExpr *Expr = Symbol.getVariableValue();
170 Expr->
getLoc(),
"expression could not be evaluated");
178 "' could not be evaluated in a subtraction expression");
189 Asm.getContext().reportError(Expr->
getLoc(),
190 "Common symbol '" + ASym.
getName() +
191 "' cannot be used in assignment expr");
218 "computeBundlePadding should only be called if bundling is enabled");
219 uint64_t BundleMask = BundleSize - 1;
220 uint64_t OffsetInBundle = FOffset & BundleMask;
221 uint64_t EndOfFragment = OffsetInBundle + FSize;
230 if (
F->alignToBundleEnd()) {
241 if (EndOfFragment == BundleSize)
243 else if (EndOfFragment < BundleSize)
244 return BundleSize - EndOfFragment;
246 return 2 * BundleSize - EndOfFragment;
248 }
else if (OffsetInBundle > 0 && EndOfFragment > BundleSize)
249 return BundleSize - OffsetInBundle;
260 : Parent(Parent), Atom(nullptr),
Offset(~UINT64_C(0)), LayoutOrder(0),
261 Kind(Kind), IsBeingLaidOut(
false), HasInstructions(HasInstructions) {
262 if (Parent && !isa<MCDummyFragment>(*
this))
275 delete cast<MCAlignFragment>(
this);
278 delete cast<MCDataFragment>(
this);
281 delete cast<MCCompactEncodedInstFragment>(
this);
284 delete cast<MCFillFragment>(
this);
287 delete cast<MCNopsFragment>(
this);
290 delete cast<MCRelaxableFragment>(
this);
293 delete cast<MCOrgFragment>(
this);
296 delete cast<MCDwarfLineAddrFragment>(
this);
299 delete cast<MCDwarfCallFrameFragment>(
this);
302 delete cast<MCLEBFragment>(
this);
305 delete cast<MCBoundaryAlignFragment>(
this);
308 delete cast<MCSymbolIdFragment>(
this);
311 delete cast<MCCVInlineLineTableFragment>(
this);
314 delete cast<MCCVDefRangeFragment>(
this);
317 delete cast<MCPseudoProbeAddrFragment>(
this);
320 delete cast<MCDummyFragment>(
this);
332 <<
" Kind:" << AF.
getKind() <<
">";
338#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
347 OS <<
"MCCompactEncodedInstFragment";
break;
350 OS <<
"MCFNopsFragment";
362 OS <<
"MCPseudoProbe";
367 OS <<
"<MCFragment " << (
const void *)
this <<
" LayoutOrder:" << LayoutOrder
369 if (
const auto *EF = dyn_cast<MCEncodedFragment>(
this))
370 OS <<
" BundlePadding:" <<
static_cast<unsigned>(EF->getBundlePadding());
375 const auto *AF = cast<MCAlignFragment>(
this);
376 if (AF->hasEmitNops())
377 OS <<
" (emit nops)";
379 OS <<
" Alignment:" << AF->getAlignment().value()
380 <<
" Value:" << AF->getValue() <<
" ValueSize:" << AF->getValueSize()
381 <<
" MaxBytesToEmit:" << AF->getMaxBytesToEmit() <<
">";
385 const auto *
DF = cast<MCDataFragment>(
this);
389 for (
unsigned i = 0, e = Contents.
size(); i != e; ++i) {
391 OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
393 OS <<
"] (" << Contents.
size() <<
" bytes)";
395 if (
DF->fixup_begin() !=
DF->fixup_end()) {
399 ie =
DF->fixup_end(); it != ie; ++it) {
400 if (it !=
DF->fixup_begin())
OS <<
",\n ";
409 cast<MCCompactEncodedInstFragment>(
this);
413 for (
unsigned i = 0, e = Contents.
size(); i != e; ++i) {
415 OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
417 OS <<
"] (" << Contents.
size() <<
" bytes)";
421 const auto *FF = cast<MCFillFragment>(
this);
422 OS <<
" Value:" <<
static_cast<unsigned>(FF->getValue())
423 <<
" ValueSize:" <<
static_cast<unsigned>(FF->getValueSize())
424 <<
" NumValues:" << FF->getNumValues();
428 const auto *NF = cast<MCNopsFragment>(
this);
429 OS <<
" NumBytes:" << NF->getNumBytes()
430 <<
" ControlledNopLength:" << NF->getControlledNopLength();
434 const auto *
F = cast<MCRelaxableFragment>(
this);
437 F->getInst().dump_pretty(
OS);
438 OS <<
" (" <<
F->getContents().size() <<
" bytes)";
442 const auto *OF = cast<MCOrgFragment>(
this);
444 OS <<
" Offset:" << OF->getOffset()
445 <<
" Value:" <<
static_cast<unsigned>(OF->getValue());
449 const auto *OF = cast<MCDwarfLineAddrFragment>(
this);
451 OS <<
" AddrDelta:" << OF->getAddrDelta()
452 <<
" LineDelta:" << OF->getLineDelta();
456 const auto *CF = cast<MCDwarfCallFrameFragment>(
this);
458 OS <<
" AddrDelta:" << CF->getAddrDelta();
462 const auto *LF = cast<MCLEBFragment>(
this);
464 OS <<
" Value:" << LF->getValue() <<
" Signed:" << LF->isSigned();
468 const auto *BF = cast<MCBoundaryAlignFragment>(
this);
470 OS <<
" BoundarySize:" << BF->getAlignment().value()
471 <<
" LastFragment:" << BF->getLastFragment()
472 <<
" Size:" << BF->getSize();
476 const auto *
F = cast<MCSymbolIdFragment>(
this);
478 OS <<
" Sym:" <<
F->getSymbol();
482 const auto *
F = cast<MCCVInlineLineTableFragment>(
this);
484 OS <<
" Sym:" << *
F->getFnStartSym();
488 const auto *
F = cast<MCCVDefRangeFragment>(
this);
490 for (std::pair<const MCSymbol *, const MCSymbol *> RangeStartEnd :
492 OS <<
" RangeStart:" << RangeStartEnd.first;
493 OS <<
" RangeEnd:" << RangeStartEnd.second;
498 const auto *OF = cast<MCPseudoProbeAddrFragment>(
this);
500 OS <<
" AddrDelta:" << OF->getAddrDelta();
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S, bool ReportError, uint64_t &Val)
static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S, bool ReportError, uint64_t &Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Encapsulates the layout of an assembly file at a particular point in time.
void invalidateFragmentsFrom(MCFragment *F)
Invalidate the fragments starting with F because it has been resized.
const MCSymbol * getBaseSymbol(const MCSymbol &Symbol) const
If this symbol is equivalent to A + Constant, return A.
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
uint64_t getSectionFileSize(const MCSection *Sec) const
Get the data size of the given section, as emitted to the object file.
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
MCAsmLayout(MCAssembler &Assembler)
void layoutFragment(MCFragment *Fragment)
Perform layout for a single fragment, assuming that the previous fragment has already been laid out c...
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
bool canGetFragmentOffset(const MCFragment *F) const
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
MCContext & getContext() const
unsigned getBundleAlignSize() const
uint64_t computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const
Compute the effective fragment size assuming it is laid out at the given SectionAddress and FragmentO...
void reportError(SMLoc L, const Twine &Msg)
SmallVectorImpl< MCFixup >::const_iterator const_fixup_iterator
Interface implemented by fragments that contain encoded instructions and/or data.
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const
Try to evaluate the expression to the form (a - b + constant) where neither a nor b are variables.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
const MCExpr * getValue() const
uint32_t getOffset() const
MCFixupKind getKind() const
FragmentType getKind() const
unsigned getLayoutOrder() const
void destroy()
Destroys the current fragment.
MCSection * getParent() const
bool hasInstructions() const
Does this fragment have instructions emitted into it? By default this is false, but specific fragment...
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSection::FragmentListType & getFragmentList()
virtual bool isVirtualSection() const =0
Check whether this section is "virtual", that is has no actual object file contents.
FragmentListType::iterator iterator
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
bool isCommon() const
Is this a 'common' symbol.
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
uint64_t getOffset() const
MCFragment * getFragment(bool SetUsed=true) const
This represents an "assembler immediate".
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
void push_back(pointer val)
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCEncodedFragment *F, uint64_t FOffset, uint64_t FSize)
Compute the amount of padding required before the fragment F to obey bundling restrictions,...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
static void deleteNode(NodeTy *V)