Skip to content

[BOLT][NFC] Log through JournalingStreams #81524

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 47 additions & 4 deletions bolt/include/bolt/Core/BinaryContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,35 @@ class FilterIterator {
}
};

/// BOLT-exclusive errors generated in core BOLT libraries, optionally holding a
/// string message and whether it is fatal or not. In case it is fatal and if
/// BOLT is running as a standalone process, the process might be killed as soon
/// as the error is checked.
class BOLTError : public ErrorInfo<BOLTError> {
public:
static char ID;

BOLTError(bool IsFatal, const Twine &S = Twine());
void log(raw_ostream &OS) const override;
bool isFatal() const { return IsFatal; }

const std::string &getMessage() const { return Msg; }
std::error_code convertToErrorCode() const override;

private:
bool IsFatal;
std::string Msg;
};

/// Streams used by BOLT to log regular or error events
struct JournalingStreams {
raw_ostream &Out;
raw_ostream &Err;
};

Error createNonFatalBOLTError(const Twine &S);
Error createFatalBOLTError(const Twine &S);

class BinaryContext {
BinaryContext() = delete;

Expand Down Expand Up @@ -237,7 +266,8 @@ class BinaryContext {
public:
static Expected<std::unique_ptr<BinaryContext>>
createBinaryContext(const ObjectFile *File, bool IsPIC,
std::unique_ptr<DWARFContext> DwCtx);
std::unique_ptr<DWARFContext> DwCtx,
JournalingStreams Logger);

/// Superset of compiler units that will contain overwritten code that needs
/// new debug info. In a few cases, functions may end up not being
Expand Down Expand Up @@ -605,6 +635,10 @@ class BinaryContext {

std::unique_ptr<MCAsmBackend> MAB;

/// Allows BOLT to print to log whenever it is necessary (with or without
/// const references)
mutable JournalingStreams Logger;

/// Indicates if the binary is Linux kernel.
bool IsLinuxKernel{false};

Expand Down Expand Up @@ -737,7 +771,8 @@ class BinaryContext {
std::unique_ptr<const MCInstrAnalysis> MIA,
std::unique_ptr<MCPlusBuilder> MIB,
std::unique_ptr<const MCRegisterInfo> MRI,
std::unique_ptr<MCDisassembler> DisAsm);
std::unique_ptr<MCDisassembler> DisAsm,
JournalingStreams Logger);

~BinaryContext();

Expand Down Expand Up @@ -1349,8 +1384,12 @@ class BinaryContext {
return Offset;
}

void exitWithBugReport(StringRef Message,
const BinaryFunction &Function) const;
/// Log BOLT errors to journaling streams and quit process with non-zero error
/// code 1 if error is fatal.
void logBOLTErrorsAndQuitOnFatal(Error E);

std::string generateBugReportMessage(StringRef Message,
const BinaryFunction &Function) const;

struct IndependentCodeEmitter {
std::unique_ptr<MCObjectFileInfo> LocalMOFI;
Expand Down Expand Up @@ -1398,6 +1437,10 @@ class BinaryContext {
assert(IOAddressMap && "Address map not set yet");
return *IOAddressMap;
}

raw_ostream &outs() const { return Logger.Out; }

raw_ostream &errs() const { return Logger.Err; }
};

template <typename T, typename = std::enable_if_t<sizeof(T) == 1>>
Expand Down
21 changes: 11 additions & 10 deletions bolt/include/bolt/Core/BinaryFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1910,12 +1910,11 @@ class BinaryFunction {

/// Support dynamic relocations in constant islands, which may happen if
/// binary is linked with -z notext option.
void markIslandDynamicRelocationAtAddress(uint64_t Address) {
if (!isInConstantIsland(Address)) {
errs() << "BOLT-ERROR: dynamic relocation found for text section at 0x"
<< Twine::utohexstr(Address) << "\n";
exit(1);
}
Error markIslandDynamicRelocationAtAddress(uint64_t Address) {
if (!isInConstantIsland(Address))
return createFatalBOLTError(
Twine("dynamic relocation found for text section at 0x") +
Twine::utohexstr(Address) + Twine("\n"));

// Mark island to have dynamic relocation
Islands->HasDynamicRelocations = true;
Expand All @@ -1924,6 +1923,7 @@ class BinaryFunction {
// move binary data during updateOutputValues, making us emit
// dynamic relocation with the right offset value.
getOrCreateIslandAccess(Address);
return Error::success();
}

bool hasDynamicRelocationAtIsland() const {
Expand Down Expand Up @@ -2054,9 +2054,10 @@ class BinaryFunction {
/// state to State:Disassembled.
///
/// Returns false if disassembly failed.
bool disassemble();
Error disassemble();

void handlePCRelOperand(MCInst &Instruction, uint64_t Address, uint64_t Size);
Error handlePCRelOperand(MCInst &Instruction, uint64_t Address,
uint64_t Size);

MCSymbol *handleExternalReference(MCInst &Instruction, uint64_t Size,
uint64_t Offset, uint64_t TargetAddress,
Expand Down Expand Up @@ -2100,7 +2101,7 @@ class BinaryFunction {
///
/// Returns true on success and update the current function state to
/// State::CFG. Returns false if CFG cannot be built.
bool buildCFG(MCPlusBuilder::AllocatorIdTy);
Error buildCFG(MCPlusBuilder::AllocatorIdTy);

/// Perform post-processing of the CFG.
void postProcessCFG();
Expand Down Expand Up @@ -2217,7 +2218,7 @@ class BinaryFunction {
}

/// Process LSDA information for the function.
void parseLSDA(ArrayRef<uint8_t> LSDAData, uint64_t LSDAAddress);
Error parseLSDA(ArrayRef<uint8_t> LSDAData, uint64_t LSDAAddress);

/// Update exception handling ranges for the function.
void updateEHRanges();
Expand Down
4 changes: 2 additions & 2 deletions bolt/include/bolt/Core/BinarySection.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class BinarySection {
static StringRef getName(SectionRef Section) {
return cantFail(Section.getName());
}
static StringRef getContents(SectionRef Section) {
static StringRef getContentsOrQuit(SectionRef Section) {
if (Section.getObject()->isELF() &&
ELFSectionRef(Section).getType() == ELF::SHT_NOBITS)
return StringRef();
Expand Down Expand Up @@ -159,7 +159,7 @@ class BinarySection {

BinarySection(BinaryContext &BC, SectionRef Section)
: BC(BC), Name(getName(Section)), Section(Section),
Contents(getContents(Section)), Address(Section.getAddress()),
Contents(getContentsOrQuit(Section)), Address(Section.getAddress()),
Size(Section.getSize()), Alignment(Section.getAlignment().value()),
OutputName(Name), SectionNumber(++Count) {
if (isELF()) {
Expand Down
17 changes: 11 additions & 6 deletions bolt/include/bolt/Core/DIEBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef BOLT_CORE_DIE_BUILDER_H
#define BOLT_CORE_DIE_BUILDER_H

#include "bolt/Core/BinaryContext.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
Expand All @@ -32,6 +33,7 @@
namespace llvm {

namespace bolt {

class DIEStreamer;
class DebugStrOffsetsWriter;

Expand Down Expand Up @@ -120,6 +122,7 @@ class DIEBuilder {
std::unique_ptr<State> BuilderState;
FoldingSet<DIEAbbrev> AbbreviationsSet;
std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
BinaryContext &BC;
DWARFContext *DwarfContext{nullptr};
bool IsDWO{false};
uint64_t UnitSize{0};
Expand Down Expand Up @@ -219,9 +222,10 @@ class DIEBuilder {
if (getState().CloneUnitCtxMap[UnitId].DieInfoVector.size() > DIEId)
return *getState().CloneUnitCtxMap[UnitId].DieInfoVector[DIEId].get();

errs() << "BOLT-WARNING: [internal-dwarf-error]: The DIE is not allocated "
"before looking up, some"
<< "unexpected corner cases happened.\n";
BC.errs()
<< "BOLT-WARNING: [internal-dwarf-error]: The DIE is not allocated "
"before looking up, some"
<< "unexpected corner cases happened.\n";
return *getState().CloneUnitCtxMap[UnitId].DieInfoVector.front().get();
}

Expand Down Expand Up @@ -261,7 +265,7 @@ class DIEBuilder {
DIE *constructDIEFast(DWARFDie &DDie, DWARFUnit &U, uint32_t UnitId);

public:
DIEBuilder(DWARFContext *DwarfContext, bool IsDWO = false);
DIEBuilder(BinaryContext &BC, DWARFContext *DwarfContext, bool IsDWO = false);

/// Returns enum to what we are currently processing.
ProcessingType getCurrentProcessingState() { return getState().Type; }
Expand Down Expand Up @@ -295,8 +299,9 @@ class DIEBuilder {
if (getState().TypeDIEMap.count(&DU))
return getState().TypeDIEMap[&DU];

errs() << "BOLT-ERROR: unable to find TypeUnit for Type Unit at offset 0x"
<< DU.getOffset() << "\n";
BC.errs()
<< "BOLT-ERROR: unable to find TypeUnit for Type Unit at offset 0x"
<< DU.getOffset() << "\n";
return nullptr;
}

Expand Down
15 changes: 8 additions & 7 deletions bolt/include/bolt/Core/DynoStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,9 @@ inline DynoStats getDynoStats(FuncsType &Funcs, bool IsAArch64) {

/// Call a function with optional before and after dynostats printing.
template <typename FnType, typename FuncsType>
inline void callWithDynoStats(FnType &&Func, FuncsType &Funcs, StringRef Phase,
const bool Flag, bool IsAArch64) {
inline void callWithDynoStats(raw_ostream &OS, FnType &&Func, FuncsType &Funcs,
StringRef Phase, const bool Flag,
bool IsAArch64) {
DynoStats DynoStatsBefore(IsAArch64);
if (Flag)
DynoStatsBefore = getDynoStats(Funcs, IsAArch64);
Expand All @@ -170,12 +171,12 @@ inline void callWithDynoStats(FnType &&Func, FuncsType &Funcs, StringRef Phase,
if (Flag) {
const DynoStats DynoStatsAfter = getDynoStats(Funcs, IsAArch64);
const bool Changed = (DynoStatsAfter != DynoStatsBefore);
outs() << "BOLT-INFO: program-wide dynostats after running " << Phase
<< (Changed ? "" : " (no change)") << ":\n\n"
<< DynoStatsBefore << '\n';
OS << "BOLT-INFO: program-wide dynostats after running " << Phase
<< (Changed ? "" : " (no change)") << ":\n\n"
<< DynoStatsBefore << '\n';
if (Changed)
DynoStatsAfter.print(outs(), &DynoStatsBefore);
outs() << '\n';
DynoStatsAfter.print(OS, &DynoStatsBefore);
OS << '\n';
}
}

Expand Down
4 changes: 3 additions & 1 deletion bolt/include/bolt/Core/Exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ class FDE;

namespace bolt {

class BinaryContext;
class BinaryFunction;

/// \brief Wraps up information to read all CFI instructions and feed them to a
/// BinaryFunction, as well as rewriting CFI sections.
class CFIReaderWriter {
public:
explicit CFIReaderWriter(const DWARFDebugFrame &EHFrame);
explicit CFIReaderWriter(BinaryContext &BC, const DWARFDebugFrame &EHFrame);

bool fillCFIInfoFor(BinaryFunction &Function) const;

Expand All @@ -59,6 +60,7 @@ class CFIReaderWriter {
const FDEsMap &getFDEs() const { return FDEs; }

private:
BinaryContext &BC;
FDEsMap FDEs;
};

Expand Down
13 changes: 6 additions & 7 deletions bolt/include/bolt/Passes/BinaryPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ class BinaryFunctionPass {
/// this pass is completed (printPass() must have returned true).
virtual bool shouldPrint(const BinaryFunction &BF) const;

/// Execute this pass on the given functions.
virtual Error runOnFunctions(BinaryContext &BC) = 0;
};

Expand All @@ -74,14 +73,14 @@ class DynoStatsPrintPass : public BinaryFunctionPass {
const DynoStats NewDynoStats =
getDynoStats(BC.getBinaryFunctions(), BC.isAArch64());
const bool Changed = (NewDynoStats != PrevDynoStats);
outs() << "BOLT-INFO: program-wide dynostats " << Title
<< (Changed ? "" : " (no change)") << ":\n\n"
<< PrevDynoStats;
BC.outs() << "BOLT-INFO: program-wide dynostats " << Title
<< (Changed ? "" : " (no change)") << ":\n\n"
<< PrevDynoStats;
if (Changed) {
outs() << '\n';
NewDynoStats.print(outs(), &PrevDynoStats, BC.InstPrinter.get());
BC.outs() << '\n';
NewDynoStats.print(BC.outs(), &PrevDynoStats, BC.InstPrinter.get());
}
outs() << '\n';
BC.outs() << '\n';
return Error::success();
}
};
Expand Down
2 changes: 1 addition & 1 deletion bolt/include/bolt/Passes/CMOVConversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class CMOVConversion : public BinaryFunctionPass {
}
double getMPRatio() { return (double)RemovedMP / PossibleMP; }

void dump();
void dumpTo(raw_ostream &OS);
};
// BinaryContext-wide stats
Stats Global;
Expand Down
6 changes: 5 additions & 1 deletion bolt/include/bolt/Passes/CacheMetrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
#include <vector>

namespace llvm {

class raw_ostream;

namespace bolt {
class BinaryFunction;
namespace CacheMetrics {

/// Calculate and print various metrics related to instruction cache performance
void printAll(const std::vector<BinaryFunction *> &BinaryFunctions);
void printAll(raw_ostream &OS,
const std::vector<BinaryFunction *> &BinaryFunctions);

} // namespace CacheMetrics
} // namespace bolt
Expand Down
4 changes: 2 additions & 2 deletions bolt/include/bolt/Passes/FrameOptimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ class FrameOptimizerPass : public BinaryFunctionPass {
void removeUnusedStores(const FrameAnalysis &FA, BinaryFunction &BF);

/// Perform shrinkwrapping step
void performShrinkWrapping(const RegAnalysis &RA, const FrameAnalysis &FA,
BinaryContext &BC);
Error performShrinkWrapping(const RegAnalysis &RA, const FrameAnalysis &FA,
BinaryContext &BC);

public:
explicit FrameOptimizerPass(const cl::opt<bool> &PrintPass)
Expand Down
4 changes: 2 additions & 2 deletions bolt/include/bolt/Passes/LongJmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ class LongJmpPass : public BinaryFunctionPass {
uint64_t DotAddress) const;

/// Expand the range of the stub in StubBB if necessary
bool relaxStub(BinaryBasicBlock &StubBB);
Error relaxStub(BinaryBasicBlock &StubBB, bool &Modified);

/// Helper to resolve a symbol address according to our tentative layout
uint64_t getSymbolAddress(const BinaryContext &BC, const MCSymbol *Target,
const BinaryBasicBlock *TgtBB) const;

/// Relax function by adding necessary stubs or relaxing existing stubs
bool relax(BinaryFunction &BF);
Error relax(BinaryFunction &BF, bool &Modified);

public:
/// BinaryPass public interface
Expand Down
3 changes: 2 additions & 1 deletion bolt/include/bolt/Passes/ReorderData.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class ReorderData : public BinaryFunctionPass {
sortedByFunc(BinaryContext &BC, const BinarySection &Section,
std::map<uint64_t, BinaryFunction> &BFs) const;

void printOrder(const BinarySection &Section, DataOrder::const_iterator Begin,
void printOrder(BinaryContext &BC, const BinarySection &Section,
DataOrder::const_iterator Begin,
DataOrder::const_iterator End) const;

/// Set the ordering of the section with \p SectionName. \p NewOrder is a
Expand Down
6 changes: 3 additions & 3 deletions bolt/include/bolt/Passes/ReorderFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ class Cluster;
class ReorderFunctions : public BinaryFunctionPass {
BinaryFunctionCallGraph Cg;

void reorder(std::vector<Cluster> &&Clusters,
void reorder(BinaryContext &BC, std::vector<Cluster> &&Clusters,
std::map<uint64_t, BinaryFunction> &BFs);

void printStats(const std::vector<Cluster> &Clusters,
void printStats(BinaryContext &BC, const std::vector<Cluster> &Clusters,
const std::vector<uint64_t> &FuncAddr);

public:
Expand All @@ -44,7 +44,7 @@ class ReorderFunctions : public BinaryFunctionPass {
const char *getName() const override { return "reorder-functions"; }
Error runOnFunctions(BinaryContext &BC) override;

static std::vector<std::string> readFunctionOrderFile();
static Error readFunctionOrderFile(std::vector<std::string> &FunctionNames);
};

} // namespace bolt
Expand Down
Loading