
The being-removed PNaCl has a Software Fault Isolation mechanism, which requires that certain instructions and groups of instructions do not cross a bundle boundary. When `.bundle_align_mode` is in effect, each instruction is placed in its own fragment, allowing flexible NOP padding. This feature has significantly complicated our refactoring of MCStreamer and MCFragment, leading to considerable effort spent untangling it (including flushPendingLabels (75006466296ed4b0f845cbbec4bf77c21de43b40), MCAssembler iteration improvement, and recent MCFragment refactoring). * Make MCObjectStreamer::emitInstToData non-virtual and delete MCELFStreamer::emitInstTodata * Delete MCELFStreamer::emitValueImpl and emitValueToAlignment Minor instructions:u decrease for both -O0 -g and -O3 builds https://llvm-compile-time-tracker.com/compare.php?from=c06d3a7b728293cbc53ff91239d6cd87c0982ffb&to=9b078c7f228bc5b6cdbfe839f751c9407f8aec3e&stat=instructions:u Pull Request: https://github.com/llvm/llvm-project/pull/148781
98 lines
3.2 KiB
C++
98 lines
3.2 KiB
C++
//===- lib/MC/MCSection.cpp - Machine Code Section Representation ---------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/MC/MCSection.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/Config/llvm-config.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCSymbol.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <utility>
|
|
|
|
using namespace llvm;
|
|
|
|
MCSection::MCSection(SectionVariant V, StringRef Name, bool IsText,
|
|
bool IsVirtual, MCSymbol *Begin)
|
|
: Begin(Begin), HasInstructions(false), IsRegistered(false), IsText(IsText),
|
|
IsVirtual(IsVirtual), LinkerRelaxable(false), Name(Name), Variant(V) {
|
|
// The initial subsection number is 0. Create a fragment list.
|
|
CurFragList = &Subsections.emplace_back(0u, FragList{}).second;
|
|
}
|
|
|
|
MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
|
|
if (!End)
|
|
End = Ctx.createTempSymbol("sec_end");
|
|
return End;
|
|
}
|
|
|
|
bool MCSection::hasEnded() const { return End && End->isInSection(); }
|
|
|
|
StringRef MCSection::getVirtualSectionKind() const { return "virtual"; }
|
|
|
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
|
LLVM_DUMP_METHOD void MCSection::dump(
|
|
DenseMap<const MCFragment *, SmallVector<const MCSymbol *, 0>> *FragToSyms)
|
|
const {
|
|
raw_ostream &OS = errs();
|
|
|
|
OS << "MCSection Name:" << getName();
|
|
for (auto &F : *this) {
|
|
OS << '\n';
|
|
F.dump();
|
|
if (!FragToSyms)
|
|
continue;
|
|
auto It = FragToSyms->find(&F);
|
|
if (It == FragToSyms->end())
|
|
continue;
|
|
for (auto *Sym : It->second) {
|
|
OS << "\n Symbol @" << Sym->getOffset() << ' ' << Sym->getName();
|
|
if (Sym->isTemporary())
|
|
OS << " Temporary";
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void MCEncodedFragment::setContents(ArrayRef<char> Contents) {
|
|
auto &S = getParent()->ContentStorage;
|
|
if (ContentStart + Contents.size() > ContentEnd) {
|
|
ContentStart = S.size();
|
|
S.resize_for_overwrite(S.size() + Contents.size());
|
|
}
|
|
ContentEnd = ContentStart + Contents.size();
|
|
llvm::copy(Contents, S.begin() + ContentStart);
|
|
}
|
|
|
|
void MCEncodedFragment::addFixup(MCFixup Fixup) { appendFixups({Fixup}); }
|
|
|
|
void MCEncodedFragment::appendFixups(ArrayRef<MCFixup> Fixups) {
|
|
auto &S = getParent()->FixupStorage;
|
|
if (LLVM_UNLIKELY(FixupEnd != S.size())) {
|
|
// Move the elements to the end. Reserve space to avoid invalidating
|
|
// S.begin()+I for `append`.
|
|
auto Size = FixupEnd - FixupStart;
|
|
auto I = std::exchange(FixupStart, S.size());
|
|
S.reserve(S.size() + Size);
|
|
S.append(S.begin() + I, S.begin() + I + Size);
|
|
}
|
|
S.append(Fixups.begin(), Fixups.end());
|
|
FixupEnd = S.size();
|
|
}
|
|
|
|
void MCEncodedFragment::setFixups(ArrayRef<MCFixup> Fixups) {
|
|
auto &S = getParent()->FixupStorage;
|
|
if (FixupStart + Fixups.size() > FixupEnd) {
|
|
FixupStart = S.size();
|
|
S.resize_for_overwrite(S.size() + Fixups.size());
|
|
}
|
|
FixupEnd = FixupStart + Fixups.size();
|
|
llvm::copy(Fixups, S.begin() + FixupStart);
|
|
}
|