[llvm] [BOLT][NFC] Log through JournalingStreams (PR #81524)
Amir Ayupov via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 12 14:53:15 PST 2024
https://github.com/aaupov updated https://github.com/llvm/llvm-project/pull/81524
>From 3c83dd2d9f69251c55f44a8d6adb7e7bf19f1dae Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Mon, 12 Feb 2024 12:06:16 -0800
Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
=?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
[skip ci]
---
bolt/include/bolt/Core/BinaryContext.h | 23 +++++
bolt/include/bolt/Core/BinaryFunction.h | 21 +++--
bolt/include/bolt/Core/BinarySection.h | 4 +-
bolt/include/bolt/Passes/ADRRelaxationPass.h | 2 +-
bolt/include/bolt/Passes/Aligner.h | 2 +-
bolt/include/bolt/Passes/AllocCombiner.h | 2 +-
bolt/include/bolt/Passes/AsmDump.h | 2 +-
bolt/include/bolt/Passes/BinaryPasses.h | 45 ++++-----
bolt/include/bolt/Passes/CMOVConversion.h | 2 +-
bolt/include/bolt/Passes/FixRISCVCallsPass.h | 2 +-
bolt/include/bolt/Passes/FixRelaxationPass.h | 2 +-
bolt/include/bolt/Passes/FrameOptimizer.h | 6 +-
bolt/include/bolt/Passes/Hugify.h | 2 +-
.../bolt/Passes/IdenticalCodeFolding.h | 2 +-
.../bolt/Passes/IndirectCallPromotion.h | 2 +-
bolt/include/bolt/Passes/Inliner.h | 2 +-
bolt/include/bolt/Passes/Instrumentation.h | 2 +-
.../bolt/Passes/JTFootprintReduction.h | 2 +-
bolt/include/bolt/Passes/LongJmp.h | 6 +-
bolt/include/bolt/Passes/LoopInversionPass.h | 2 +-
bolt/include/bolt/Passes/PLTCall.h | 2 +-
bolt/include/bolt/Passes/PatchEntries.h | 2 +-
bolt/include/bolt/Passes/RegReAssign.h | 2 +-
bolt/include/bolt/Passes/ReorderData.h | 2 +-
bolt/include/bolt/Passes/ReorderFunctions.h | 4 +-
bolt/include/bolt/Passes/RetpolineInsertion.h | 2 +-
bolt/include/bolt/Passes/ShrinkWrapping.h | 24 ++---
bolt/include/bolt/Passes/SplitFunctions.h | 2 +-
bolt/include/bolt/Passes/StokeInfo.h | 2 +-
bolt/include/bolt/Passes/TailDuplication.h | 2 +-
bolt/include/bolt/Passes/ThreeWayBranch.h | 2 +-
.../bolt/Passes/ValidateInternalCalls.h | 2 +-
bolt/include/bolt/Passes/ValidateMemRefs.h | 2 +-
bolt/include/bolt/Passes/VeneerElimination.h | 2 +-
bolt/include/bolt/Rewrite/BinaryPassManager.h | 4 +-
bolt/lib/Core/BinaryContext.cpp | 31 +++++++
bolt/lib/Core/BinaryFunction.cpp | 71 ++++++++++-----
bolt/lib/Core/BinarySection.cpp | 2 +-
bolt/lib/Core/Exceptions.cpp | 11 ++-
bolt/lib/Passes/ADRRelaxationPass.cpp | 7 +-
bolt/lib/Passes/Aligner.cpp | 5 +-
bolt/lib/Passes/AllocCombiner.cpp | 5 +-
bolt/lib/Passes/AsmDump.cpp | 3 +-
bolt/lib/Passes/BinaryPasses.cpp | 91 ++++++++++++-------
bolt/lib/Passes/CMOVConversion.cpp | 3 +-
bolt/lib/Passes/FixRISCVCallsPass.cpp | 6 +-
bolt/lib/Passes/FixRelaxationPass.cpp | 5 +-
bolt/lib/Passes/FrameOptimizer.cpp | 26 ++++--
bolt/lib/Passes/Hugify.cpp | 5 +-
bolt/lib/Passes/IdenticalCodeFolding.cpp | 4 +-
bolt/lib/Passes/IndirectCallPromotion.cpp | 5 +-
bolt/lib/Passes/Inliner.cpp | 5 +-
bolt/lib/Passes/Instrumentation.cpp | 17 ++--
bolt/lib/Passes/JTFootprintReduction.cpp | 7 +-
bolt/lib/Passes/LongJmp.cpp | 45 ++++-----
bolt/lib/Passes/LoopInversionPass.cpp | 5 +-
bolt/lib/Passes/PLTCall.cpp | 5 +-
bolt/lib/Passes/PatchEntries.cpp | 7 +-
bolt/lib/Passes/RegReAssign.cpp | 5 +-
bolt/lib/Passes/ReorderData.cpp | 7 +-
bolt/lib/Passes/ReorderFunctions.cpp | 29 +++---
bolt/lib/Passes/RetpolineInsertion.cpp | 5 +-
bolt/lib/Passes/ShrinkWrapping.cpp | 65 ++++++++-----
bolt/lib/Passes/SplitFunctions.cpp | 7 +-
bolt/lib/Passes/StokeInfo.cpp | 5 +-
bolt/lib/Passes/TailDuplication.cpp | 5 +-
bolt/lib/Passes/ThreeWayBranch.cpp | 3 +-
bolt/lib/Passes/ValidateInternalCalls.cpp | 7 +-
bolt/lib/Passes/ValidateMemRefs.cpp | 9 +-
bolt/lib/Passes/VeneerElimination.cpp | 9 +-
bolt/lib/Rewrite/BinaryPassManager.cpp | 23 +++--
bolt/lib/Rewrite/BoltDiff.cpp | 8 +-
bolt/lib/Rewrite/RewriteInstance.cpp | 23 ++++-
bolt/lib/Target/X86/X86MCSymbolizer.cpp | 17 +++-
bolt/lib/Target/X86/X86MCSymbolizer.h | 4 +-
75 files changed, 495 insertions(+), 296 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index f1db1fbded6a47..5dc5fdb150be25 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -145,6 +145,29 @@ 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;
+};
+
+Error createNonFatalBOLTError(const Twine &S);
+Error createFatalBOLTError(const Twine &S);
+
class BinaryContext {
BinaryContext() = delete;
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index 3a1eae3311bd76..a177178769e456 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -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;
@@ -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 {
@@ -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,
@@ -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();
@@ -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();
diff --git a/bolt/include/bolt/Core/BinarySection.h b/bolt/include/bolt/Core/BinarySection.h
index 70914f59157d24..a85dbf28950e31 100644
--- a/bolt/include/bolt/Core/BinarySection.h
+++ b/bolt/include/bolt/Core/BinarySection.h
@@ -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();
@@ -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()) {
diff --git a/bolt/include/bolt/Passes/ADRRelaxationPass.h b/bolt/include/bolt/Passes/ADRRelaxationPass.h
index a5ff0c4a800301..1d35a335c0250c 100644
--- a/bolt/include/bolt/Passes/ADRRelaxationPass.h
+++ b/bolt/include/bolt/Passes/ADRRelaxationPass.h
@@ -30,7 +30,7 @@ class ADRRelaxationPass : public BinaryFunctionPass {
const char *getName() const override { return "adr-relaxation"; }
/// Pass entry point
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
void runOnFunction(BinaryFunction &BF);
};
diff --git a/bolt/include/bolt/Passes/Aligner.h b/bolt/include/bolt/Passes/Aligner.h
index 4cb44fdb121e86..eb077182c9456a 100644
--- a/bolt/include/bolt/Passes/Aligner.h
+++ b/bolt/include/bolt/Passes/Aligner.h
@@ -39,7 +39,7 @@ class AlignerPass : public BinaryFunctionPass {
const char *getName() const override { return "aligner"; }
/// Pass entry point
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/AllocCombiner.h b/bolt/include/bolt/Passes/AllocCombiner.h
index 44c6fddd34de45..8532f761c9adb2 100644
--- a/bolt/include/bolt/Passes/AllocCombiner.h
+++ b/bolt/include/bolt/Passes/AllocCombiner.h
@@ -33,7 +33,7 @@ class AllocCombinerPass : public BinaryFunctionPass {
}
/// Pass entry point
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/AsmDump.h b/bolt/include/bolt/Passes/AsmDump.h
index 7cc96f20a92068..d993909f279461 100644
--- a/bolt/include/bolt/Passes/AsmDump.h
+++ b/bolt/include/bolt/Passes/AsmDump.h
@@ -28,7 +28,7 @@ class AsmDumpPass : public BinaryFunctionPass {
bool shouldPrint(const BinaryFunction &BF) const override { return false; }
/// Pass entry point
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/BinaryPasses.h b/bolt/include/bolt/Passes/BinaryPasses.h
index dace07e903e7bc..8d52337b50ad04 100644
--- a/bolt/include/bolt/Passes/BinaryPasses.h
+++ b/bolt/include/bolt/Passes/BinaryPasses.h
@@ -51,7 +51,7 @@ class BinaryFunctionPass {
virtual bool shouldPrint(const BinaryFunction &BF) const;
/// Execute this pass on the given functions.
- virtual void runOnFunctions(BinaryContext &BC) = 0;
+ virtual Error runOnFunctions(BinaryContext &BC) = 0;
};
/// A pass to print program-wide dynostats.
@@ -70,7 +70,7 @@ class DynoStatsPrintPass : public BinaryFunctionPass {
bool shouldPrint(const BinaryFunction &BF) const override { return false; }
- void runOnFunctions(BinaryContext &BC) override {
+ Error runOnFunctions(BinaryContext &BC) override {
const DynoStats NewDynoStats =
getDynoStats(BC.getBinaryFunctions(), BC.isAArch64());
const bool Changed = (NewDynoStats != PrevDynoStats);
@@ -82,6 +82,7 @@ class DynoStatsPrintPass : public BinaryFunctionPass {
NewDynoStats.print(outs(), &PrevDynoStats, BC.InstPrinter.get());
}
outs() << '\n';
+ return Error::success();
}
};
@@ -100,7 +101,7 @@ class NormalizeCFG : public BinaryFunctionPass {
const char *getName() const override { return "normalize CFG"; }
- void runOnFunctions(BinaryContext &) override;
+ Error runOnFunctions(BinaryContext &) override;
};
/// Detect and eliminate unreachable basic blocks. We could have those
@@ -119,7 +120,7 @@ class EliminateUnreachableBlocks : public BinaryFunctionPass {
bool shouldPrint(const BinaryFunction &BF) const override {
return BinaryFunctionPass::shouldPrint(BF) && Modified.count(&BF) > 0;
}
- void runOnFunctions(BinaryContext &) override;
+ Error runOnFunctions(BinaryContext &) override;
};
// Reorder the basic blocks for each function based on hotness.
@@ -165,7 +166,7 @@ class ReorderBasicBlocks : public BinaryFunctionPass {
const char *getName() const override { return "reorder-blocks"; }
bool shouldPrint(const BinaryFunction &BF) const override;
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Sync local branches with CFG.
@@ -175,7 +176,7 @@ class FixupBranches : public BinaryFunctionPass {
: BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "fix-branches"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Fix the CFI state and exception handling information after all other
@@ -186,7 +187,7 @@ class FinalizeFunctions : public BinaryFunctionPass {
: BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "finalize-functions"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Perform any necessary adjustments for functions that do not fit into their
@@ -198,7 +199,7 @@ class CheckLargeFunctions : public BinaryFunctionPass {
const char *getName() const override { return "check-large-functions"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
bool shouldOptimize(const BinaryFunction &BF) const override;
};
@@ -210,7 +211,7 @@ class LowerAnnotations : public BinaryFunctionPass {
: BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "lower-annotations"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Clean the state of the MC representation before sending it to emission
@@ -220,7 +221,7 @@ class CleanMCState : public BinaryFunctionPass {
: BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "clean-mc-state"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// An optimization to simplify conditional tail calls by removing
@@ -292,7 +293,7 @@ class SimplifyConditionalTailCalls : public BinaryFunctionPass {
bool shouldPrint(const BinaryFunction &BF) const override {
return BinaryFunctionPass::shouldPrint(BF) && Modified.count(&BF) > 0;
}
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Convert instructions to the form with the minimum operand width.
@@ -305,7 +306,7 @@ class ShortenInstructions : public BinaryFunctionPass {
const char *getName() const override { return "shorten-instructions"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Perform simple peephole optimizations.
@@ -339,7 +340,7 @@ class Peepholes : public BinaryFunctionPass {
: BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "peepholes"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// An optimization to simplify loads from read-only sections.The pass converts
@@ -370,7 +371,7 @@ class SimplifyRODataLoads : public BinaryFunctionPass {
bool shouldPrint(const BinaryFunction &BF) const override {
return BinaryFunctionPass::shouldPrint(BF) && Modified.count(&BF) > 0;
}
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Assign output sections to all functions.
@@ -379,7 +380,7 @@ class AssignSections : public BinaryFunctionPass {
explicit AssignSections() : BinaryFunctionPass(false) {}
const char *getName() const override { return "assign-sections"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Compute and report to the user the imbalance in flow equations for all
@@ -394,7 +395,7 @@ class PrintProfileStats : public BinaryFunctionPass {
const char *getName() const override { return "profile-stats"; }
bool shouldPrint(const BinaryFunction &) const override { return false; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Prints a list of the top 100 functions sorted by a set of
@@ -406,7 +407,7 @@ class PrintProgramStats : public BinaryFunctionPass {
const char *getName() const override { return "print-stats"; }
bool shouldPrint(const BinaryFunction &) const override { return false; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Pass for lowering any instructions that we have raised and that have
@@ -418,7 +419,7 @@ class InstructionLowering : public BinaryFunctionPass {
const char *getName() const override { return "inst-lowering"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Pass for stripping 'repz' from 'repz retq' sequence of instructions.
@@ -429,7 +430,7 @@ class StripRepRet : public BinaryFunctionPass {
const char *getName() const override { return "strip-rep-ret"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Pass for inlining calls to memcpy using 'rep movsb' on X86.
@@ -440,7 +441,7 @@ class InlineMemcpy : public BinaryFunctionPass {
const char *getName() const override { return "inline-memcpy"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Pass for specializing memcpy for a size of 1 byte.
@@ -461,7 +462,7 @@ class SpecializeMemcpy1 : public BinaryFunctionPass {
const char *getName() const override { return "specialize-memcpy"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
/// Pass to remove nops in code
@@ -475,7 +476,7 @@ class RemoveNops : public BinaryFunctionPass {
const char *getName() const override { return "remove-nops"; }
/// Pass entry point
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
enum FrameOptimizationType : char {
diff --git a/bolt/include/bolt/Passes/CMOVConversion.h b/bolt/include/bolt/Passes/CMOVConversion.h
index 77ce2235001a6d..29b5184254fef2 100644
--- a/bolt/include/bolt/Passes/CMOVConversion.h
+++ b/bolt/include/bolt/Passes/CMOVConversion.h
@@ -76,7 +76,7 @@ class CMOVConversion : public BinaryFunctionPass {
const char *getName() const override { return "CMOV conversion"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/FixRISCVCallsPass.h b/bolt/include/bolt/Passes/FixRISCVCallsPass.h
index 46418c43d1928f..a5c3e5158d6d94 100644
--- a/bolt/include/bolt/Passes/FixRISCVCallsPass.h
+++ b/bolt/include/bolt/Passes/FixRISCVCallsPass.h
@@ -33,7 +33,7 @@ class FixRISCVCallsPass : public BinaryFunctionPass {
const char *getName() const override { return "fix-riscv-calls"; }
/// Pass entry point
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/FixRelaxationPass.h b/bolt/include/bolt/Passes/FixRelaxationPass.h
index 45ee9cb736037c..50b64480aa62e5 100644
--- a/bolt/include/bolt/Passes/FixRelaxationPass.h
+++ b/bolt/include/bolt/Passes/FixRelaxationPass.h
@@ -31,7 +31,7 @@ class FixRelaxations : public BinaryFunctionPass {
const char *getName() const override { return "fix-relaxations"; }
/// Pass entry point
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/FrameOptimizer.h b/bolt/include/bolt/Passes/FrameOptimizer.h
index 310bebfee266ab..64055bd251729b 100644
--- a/bolt/include/bolt/Passes/FrameOptimizer.h
+++ b/bolt/include/bolt/Passes/FrameOptimizer.h
@@ -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)
@@ -108,7 +108,7 @@ class FrameOptimizerPass : public BinaryFunctionPass {
const char *getName() const override { return "frame-optimizer"; }
/// Pass entry point
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
bool shouldPrint(const BinaryFunction &BF) const override {
return BinaryFunctionPass::shouldPrint(BF) && FuncsChanged.count(&BF) > 0;
diff --git a/bolt/include/bolt/Passes/Hugify.h b/bolt/include/bolt/Passes/Hugify.h
index 0a7734059121c1..52c0ae19102b67 100644
--- a/bolt/include/bolt/Passes/Hugify.h
+++ b/bolt/include/bolt/Passes/Hugify.h
@@ -18,7 +18,7 @@ class HugePage : public BinaryFunctionPass {
public:
HugePage(const cl::opt<bool> &PrintPass) : BinaryFunctionPass(PrintPass) {}
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
const char *getName() const override { return "HugePage"; }
};
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index c15cebc8af19a4..b4206fa3607445 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -35,7 +35,7 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
: BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "identical-code-folding"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/IndirectCallPromotion.h b/bolt/include/bolt/Passes/IndirectCallPromotion.h
index 397a38663948e9..adc58d70ec0f4d 100644
--- a/bolt/include/bolt/Passes/IndirectCallPromotion.h
+++ b/bolt/include/bolt/Passes/IndirectCallPromotion.h
@@ -221,7 +221,7 @@ class IndirectCallPromotion : public BinaryFunctionPass {
return BF.isSimple() && !BF.isIgnored() && BF.hasProfile() &&
!BF.hasUnknownControlFlow();
}
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/Inliner.h b/bolt/include/bolt/Passes/Inliner.h
index 711eae69d1c9fc..5d9b96a2d915c1 100644
--- a/bolt/include/bolt/Passes/Inliner.h
+++ b/bolt/include/bolt/Passes/Inliner.h
@@ -86,7 +86,7 @@ class Inliner : public BinaryFunctionPass {
return BinaryFunctionPass::shouldPrint(BF) && Modified.count(&BF) > 0;
}
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/Instrumentation.h b/bolt/include/bolt/Passes/Instrumentation.h
index 1a11f9eab51109..76ffcf41db6ea9 100644
--- a/bolt/include/bolt/Passes/Instrumentation.h
+++ b/bolt/include/bolt/Passes/Instrumentation.h
@@ -31,7 +31,7 @@ class Instrumentation : public BinaryFunctionPass {
Summary(std::make_unique<InstrumentationSummary>()) {}
/// Modifies all functions by inserting instrumentation code (first step)
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
const char *getName() const override { return "instrumentation"; }
diff --git a/bolt/include/bolt/Passes/JTFootprintReduction.h b/bolt/include/bolt/Passes/JTFootprintReduction.h
index 084049d3b4631d..4b015e1f96b315 100644
--- a/bolt/include/bolt/Passes/JTFootprintReduction.h
+++ b/bolt/include/bolt/Passes/JTFootprintReduction.h
@@ -68,7 +68,7 @@ class JTFootprintReduction : public BinaryFunctionPass {
bool shouldPrint(const BinaryFunction &BF) const override {
return BinaryFunctionPass::shouldPrint(BF) && Modified.count(&BF) > 0;
}
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/LongJmp.h b/bolt/include/bolt/Passes/LongJmp.h
index c95181922dbc73..3d02d75ac4a277 100644
--- a/bolt/include/bolt/Passes/LongJmp.h
+++ b/bolt/include/bolt/Passes/LongJmp.h
@@ -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
@@ -148,7 +148,7 @@ class LongJmpPass : public BinaryFunctionPass {
const char *getName() const override { return "long-jmp"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
} // namespace llvm
diff --git a/bolt/include/bolt/Passes/LoopInversionPass.h b/bolt/include/bolt/Passes/LoopInversionPass.h
index 472fb36640c140..aee441d720931b 100644
--- a/bolt/include/bolt/Passes/LoopInversionPass.h
+++ b/bolt/include/bolt/Passes/LoopInversionPass.h
@@ -49,7 +49,7 @@ class LoopInversionPass : public BinaryFunctionPass {
const char *getName() const override { return "loop-inversion-opt"; }
/// Pass entry point
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
bool runOnFunction(BinaryFunction &Function);
};
diff --git a/bolt/include/bolt/Passes/PLTCall.h b/bolt/include/bolt/Passes/PLTCall.h
index 4fdbf60c7f9f85..09ef96e27293da 100644
--- a/bolt/include/bolt/Passes/PLTCall.h
+++ b/bolt/include/bolt/Passes/PLTCall.h
@@ -30,7 +30,7 @@ class PLTCall : public BinaryFunctionPass {
bool shouldPrint(const BinaryFunction &BF) const override {
return BinaryFunctionPass::shouldPrint(BF);
}
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/PatchEntries.h b/bolt/include/bolt/Passes/PatchEntries.h
index b9ed4a5e428037..fa6b5811a4c3b1 100644
--- a/bolt/include/bolt/Passes/PatchEntries.h
+++ b/bolt/include/bolt/Passes/PatchEntries.h
@@ -34,7 +34,7 @@ class PatchEntries : public BinaryFunctionPass {
explicit PatchEntries() : BinaryFunctionPass(false) {}
const char *getName() const override { return "patch-entries"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/RegReAssign.h b/bolt/include/bolt/Passes/RegReAssign.h
index cd7bea6a62c15a..c50e32ff46e293 100644
--- a/bolt/include/bolt/Passes/RegReAssign.h
+++ b/bolt/include/bolt/Passes/RegReAssign.h
@@ -55,7 +55,7 @@ class RegReAssign : public BinaryFunctionPass {
return BinaryFunctionPass::shouldPrint(BF) && FuncsChanged.count(&BF) > 0;
}
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
} // namespace llvm
diff --git a/bolt/include/bolt/Passes/ReorderData.h b/bolt/include/bolt/Passes/ReorderData.h
index 65b7306521019b..ed183bfce00c4f 100644
--- a/bolt/include/bolt/Passes/ReorderData.h
+++ b/bolt/include/bolt/Passes/ReorderData.h
@@ -51,7 +51,7 @@ class ReorderData : public BinaryFunctionPass {
const char *getName() const override { return "reorder-data"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/ReorderFunctions.h b/bolt/include/bolt/Passes/ReorderFunctions.h
index 8f9507d0a82494..b75937da2314d3 100644
--- a/bolt/include/bolt/Passes/ReorderFunctions.h
+++ b/bolt/include/bolt/Passes/ReorderFunctions.h
@@ -42,9 +42,9 @@ class ReorderFunctions : public BinaryFunctionPass {
: BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "reorder-functions"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
- static std::vector<std::string> readFunctionOrderFile();
+ static Error readFunctionOrderFile(std::vector<std::string> &FunctionNames);
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/RetpolineInsertion.h b/bolt/include/bolt/Passes/RetpolineInsertion.h
index 12f46a95264c93..2cdde7f0748345 100644
--- a/bolt/include/bolt/Passes/RetpolineInsertion.h
+++ b/bolt/include/bolt/Passes/RetpolineInsertion.h
@@ -62,7 +62,7 @@ class RetpolineInsertion : public BinaryFunctionPass {
const char *getName() const override { return "retpoline-insertion"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/ShrinkWrapping.h b/bolt/include/bolt/Passes/ShrinkWrapping.h
index cccbc518dd26b5..016bea75f649ac 100644
--- a/bolt/include/bolt/Passes/ShrinkWrapping.h
+++ b/bolt/include/bolt/Passes/ShrinkWrapping.h
@@ -467,8 +467,9 @@ class ShrinkWrapping {
/// If \p CreatePushOrPop is true, create a push/pop instead. Current SP/FP
/// values, as determined by StackPointerTracking, should be informed via
/// \p SPVal and \p FPVal in order to emit the correct offset form SP/FP.
- MCInst createStackAccess(int SPVal, int FPVal, const FrameIndexEntry &FIE,
- bool CreatePushOrPop);
+ Expected<MCInst> createStackAccess(int SPVal, int FPVal,
+ const FrameIndexEntry &FIE,
+ bool CreatePushOrPop);
/// Update the CFI referenced by \p Inst with \p NewOffset, if the CFI has
/// an offset.
@@ -484,22 +485,23 @@ class ShrinkWrapping {
/// InsertionPoint for other instructions that need to be inserted at the same
/// original location, since this insertion may have invalidated the previous
/// location.
- BBIterTy processInsertion(BBIterTy InsertionPoint, BinaryBasicBlock *CurBB,
- const WorklistItem &Item, int64_t SPVal,
- int64_t FPVal);
+ Expected<BBIterTy> processInsertion(BBIterTy InsertionPoint,
+ BinaryBasicBlock *CurBB,
+ const WorklistItem &Item, int64_t SPVal,
+ int64_t FPVal);
/// Auxiliary function to processInsertions(), helping perform all the
/// insertion tasks in the todo list associated with a single insertion point.
/// Return true if at least one insertion was performed.
- BBIterTy processInsertionsList(BBIterTy InsertionPoint,
- BinaryBasicBlock *CurBB,
- std::vector<WorklistItem> &TodoList,
- int64_t SPVal, int64_t FPVal);
+ Expected<BBIterTy> processInsertionsList(BBIterTy InsertionPoint,
+ BinaryBasicBlock *CurBB,
+ std::vector<WorklistItem> &TodoList,
+ int64_t SPVal, int64_t FPVal);
/// Apply all insertion todo tasks regarding insertion of new stores/loads or
/// push/pops at annotated points. Return false if the entire function had
/// no todo tasks annotation and this pass has nothing to do.
- bool processInsertions();
+ Expected<bool> processInsertions();
/// Apply all deletion todo tasks (or tasks to change a push/pop to a memory
/// access no-op)
@@ -519,7 +521,7 @@ class ShrinkWrapping {
BC.MIB->removeAnnotation(Inst, getAnnotationIndex());
}
- bool perform(bool HotOnly = false);
+ Expected<bool> perform(bool HotOnly = false);
static void printStats();
};
diff --git a/bolt/include/bolt/Passes/SplitFunctions.h b/bolt/include/bolt/Passes/SplitFunctions.h
index 28e9e79d1b8f87..8bdc48b68eb7ae 100644
--- a/bolt/include/bolt/Passes/SplitFunctions.h
+++ b/bolt/include/bolt/Passes/SplitFunctions.h
@@ -104,7 +104,7 @@ class SplitFunctions : public BinaryFunctionPass {
const char *getName() const override { return "split-functions"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/StokeInfo.h b/bolt/include/bolt/Passes/StokeInfo.h
index 75cfa1e7de4355..76417e6a2c3baa 100644
--- a/bolt/include/bolt/Passes/StokeInfo.h
+++ b/bolt/include/bolt/Passes/StokeInfo.h
@@ -120,7 +120,7 @@ class StokeInfo : public BinaryFunctionPass {
bool checkFunction(BinaryFunction &BF, DataflowInfoManager &DInfo,
RegAnalysis &RA, StokeFuncInfo &FuncInfo);
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/TailDuplication.h b/bolt/include/bolt/Passes/TailDuplication.h
index b3f1d7b7d9643a..a2fcab0720ca27 100644
--- a/bolt/include/bolt/Passes/TailDuplication.h
+++ b/bolt/include/bolt/Passes/TailDuplication.h
@@ -145,7 +145,7 @@ class TailDuplication : public BinaryFunctionPass {
const char *getName() const override { return "tail duplication"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/ThreeWayBranch.h b/bolt/include/bolt/Passes/ThreeWayBranch.h
index 3eabf1b27e9d4e..9abf4c34134fdd 100644
--- a/bolt/include/bolt/Passes/ThreeWayBranch.h
+++ b/bolt/include/bolt/Passes/ThreeWayBranch.h
@@ -32,7 +32,7 @@ class ThreeWayBranch : public BinaryFunctionPass {
const char *getName() const override { return "three way branch"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Passes/ValidateInternalCalls.h b/bolt/include/bolt/Passes/ValidateInternalCalls.h
index 137b83b0179f49..0cdb8584f92df2 100644
--- a/bolt/include/bolt/Passes/ValidateInternalCalls.h
+++ b/bolt/include/bolt/Passes/ValidateInternalCalls.h
@@ -54,7 +54,7 @@ class ValidateInternalCalls : public BinaryFunctionPass {
const char *getName() const override { return "validate-internal-calls"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
private:
/// Fix the CFG to take into consideration internal calls that do not
diff --git a/bolt/include/bolt/Passes/ValidateMemRefs.h b/bolt/include/bolt/Passes/ValidateMemRefs.h
index d33862cf7b1697..90acce370249af 100644
--- a/bolt/include/bolt/Passes/ValidateMemRefs.h
+++ b/bolt/include/bolt/Passes/ValidateMemRefs.h
@@ -25,7 +25,7 @@ class ValidateMemRefs : public BinaryFunctionPass {
const char *getName() const override { return "validate-mem-refs"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
private:
bool checkAndFixJTReference(BinaryFunction &BF, MCInst &Inst,
diff --git a/bolt/include/bolt/Passes/VeneerElimination.h b/bolt/include/bolt/Passes/VeneerElimination.h
index 10c849674ab6df..9ba10408a4c87b 100644
--- a/bolt/include/bolt/Passes/VeneerElimination.h
+++ b/bolt/include/bolt/Passes/VeneerElimination.h
@@ -22,7 +22,7 @@ class VeneerElimination : public BinaryFunctionPass {
const char *getName() const override { return "veneer-elimination"; }
- void runOnFunctions(BinaryContext &BC) override;
+ Error runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
diff --git a/bolt/include/bolt/Rewrite/BinaryPassManager.h b/bolt/include/bolt/Rewrite/BinaryPassManager.h
index 84ab192c415a40..2297c3bf52fd66 100644
--- a/bolt/include/bolt/Rewrite/BinaryPassManager.h
+++ b/bolt/include/bolt/Rewrite/BinaryPassManager.h
@@ -46,10 +46,10 @@ class BinaryFunctionPassManager {
}
/// Run all registered passes in the order they were added.
- void runPasses();
+ Error runPasses();
/// Runs all enabled implemented passes on all functions.
- static void runAllPasses(BinaryContext &BC);
+ static Error runAllPasses(BinaryContext &BC);
};
} // namespace bolt
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index df835d2876804a..1c33544f40a113 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -83,6 +83,37 @@ cl::opt<std::string> CompDirOverride(
namespace llvm {
namespace bolt {
+char BOLTError::ID = 0;
+
+BOLTError::BOLTError(bool IsFatal, const Twine &S)
+ : IsFatal(IsFatal), Msg(S.str()) {}
+
+void BOLTError::log(raw_ostream &OS) const {
+ if (IsFatal)
+ OS << "FATAL ";
+ StringRef ErrMsg = StringRef(Msg);
+ // Prepend our error prefix if it is missing
+ if (ErrMsg.empty()) {
+ OS << "BOLT-ERROR\n";
+ } else {
+ if (!ErrMsg.starts_with("BOLT-ERROR"))
+ OS << "BOLT-ERROR: ";
+ OS << ErrMsg << "\n";
+ }
+}
+
+std::error_code BOLTError::convertToErrorCode() const {
+ return inconvertibleErrorCode();
+}
+
+Error createNonFatalBOLTError(const Twine &S) {
+ return make_error<BOLTError>(/*IsFatal*/ false, S);
+}
+
+Error createFatalBOLTError(const Twine &S) {
+ return make_error<BOLTError>(/*IsFatal*/ true, S);
+}
+
BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
std::unique_ptr<DWARFContext> DwCtx,
std::unique_ptr<Triple> TheTriple,
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 0ac47a53a44677..3f3da3b8004109 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -1021,24 +1021,25 @@ bool BinaryFunction::isZeroPaddingAt(uint64_t Offset) const {
return true;
}
-void BinaryFunction::handlePCRelOperand(MCInst &Instruction, uint64_t Address,
- uint64_t Size) {
+Error BinaryFunction::handlePCRelOperand(MCInst &Instruction, uint64_t Address,
+ uint64_t Size) {
auto &MIB = BC.MIB;
uint64_t TargetAddress = 0;
if (!MIB->evaluateMemOperandTarget(Instruction, TargetAddress, Address,
Size)) {
- errs() << "BOLT-ERROR: PC-relative operand can't be evaluated:\n";
- BC.InstPrinter->printInst(&Instruction, 0, "", *BC.STI, errs());
- errs() << '\n';
- Instruction.dump_pretty(errs(), BC.InstPrinter.get());
- errs() << '\n';
- errs() << "BOLT-ERROR: cannot handle PC-relative operand at 0x"
- << Twine::utohexstr(Address) << ". Skipping function " << *this
- << ".\n";
+ std::string Msg;
+ raw_string_ostream SS(Msg);
+ SS << "BOLT-ERROR: PC-relative operand can't be evaluated:\n";
+ BC.InstPrinter->printInst(&Instruction, 0, "", *BC.STI, SS);
+ SS << '\n';
+ Instruction.dump_pretty(SS, BC.InstPrinter.get());
+ SS << '\n';
+ SS << "BOLT-ERROR: cannot handle PC-relative operand at 0x"
+ << Twine::utohexstr(Address) << ". Skipping function " << *this << ".\n";
if (BC.HasRelocations)
- exit(1);
+ return createFatalBOLTError(Msg);
IsSimple = false;
- return;
+ return createNonFatalBOLTError(Msg);
}
if (TargetAddress == 0 && opts::Verbosity >= 1) {
outs() << "BOLT-INFO: PC-relative operand is zero in function " << *this
@@ -1054,6 +1055,7 @@ void BinaryFunction::handlePCRelOperand(MCInst &Instruction, uint64_t Address,
Instruction, TargetSymbol, static_cast<int64_t>(TargetOffset), &*BC.Ctx);
(void)ReplaceSuccess;
assert(ReplaceSuccess && "Failed to replace mem operand with symbol+off.");
+ return Error::success();
}
MCSymbol *BinaryFunction::handleExternalReference(MCInst &Instruction,
@@ -1164,7 +1166,7 @@ void BinaryFunction::handleAArch64IndirectCall(MCInst &Instruction,
}
}
-bool BinaryFunction::disassemble() {
+Error BinaryFunction::disassemble() {
NamedRegionTimer T("disassemble", "Disassemble function", "buildfuncs",
"Build Binary Functions", opts::TimeBuild);
ErrorOr<ArrayRef<uint8_t>> ErrorOrFunctionData = getData();
@@ -1332,8 +1334,19 @@ bool BinaryFunction::disassemble() {
if (MIB->isIndirectBranch(Instruction))
handleIndirectBranch(Instruction, Size, Offset);
// Indirect call. We only need to fix it if the operand is RIP-relative.
- if (IsSimple && MIB->hasPCRelOperand(Instruction))
- handlePCRelOperand(Instruction, AbsoluteInstrAddr, Size);
+ if (IsSimple && MIB->hasPCRelOperand(Instruction)) {
+ if (auto NewE = handleErrors(
+ handlePCRelOperand(Instruction, AbsoluteInstrAddr, Size),
+ [&](const BOLTError &E) -> Error {
+ if (E.isFatal())
+ return Error(std::make_unique<BOLTError>(std::move(E)));
+ if (!E.getMessage().empty())
+ E.log(errs());
+ return Error::success();
+ })) {
+ return Error(std::move(NewE));
+ }
+ }
if (BC.isAArch64())
handleAArch64IndirectCall(Instruction, Offset);
@@ -1372,8 +1385,18 @@ bool BinaryFunction::disassemble() {
UsedReloc = true;
}
- if (!BC.isRISCV() && MIB->hasPCRelOperand(Instruction) && !UsedReloc)
- handlePCRelOperand(Instruction, AbsoluteInstrAddr, Size);
+ if (!BC.isRISCV() && MIB->hasPCRelOperand(Instruction) && !UsedReloc) {
+ if (auto NewE = handleErrors(
+ handlePCRelOperand(Instruction, AbsoluteInstrAddr, Size),
+ [&](const BOLTError &E) -> Error {
+ if (E.isFatal())
+ return Error(std::make_unique<BOLTError>(std::move(E)));
+ if (!E.getMessage().empty())
+ E.log(errs());
+ return Error::success();
+ }))
+ return Error(std::move(NewE));
+ }
}
add_instruction:
@@ -1413,12 +1436,12 @@ bool BinaryFunction::disassemble() {
if (!IsSimple) {
clearList(Instructions);
- return false;
+ return createNonFatalBOLTError("");
}
updateState(State::Disassembled);
- return true;
+ return Error::success();
}
bool BinaryFunction::scanExternalRefs() {
@@ -1946,17 +1969,17 @@ void BinaryFunction::recomputeLandingPads() {
}
}
-bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
+Error BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
auto &MIB = BC.MIB;
if (!isSimple()) {
assert(!BC.HasRelocations &&
"cannot process file with non-simple function in relocs mode");
- return false;
+ return createNonFatalBOLTError("");
}
if (CurrentState != State::Disassembled)
- return false;
+ return createNonFatalBOLTError("");
assert(BasicBlocks.empty() && "basic block list should be empty");
assert((Labels.find(getFirstInstructionOffset()) != Labels.end()) &&
@@ -2093,7 +2116,7 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
if (BasicBlocks.empty()) {
setSimple(false);
- return false;
+ return createNonFatalBOLTError("");
}
// Intermediate dump.
@@ -2204,7 +2227,7 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
clearList(ExternallyReferencedOffsets);
clearList(UnknownIndirectBranchOffsets);
- return true;
+ return Error::success();
}
void BinaryFunction::postProcessCFG() {
diff --git a/bolt/lib/Core/BinarySection.cpp b/bolt/lib/Core/BinarySection.cpp
index 97bc2519354753..564c63e81914c3 100644
--- a/bolt/lib/Core/BinarySection.cpp
+++ b/bolt/lib/Core/BinarySection.cpp
@@ -198,7 +198,7 @@ BinarySection::~BinarySection() {
if (!isAllocatable() && !hasValidSectionID() &&
(!hasSectionRef() ||
- OutputContents.data() != getContents(Section).data())) {
+ OutputContents.data() != getContentsOrQuit(Section).data())) {
delete[] getOutputData();
}
}
diff --git a/bolt/lib/Core/Exceptions.cpp b/bolt/lib/Core/Exceptions.cpp
index ab1885f6bb5851..dd3fa46b6f1280 100644
--- a/bolt/lib/Core/Exceptions.cpp
+++ b/bolt/lib/Core/Exceptions.cpp
@@ -98,12 +98,12 @@ namespace bolt {
// site table will be the same size as GCC uses uleb encodings for PC offsets.
//
// Note: some functions have LSDA entries with 0 call site entries.
-void BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
- uint64_t LSDASectionAddress) {
+Error BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
+ uint64_t LSDASectionAddress) {
assert(CurrentState == State::Disassembled && "unexpected function state");
if (!getLSDAAddress())
- return;
+ return Error::success();
DWARFDataExtractor Data(
StringRef(reinterpret_cast<const char *>(LSDASectionData.data()),
@@ -121,7 +121,7 @@ void BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
if (!MaybeLPStart) {
errs() << "BOLT-ERROR: unsupported LPStartEncoding: "
<< (unsigned)LPStartEncoding << '\n';
- exit(1);
+ return createFatalBOLTError("");
}
LPStart = *MaybeLPStart;
}
@@ -209,7 +209,7 @@ void BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
"BOLT-ERROR: cannot have landing pads in different functions");
setHasIndirectTargetToSplitFragment(true);
BC.addFragmentsToSkip(this);
- return;
+ return Error::success();
}
const uint64_t LPOffset = LandingPad - getAddress();
@@ -354,6 +354,7 @@ void BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
LSDATypeIndexTable =
LSDASectionData.slice(TypeIndexTableStart, MaxTypeIndexTableOffset);
}
+ return Error::success();
}
void BinaryFunction::updateEHRanges() {
diff --git a/bolt/lib/Passes/ADRRelaxationPass.cpp b/bolt/lib/Passes/ADRRelaxationPass.cpp
index 27a1377adef164..aa715a3f378715 100644
--- a/bolt/lib/Passes/ADRRelaxationPass.cpp
+++ b/bolt/lib/Passes/ADRRelaxationPass.cpp
@@ -97,9 +97,9 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
}
}
-void ADRRelaxationPass::runOnFunctions(BinaryContext &BC) {
+Error ADRRelaxationPass::runOnFunctions(BinaryContext &BC) {
if (!opts::AdrPassOpt || !BC.HasRelocations)
- return;
+ return Error::success();
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
runOnFunction(BF);
@@ -110,7 +110,8 @@ void ADRRelaxationPass::runOnFunctions(BinaryContext &BC) {
"ADRRelaxationPass");
if (PassFailed)
- exit(1);
+ return createFatalBOLTError("");
+ return Error::success();
}
} // end namespace bolt
diff --git a/bolt/lib/Passes/Aligner.cpp b/bolt/lib/Passes/Aligner.cpp
index 7c387525434bd3..555f82a5a81780 100644
--- a/bolt/lib/Passes/Aligner.cpp
+++ b/bolt/lib/Passes/Aligner.cpp
@@ -147,9 +147,9 @@ void AlignerPass::alignBlocks(BinaryFunction &Function,
}
}
-void AlignerPass::runOnFunctions(BinaryContext &BC) {
+Error AlignerPass::runOnFunctions(BinaryContext &BC) {
if (!BC.HasRelocations)
- return;
+ return Error::success();
AlignHistogram.resize(opts::BlockAlignment);
@@ -179,6 +179,7 @@ void AlignerPass::runOnFunctions(BinaryContext &BC) {
dbgs() << "BOLT-DEBUG: total execution count of aligned blocks: "
<< AlignedBlocksCount << '\n';
);
+ return Error::success();
}
} // end namespace bolt
diff --git a/bolt/lib/Passes/AllocCombiner.cpp b/bolt/lib/Passes/AllocCombiner.cpp
index 6d3f2a56424cb1..2397dc49c0fb12 100644
--- a/bolt/lib/Passes/AllocCombiner.cpp
+++ b/bolt/lib/Passes/AllocCombiner.cpp
@@ -103,9 +103,9 @@ void AllocCombinerPass::combineAdjustments(BinaryFunction &BF) {
}
}
-void AllocCombinerPass::runOnFunctions(BinaryContext &BC) {
+Error AllocCombinerPass::runOnFunctions(BinaryContext &BC) {
if (opts::FrameOptimization == FOP_NONE)
- return;
+ return Error::success();
runForAllWeCare(BC.getBinaryFunctions(), [&](BinaryFunction &Function) {
combineAdjustments(Function);
@@ -114,6 +114,7 @@ void AllocCombinerPass::runOnFunctions(BinaryContext &BC) {
outs() << "BOLT-INFO: Allocation combiner: " << NumCombined
<< " empty spaces coalesced (dyn count: " << DynamicCountCombined
<< ").\n";
+ return Error::success();
}
} // end namespace bolt
diff --git a/bolt/lib/Passes/AsmDump.cpp b/bolt/lib/Passes/AsmDump.cpp
index 18d0395cbc4ad7..1eaf890ff9b3a0 100644
--- a/bolt/lib/Passes/AsmDump.cpp
+++ b/bolt/lib/Passes/AsmDump.cpp
@@ -237,9 +237,10 @@ void dumpFunction(const BinaryFunction &BF) {
dumpBinaryDataSymbols(OS, BD, LastSection);
}
-void AsmDumpPass::runOnFunctions(BinaryContext &BC) {
+Error AsmDumpPass::runOnFunctions(BinaryContext &BC) {
for (const auto &BFIt : BC.getBinaryFunctions())
dumpFunction(BFIt.second);
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp
index 08dce2fee1828e..4d92b27462513c 100644
--- a/bolt/lib/Passes/BinaryPasses.cpp
+++ b/bolt/lib/Passes/BinaryPasses.cpp
@@ -301,7 +301,7 @@ void NormalizeCFG::runOnFunction(BinaryFunction &BF) {
NumBlocksRemoved += NumRemoved;
}
-void NormalizeCFG::runOnFunctions(BinaryContext &BC) {
+Error NormalizeCFG::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_BB_LINEAR,
[&](BinaryFunction &BF) { runOnFunction(BF); },
@@ -314,6 +314,7 @@ void NormalizeCFG::runOnFunctions(BinaryContext &BC) {
outs() << "BOLT-INFO: merged " << NumDuplicateEdgesMerged
<< " duplicate CFG edge" << (NumDuplicateEdgesMerged == 1 ? "" : "s")
<< '\n';
+ return Error::success();
}
void EliminateUnreachableBlocks::runOnFunction(BinaryFunction &Function) {
@@ -345,7 +346,7 @@ void EliminateUnreachableBlocks::runOnFunction(BinaryFunction &Function) {
}
}
-void EliminateUnreachableBlocks::runOnFunctions(BinaryContext &BC) {
+Error EliminateUnreachableBlocks::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
runOnFunction(BF);
};
@@ -361,6 +362,7 @@ void EliminateUnreachableBlocks::runOnFunctions(BinaryContext &BC) {
if (DeletedBlocks)
outs() << "BOLT-INFO: UCE removed " << DeletedBlocks << " blocks and "
<< DeletedBytes << " bytes of code\n";
+ return Error::success();
}
bool ReorderBasicBlocks::shouldPrint(const BinaryFunction &BF) const {
@@ -376,9 +378,9 @@ bool ReorderBasicBlocks::shouldOptimize(const BinaryFunction &BF) const {
return BinaryFunctionPass::shouldOptimize(BF);
}
-void ReorderBasicBlocks::runOnFunctions(BinaryContext &BC) {
+Error ReorderBasicBlocks::runOnFunctions(BinaryContext &BC) {
if (opts::ReorderBlocks == ReorderBasicBlocks::LT_NONE)
- return;
+ return Error::success();
std::atomic_uint64_t ModifiedFuncCount(0);
std::mutex FunctionEditDistanceMutex;
@@ -452,6 +454,7 @@ void ReorderBasicBlocks::runOnFunctions(BinaryContext &BC) {
<< FunctionEditDistance.lookup(&Function) << "\n\n";
}
}
+ return Error::success();
}
bool ReorderBasicBlocks::modifyFunctionLayout(BinaryFunction &BF,
@@ -513,7 +516,7 @@ bool ReorderBasicBlocks::modifyFunctionLayout(BinaryFunction &BF,
return BF.getLayout().update(NewLayout);
}
-void FixupBranches::runOnFunctions(BinaryContext &BC) {
+Error FixupBranches::runOnFunctions(BinaryContext &BC) {
for (auto &It : BC.getBinaryFunctions()) {
BinaryFunction &Function = It.second;
if (!BC.shouldEmit(Function) || !Function.isSimple())
@@ -521,15 +524,18 @@ void FixupBranches::runOnFunctions(BinaryContext &BC) {
Function.fixBranches();
}
+ return Error::success();
}
-void FinalizeFunctions::runOnFunctions(BinaryContext &BC) {
+Error FinalizeFunctions::runOnFunctions(BinaryContext &BC) {
+ std::atomic<bool> HasFatal{false};
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
if (!BF.finalizeCFIState()) {
if (BC.HasRelocations) {
errs() << "BOLT-ERROR: unable to fix CFI state for function " << BF
<< ". Exiting.\n";
- exit(1);
+ HasFatal = true;
+ return;
}
BF.setSimple(false);
return;
@@ -548,11 +554,14 @@ void FinalizeFunctions::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_CONSTANT, WorkFun,
SkipPredicate, "FinalizeFunctions");
+ if (HasFatal)
+ return createFatalBOLTError("finalize CFI state failure");
+ return Error::success();
}
-void CheckLargeFunctions::runOnFunctions(BinaryContext &BC) {
+Error CheckLargeFunctions::runOnFunctions(BinaryContext &BC) {
if (BC.HasRelocations)
- return;
+ return Error::success();
// If the function wouldn't fit, mark it as non-simple. Otherwise, we may emit
// incorrect meta data.
@@ -571,6 +580,8 @@ void CheckLargeFunctions::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun,
SkipFunc, "CheckLargeFunctions");
+
+ return Error::success();
}
bool CheckLargeFunctions::shouldOptimize(const BinaryFunction &BF) const {
@@ -578,7 +589,7 @@ bool CheckLargeFunctions::shouldOptimize(const BinaryFunction &BF) const {
return BF.isSimple() && !BF.isIgnored();
}
-void LowerAnnotations::runOnFunctions(BinaryContext &BC) {
+Error LowerAnnotations::runOnFunctions(BinaryContext &BC) {
// Convert GnuArgsSize annotations into CFIs.
for (BinaryFunction *BF : BC.getAllBinaryFunctions()) {
for (FunctionFragment &FF : BF->getLayout().fragments()) {
@@ -604,13 +615,14 @@ void LowerAnnotations::runOnFunctions(BinaryContext &BC) {
}
}
}
+ return Error::success();
}
// Check for dirty state in MCSymbol objects that might be a consequence
// of running calculateEmittedSize() in parallel, during split functions
// pass. If an inconsistent state is found (symbol already registered or
// already defined), clean it.
-void CleanMCState::runOnFunctions(BinaryContext &BC) {
+Error CleanMCState::runOnFunctions(BinaryContext &BC) {
MCContext &Ctx = *BC.Ctx;
for (const auto &SymMapEntry : Ctx.getSymbols()) {
const MCSymbol *S = SymMapEntry.second;
@@ -628,6 +640,7 @@ void CleanMCState::runOnFunctions(BinaryContext &BC) {
dbgs() << "BOLT-DEBUG: Symbol \"" << S->getName() << "\" is variable\n";
});
}
+ return Error::success();
}
// This peephole fixes jump instructions that jump to another basic
@@ -963,9 +976,9 @@ uint64_t SimplifyConditionalTailCalls::fixTailCalls(BinaryFunction &BF) {
return NumLocalCTCs > 0;
}
-void SimplifyConditionalTailCalls::runOnFunctions(BinaryContext &BC) {
+Error SimplifyConditionalTailCalls::runOnFunctions(BinaryContext &BC) {
if (!BC.isX86())
- return;
+ return Error::success();
for (auto &It : BC.getBinaryFunctions()) {
BinaryFunction &Function = It.second;
@@ -990,6 +1003,7 @@ void SimplifyConditionalTailCalls::runOnFunctions(BinaryContext &BC) {
<< " bytes of code. CTCs total execution count is " << CTCExecCount
<< " and the number of times CTCs are taken is " << CTCTakenCount
<< "\n";
+ return Error::success();
}
uint64_t ShortenInstructions::shortenInstructions(BinaryFunction &Function) {
@@ -1019,10 +1033,10 @@ uint64_t ShortenInstructions::shortenInstructions(BinaryFunction &Function) {
return Count;
}
-void ShortenInstructions::runOnFunctions(BinaryContext &BC) {
+Error ShortenInstructions::runOnFunctions(BinaryContext &BC) {
std::atomic<uint64_t> NumShortened{0};
if (!BC.isX86())
- return;
+ return Error::success();
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR,
@@ -1031,6 +1045,7 @@ void ShortenInstructions::runOnFunctions(BinaryContext &BC) {
if (NumShortened)
outs() << "BOLT-INFO: " << NumShortened << " instructions were shortened\n";
+ return Error::success();
}
void Peepholes::addTailcallTraps(BinaryFunction &Function) {
@@ -1073,12 +1088,12 @@ void Peepholes::removeUselessCondBranches(BinaryFunction &Function) {
}
}
-void Peepholes::runOnFunctions(BinaryContext &BC) {
+Error Peepholes::runOnFunctions(BinaryContext &BC) {
const char Opts =
std::accumulate(opts::Peepholes.begin(), opts::Peepholes.end(), 0,
[](const char A, const PeepholeOpts B) { return A | B; });
if (Opts == PEEP_NONE)
- return;
+ return Error::success();
for (auto &It : BC.getBinaryFunctions()) {
BinaryFunction &Function = It.second;
@@ -1098,6 +1113,7 @@ void Peepholes::runOnFunctions(BinaryContext &BC) {
<< " tail call traps inserted.\n"
<< "BOLT-INFO: Peephole: " << NumUselessCondBranches
<< " useless conditional branches removed.\n";
+ return Error::success();
}
bool SimplifyRODataLoads::simplifyRODataLoads(BinaryFunction &BF) {
@@ -1182,7 +1198,7 @@ bool SimplifyRODataLoads::simplifyRODataLoads(BinaryFunction &BF) {
return NumLocalLoadsSimplified > 0;
}
-void SimplifyRODataLoads::runOnFunctions(BinaryContext &BC) {
+Error SimplifyRODataLoads::runOnFunctions(BinaryContext &BC) {
for (auto &It : BC.getBinaryFunctions()) {
BinaryFunction &Function = It.second;
if (shouldOptimize(Function) && simplifyRODataLoads(Function))
@@ -1194,9 +1210,10 @@ void SimplifyRODataLoads::runOnFunctions(BinaryContext &BC) {
<< "BOLT-INFO: dynamic loads simplified: " << NumDynamicLoadsSimplified
<< "\n"
<< "BOLT-INFO: dynamic loads found: " << NumDynamicLoadsFound << "\n";
+ return Error::success();
}
-void AssignSections::runOnFunctions(BinaryContext &BC) {
+Error AssignSections::runOnFunctions(BinaryContext &BC) {
for (BinaryFunction *Function : BC.getInjectedBinaryFunctions()) {
Function->setCodeSectionName(BC.getInjectedCodeSectionName());
Function->setColdCodeSectionName(BC.getInjectedColdCodeSectionName());
@@ -1204,7 +1221,7 @@ void AssignSections::runOnFunctions(BinaryContext &BC) {
// In non-relocation mode functions have pre-assigned section names.
if (!BC.HasRelocations)
- return;
+ return Error::success();
const bool UseColdSection =
BC.NumProfiledFuncs > 0 ||
@@ -1225,9 +1242,10 @@ void AssignSections::runOnFunctions(BinaryContext &BC) {
if (Function.isSplit())
Function.setColdCodeSectionName(BC.getColdCodeSectionName());
}
+ return Error::success();
}
-void PrintProfileStats::runOnFunctions(BinaryContext &BC) {
+Error PrintProfileStats::runOnFunctions(BinaryContext &BC) {
double FlowImbalanceMean = 0.0;
size_t NumBlocksConsidered = 0;
double WorstBias = 0.0;
@@ -1318,9 +1336,10 @@ void PrintProfileStats::runOnFunctions(BinaryContext &BC) {
<< "\n";
LLVM_DEBUG(WorstBiasFunc->dump());
}
+ return Error::success();
}
-void PrintProgramStats::runOnFunctions(BinaryContext &BC) {
+Error PrintProgramStats::runOnFunctions(BinaryContext &BC) {
uint64_t NumRegularFunctions = 0;
uint64_t NumStaleProfileFunctions = 0;
uint64_t NumAllStaleFunctions = 0;
@@ -1437,9 +1456,9 @@ void PrintProgramStats::runOnFunctions(BinaryContext &BC) {
<< format(" (%.1f%% of all stale)", PctStaleBlocksWithEqualIcount)
<< " have matching icount.\n";
if (PctStale > opts::StaleThreshold) {
- errs() << "BOLT-ERROR: stale functions exceed specified threshold of "
- << opts::StaleThreshold << "%. Exiting.\n";
- exit(1);
+ return createFatalBOLTError(
+ Twine("BOLT-ERROR: stale functions exceed specified threshold of ") +
+ Twine(opts::StaleThreshold.getValue()) + Twine("%. Exiting.\n"));
}
}
if (NumInferredFunctions) {
@@ -1633,18 +1652,20 @@ void PrintProgramStats::runOnFunctions(BinaryContext &BC) {
outs() << ". Use -print-unknown to see the list.";
outs() << '\n';
}
+ return Error::success();
}
-void InstructionLowering::runOnFunctions(BinaryContext &BC) {
+Error InstructionLowering::runOnFunctions(BinaryContext &BC) {
for (auto &BFI : BC.getBinaryFunctions())
for (BinaryBasicBlock &BB : BFI.second)
for (MCInst &Instruction : BB)
BC.MIB->lowerTailCall(Instruction);
+ return Error::success();
}
-void StripRepRet::runOnFunctions(BinaryContext &BC) {
+Error StripRepRet::runOnFunctions(BinaryContext &BC) {
if (!BC.isX86())
- return;
+ return Error::success();
uint64_t NumPrefixesRemoved = 0;
uint64_t NumBytesSaved = 0;
@@ -1665,11 +1686,12 @@ void StripRepRet::runOnFunctions(BinaryContext &BC) {
<< " 'repz' prefixes"
" with estimated execution count of "
<< NumPrefixesRemoved << " times.\n";
+ return Error::success();
}
-void InlineMemcpy::runOnFunctions(BinaryContext &BC) {
+Error InlineMemcpy::runOnFunctions(BinaryContext &BC) {
if (!BC.isX86())
- return;
+ return Error::success();
uint64_t NumInlined = 0;
uint64_t NumInlinedDyno = 0;
@@ -1714,6 +1736,7 @@ void InlineMemcpy::runOnFunctions(BinaryContext &BC) {
<< " times based on profile.";
outs() << '\n';
}
+ return Error::success();
}
bool SpecializeMemcpy1::shouldOptimize(const BinaryFunction &Function) const {
@@ -1754,9 +1777,9 @@ std::set<size_t> SpecializeMemcpy1::getCallSitesToOptimize(
return Sites;
}
-void SpecializeMemcpy1::runOnFunctions(BinaryContext &BC) {
+Error SpecializeMemcpy1::runOnFunctions(BinaryContext &BC) {
if (!BC.isX86())
- return;
+ return Error::success();
uint64_t NumSpecialized = 0;
uint64_t NumSpecializedDyno = 0;
@@ -1848,6 +1871,7 @@ void SpecializeMemcpy1::runOnFunctions(BinaryContext &BC) {
<< " times based on profile.";
outs() << '\n';
}
+ return Error::success();
}
void RemoveNops::runOnFunction(BinaryFunction &BF) {
@@ -1861,7 +1885,7 @@ void RemoveNops::runOnFunction(BinaryFunction &BF) {
}
}
-void RemoveNops::runOnFunctions(BinaryContext &BC) {
+Error RemoveNops::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
runOnFunction(BF);
};
@@ -1873,6 +1897,7 @@ void RemoveNops::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun,
SkipFunc, "RemoveNops");
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/CMOVConversion.cpp b/bolt/lib/Passes/CMOVConversion.cpp
index 6213479a5090ae..adb6115a61dee1 100644
--- a/bolt/lib/Passes/CMOVConversion.cpp
+++ b/bolt/lib/Passes/CMOVConversion.cpp
@@ -271,7 +271,7 @@ void CMOVConversion::runOnFunction(BinaryFunction &Function) {
Global = Global + Local;
}
-void CMOVConversion::runOnFunctions(BinaryContext &BC) {
+Error CMOVConversion::runOnFunctions(BinaryContext &BC) {
for (auto &It : BC.getBinaryFunctions()) {
BinaryFunction &Function = It.second;
if (!shouldOptimize(Function))
@@ -281,6 +281,7 @@ void CMOVConversion::runOnFunctions(BinaryContext &BC) {
outs() << "BOLT-INFO: CMOVConversion total: ";
Global.dump();
+ return Error::success();
}
} // end namespace bolt
diff --git a/bolt/lib/Passes/FixRISCVCallsPass.cpp b/bolt/lib/Passes/FixRISCVCallsPass.cpp
index e2984deda16dc3..83c745facb290b 100644
--- a/bolt/lib/Passes/FixRISCVCallsPass.cpp
+++ b/bolt/lib/Passes/FixRISCVCallsPass.cpp
@@ -68,9 +68,9 @@ void FixRISCVCallsPass::runOnFunction(BinaryFunction &BF) {
}
}
-void FixRISCVCallsPass::runOnFunctions(BinaryContext &BC) {
+Error FixRISCVCallsPass::runOnFunctions(BinaryContext &BC) {
if (!BC.isRISCV() || !BC.HasRelocations)
- return;
+ return Error::success();
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
runOnFunction(BF);
@@ -79,6 +79,8 @@ void FixRISCVCallsPass::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun, nullptr,
"FixRISCVCalls");
+
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/FixRelaxationPass.cpp b/bolt/lib/Passes/FixRelaxationPass.cpp
index 3dd19b6b43b767..a49fb9894e808c 100644
--- a/bolt/lib/Passes/FixRelaxationPass.cpp
+++ b/bolt/lib/Passes/FixRelaxationPass.cpp
@@ -47,9 +47,9 @@ void FixRelaxations::runOnFunction(BinaryFunction &BF) {
}
}
-void FixRelaxations::runOnFunctions(BinaryContext &BC) {
+Error FixRelaxations::runOnFunctions(BinaryContext &BC) {
if (!BC.isAArch64() || !BC.HasRelocations)
- return;
+ return Error::success();
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
runOnFunction(BF);
@@ -58,6 +58,7 @@ void FixRelaxations::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun, nullptr,
"FixRelaxations");
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/FrameOptimizer.cpp b/bolt/lib/Passes/FrameOptimizer.cpp
index 6f6dea08950a7d..30bcfb9084e9cc 100644
--- a/bolt/lib/Passes/FrameOptimizer.cpp
+++ b/bolt/lib/Passes/FrameOptimizer.cpp
@@ -221,9 +221,9 @@ void FrameOptimizerPass::removeUnusedStores(const FrameAnalysis &FA,
LLVM_DEBUG(dbgs() << "FOP modified \"" << BF.getPrintName() << "\"\n");
}
-void FrameOptimizerPass::runOnFunctions(BinaryContext &BC) {
+Error FrameOptimizerPass::runOnFunctions(BinaryContext &BC) {
if (opts::FrameOptimization == FOP_NONE)
- return;
+ return Error::success();
std::unique_ptr<BinaryFunctionCallGraph> CG;
std::unique_ptr<FrameAnalysis> FA;
@@ -285,7 +285,8 @@ void FrameOptimizerPass::runOnFunctions(BinaryContext &BC) {
{
NamedRegionTimer T1("shrinkwrapping", "shrink wrapping", "FOP",
"FOP breakdown", opts::TimeOpts);
- performShrinkWrapping(*RA, *FA, BC);
+ if (Error E = performShrinkWrapping(*RA, *FA, BC))
+ return Error(std::move(E));
}
outs() << "BOLT-INFO: FOP optimized " << NumRedundantLoads
@@ -303,11 +304,12 @@ void FrameOptimizerPass::runOnFunctions(BinaryContext &BC) {
<< NumRedundantStores << " store(s)\n";
FA->printStats();
ShrinkWrapping::printStats();
+ return Error::success();
}
-void FrameOptimizerPass::performShrinkWrapping(const RegAnalysis &RA,
- const FrameAnalysis &FA,
- BinaryContext &BC) {
+Error FrameOptimizerPass::performShrinkWrapping(const RegAnalysis &RA,
+ const FrameAnalysis &FA,
+ BinaryContext &BC) {
// Initialize necessary annotations to allow safe parallel accesses to
// annotation index in MIB
BC.MIB->getOrCreateAnnotationIndex(CalleeSavedAnalysis::getSaveTagName());
@@ -357,12 +359,21 @@ void FrameOptimizerPass::performShrinkWrapping(const RegAnalysis &RA,
const bool HotOnly = opts::FrameOptimization == FOP_HOT;
+ Error SWError = Error::success();
+
ParallelUtilities::WorkFuncWithAllocTy WorkFunction =
[&](BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocatorId) {
DataflowInfoManager Info(BF, &RA, &FA, AllocatorId);
ShrinkWrapping SW(FA, BF, Info, AllocatorId);
- if (SW.perform(HotOnly)) {
+ auto ChangedOrErr = SW.perform(HotOnly);
+ if (auto E = ChangedOrErr.takeError()) {
+ std::lock_guard<std::mutex> Lock(FuncsChangedMutex);
+ SWError = joinErrors(std::move(SWError), Error(std::move(E)));
+ return;
+ }
+ const bool Changed = *ChangedOrErr;
+ if (Changed) {
std::lock_guard<std::mutex> Lock(FuncsChangedMutex);
FuncsChanged.insert(&BF);
LLVM_DEBUG(LogFunc(BF));
@@ -378,6 +389,7 @@ void FrameOptimizerPass::performShrinkWrapping(const RegAnalysis &RA,
for (const auto &Elmt : Top10Funcs)
outs() << Elmt.first << " : " << Elmt.second->getPrintName() << "\n";
}
+ return SWError;
}
} // namespace bolt
diff --git a/bolt/lib/Passes/Hugify.cpp b/bolt/lib/Passes/Hugify.cpp
index d2a64fb97c196d..b77356153bfd8c 100644
--- a/bolt/lib/Passes/Hugify.cpp
+++ b/bolt/lib/Passes/Hugify.cpp
@@ -16,10 +16,10 @@ using namespace llvm;
namespace llvm {
namespace bolt {
-void HugePage::runOnFunctions(BinaryContext &BC) {
+Error HugePage::runOnFunctions(BinaryContext &BC) {
auto *RtLibrary = BC.getRuntimeLibrary();
if (!RtLibrary || !BC.isELF() || !BC.StartFunctionAddress) {
- return;
+ return Error::success();
}
auto createSimpleFunction =
@@ -45,6 +45,7 @@ void HugePage::runOnFunctions(BinaryContext &BC) {
const MCSymbol *StartSym = Start->getSymbol();
createSimpleFunction("__bolt_hugify_start_program",
BC.MIB->createSymbolTrampoline(StartSym, BC.Ctx.get()));
+ return Error::success();
}
} // namespace bolt
} // namespace llvm
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index dfbc72e48e5d28..ba3afd27090d00 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -341,7 +341,7 @@ typedef std::unordered_map<BinaryFunction *, std::vector<BinaryFunction *>,
namespace llvm {
namespace bolt {
-void IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
+Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
const size_t OriginalFunctionCount = BC.getBinaryFunctions().size();
uint64_t NumFunctionsFolded = 0;
std::atomic<uint64_t> NumJTFunctionsFolded{0};
@@ -516,6 +516,8 @@ void IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
<< format("%.2lf", (double)BytesSavedEstimate / 1024)
<< " KB of code space. Folded functions were called " << NumCalled
<< " times based on profile.\n";
+
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/IndirectCallPromotion.cpp b/bolt/lib/Passes/IndirectCallPromotion.cpp
index 451758161ef5e6..d1dc1af77e835b 100644
--- a/bolt/lib/Passes/IndirectCallPromotion.cpp
+++ b/bolt/lib/Passes/IndirectCallPromotion.cpp
@@ -1137,9 +1137,9 @@ void IndirectCallPromotion::printCallsiteInfo(
});
}
-void IndirectCallPromotion::runOnFunctions(BinaryContext &BC) {
+Error IndirectCallPromotion::runOnFunctions(BinaryContext &BC) {
if (opts::ICP == ICP_NONE)
- return;
+ return Error::success();
auto &BFs = BC.getBinaryFunctions();
@@ -1472,6 +1472,7 @@ void IndirectCallPromotion::runOnFunctions(BinaryContext &BC) {
#ifndef NDEBUG
verifyProfile(BFs);
#endif
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/Inliner.cpp b/bolt/lib/Passes/Inliner.cpp
index 8dcb8934f2d20f..d875ecbd0d4400 100644
--- a/bolt/lib/Passes/Inliner.cpp
+++ b/bolt/lib/Passes/Inliner.cpp
@@ -496,11 +496,11 @@ bool Inliner::inlineCallsInFunction(BinaryFunction &Function) {
return DidInlining;
}
-void Inliner::runOnFunctions(BinaryContext &BC) {
+Error Inliner::runOnFunctions(BinaryContext &BC) {
opts::syncOptions();
if (!opts::inliningEnabled())
- return;
+ return Error::success();
bool InlinedOnce;
unsigned NumIters = 0;
@@ -544,6 +544,7 @@ void Inliner::runOnFunctions(BinaryContext &BC) {
<< NumInlinedCallSites << " call sites in " << NumIters
<< " iteration(s). Change in binary size: " << TotalInlinedBytes
<< " bytes.\n";
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/Instrumentation.cpp b/bolt/lib/Passes/Instrumentation.cpp
index e54b0cacc4ca96..26b4a67fec4225 100644
--- a/bolt/lib/Passes/Instrumentation.cpp
+++ b/bolt/lib/Passes/Instrumentation.cpp
@@ -526,7 +526,7 @@ void Instrumentation::instrumentFunction(BinaryFunction &Function,
FuncDesc->EdgesSet.clear();
}
-void Instrumentation::runOnFunctions(BinaryContext &BC) {
+Error Instrumentation::runOnFunctions(BinaryContext &BC) {
const unsigned Flags = BinarySection::getFlags(/*IsReadOnly=*/false,
/*IsText=*/false,
/*IsAllocatable=*/true);
@@ -567,10 +567,9 @@ void Instrumentation::runOnFunctions(BinaryContext &BC) {
ErrorOr<BinarySection &> SetupSection =
BC.getUniqueSectionByName("I__setup");
- if (!SetupSection) {
- llvm::errs() << "Cannot find I__setup section\n";
- exit(1);
- }
+ if (!SetupSection)
+ return createFatalBOLTError("Cannot find I__setup section\n");
+
MCSymbol *Target = BC.registerNameAtAddress(
"__bolt_instr_setup", SetupSection->getAddress(), 0, 0);
MCInst NewInst;
@@ -586,10 +585,9 @@ void Instrumentation::runOnFunctions(BinaryContext &BC) {
BinaryBasicBlock &BB = Ctor->front();
ErrorOr<BinarySection &> FiniSection =
BC.getUniqueSectionByName("I__fini");
- if (!FiniSection) {
- llvm::errs() << "Cannot find I__fini section\n";
- exit(1);
- }
+ if (!FiniSection)
+ return createFatalBOLTError("Cannot find I__fini section");
+
MCSymbol *Target = BC.registerNameAtAddress(
"__bolt_instr_fini", FiniSection->getAddress(), 0, 0);
auto IsLEA = [&BC](const MCInst &Inst) { return BC.MIB->isLEA64r(Inst); };
@@ -603,6 +601,7 @@ void Instrumentation::runOnFunctions(BinaryContext &BC) {
}
setupRuntimeLibrary(BC);
+ return Error::success();
}
void Instrumentation::createAuxiliaryFunctions(BinaryContext &BC) {
diff --git a/bolt/lib/Passes/JTFootprintReduction.cpp b/bolt/lib/Passes/JTFootprintReduction.cpp
index d690e4d0c003dd..5d2e27affc8e74 100644
--- a/bolt/lib/Passes/JTFootprintReduction.cpp
+++ b/bolt/lib/Passes/JTFootprintReduction.cpp
@@ -246,9 +246,9 @@ void JTFootprintReduction::optimizeFunction(BinaryFunction &Function,
++I;
}
-void JTFootprintReduction::runOnFunctions(BinaryContext &BC) {
+Error JTFootprintReduction::runOnFunctions(BinaryContext &BC) {
if (opts::JumpTables == JTS_BASIC && BC.HasRelocations)
- return;
+ return Error::success();
std::unique_ptr<RegAnalysis> RA;
std::unique_ptr<BinaryFunctionCallGraph> CG;
@@ -273,7 +273,7 @@ void JTFootprintReduction::runOnFunctions(BinaryContext &BC) {
if (TotalJTs == TotalJTsDenied) {
outs() << "BOLT-INFO: JT Footprint reduction: no changes were made.\n";
- return;
+ return Error::success();
}
outs() << "BOLT-INFO: JT Footprint reduction stats (simple funcs only):\n";
@@ -289,6 +289,7 @@ void JTFootprintReduction::runOnFunctions(BinaryContext &BC) {
outs() << "\t " << NumJTsNoReg
<< " JTs discarded due to register unavailability.\n";
outs() << "\t " << BytesSaved << " bytes saved.\n";
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/LongJmp.cpp b/bolt/lib/Passes/LongJmp.cpp
index ded0db2cd30b61..72823b9c193d3a 100644
--- a/bolt/lib/Passes/LongJmp.cpp
+++ b/bolt/lib/Passes/LongJmp.cpp
@@ -459,13 +459,13 @@ uint64_t LongJmpPass::getSymbolAddress(const BinaryContext &BC,
return Iter->second;
}
-bool LongJmpPass::relaxStub(BinaryBasicBlock &StubBB) {
+Error LongJmpPass::relaxStub(BinaryBasicBlock &StubBB, bool &Modified) {
const BinaryFunction &Func = *StubBB.getFunction();
const BinaryContext &BC = Func.getBinaryContext();
const int Bits = StubBits[&StubBB];
// Already working with the largest range?
if (Bits == static_cast<int>(BC.AsmInfo->getCodePointerSize() * 8))
- return false;
+ return Error::success();
const static int RangeShortJmp = BC.MIB->getShortJmpEncodingSize();
const static int RangeSingleInstr = BC.MIB->getUncondBranchEncodingSize();
@@ -481,12 +481,12 @@ bool LongJmpPass::relaxStub(BinaryBasicBlock &StubBB) {
: TgtAddress - DotAddress;
// If it fits in one instruction, do not relax
if (!(PCRelTgtAddress & SingleInstrMask))
- return false;
+ return Error::success();
// Fits short jmp
if (!(PCRelTgtAddress & ShortJmpMask)) {
if (Bits >= RangeShortJmp)
- return false;
+ return Error::success();
LLVM_DEBUG(dbgs() << "Relaxing stub to short jump. PCRelTgtAddress = "
<< Twine::utohexstr(PCRelTgtAddress)
@@ -494,22 +494,23 @@ bool LongJmpPass::relaxStub(BinaryBasicBlock &StubBB) {
<< "\n");
relaxStubToShortJmp(StubBB, RealTargetSym);
StubBits[&StubBB] = RangeShortJmp;
- return true;
+ Modified = true;
+ return Error::success();
}
// The long jmp uses absolute address on AArch64
// So we could not use it for PIC binaries
- if (BC.isAArch64() && !BC.HasFixedLoadAddress) {
- errs() << "BOLT-ERROR: Unable to relax stub for PIC binary\n";
- exit(1);
- }
+ if (BC.isAArch64() && !BC.HasFixedLoadAddress)
+ return createFatalBOLTError(
+ "BOLT-ERROR: Unable to relax stub for PIC binary\n");
LLVM_DEBUG(dbgs() << "Relaxing stub to long jump. PCRelTgtAddress = "
<< Twine::utohexstr(PCRelTgtAddress)
<< " RealTargetSym = " << RealTargetSym->getName() << "\n");
relaxStubToLongJmp(StubBB, RealTargetSym);
StubBits[&StubBB] = static_cast<int>(BC.AsmInfo->getCodePointerSize() * 8);
- return true;
+ Modified = true;
+ return Error::success();
}
bool LongJmpPass::needsStub(const BinaryBasicBlock &BB, const MCInst &Inst,
@@ -539,9 +540,8 @@ bool LongJmpPass::needsStub(const BinaryBasicBlock &BB, const MCInst &Inst,
return PCOffset < MinVal || PCOffset > MaxVal;
}
-bool LongJmpPass::relax(BinaryFunction &Func) {
+Error LongJmpPass::relax(BinaryFunction &Func, bool &Modified) {
const BinaryContext &BC = Func.getBinaryContext();
- bool Modified = false;
assert(BC.isAArch64() && "Unsupported arch");
constexpr int InsnSize = 4; // AArch64
@@ -613,7 +613,8 @@ bool LongJmpPass::relax(BinaryFunction &Func) {
if (!Stubs[&Func].count(&BB) || !BB.isValid())
continue;
- Modified |= relaxStub(BB);
+ if (auto E = relaxStub(BB, Modified))
+ return Error(std::move(E));
}
for (std::pair<BinaryBasicBlock *, std::unique_ptr<BinaryBasicBlock>> &Elmt :
@@ -625,10 +626,10 @@ bool LongJmpPass::relax(BinaryFunction &Func) {
Func.insertBasicBlocks(Elmt.first, std::move(NewBBs), true);
}
- return Modified;
+ return Error::success();
}
-void LongJmpPass::runOnFunctions(BinaryContext &BC) {
+Error LongJmpPass::runOnFunctions(BinaryContext &BC) {
outs() << "BOLT-INFO: Starting stub-insertion pass\n";
std::vector<BinaryFunction *> Sorted = BC.getSortedFunctions();
bool Modified;
@@ -639,19 +640,19 @@ void LongJmpPass::runOnFunctions(BinaryContext &BC) {
tentativeLayout(BC, Sorted);
updateStubGroups();
for (BinaryFunction *Func : Sorted) {
- if (relax(*Func)) {
- // Don't ruin non-simple functions, they can't afford to have the layout
- // changed.
- if (Func->isSimple())
- Func->fixBranches();
- Modified = true;
- }
+ if (auto E = relax(*Func, Modified))
+ return Error(std::move(E));
+ // Don't ruin non-simple functions, they can't afford to have the layout
+ // changed.
+ if (Modified && Func->isSimple())
+ Func->fixBranches();
}
} while (Modified);
outs() << "BOLT-INFO: Inserted " << NumHotStubs
<< " stubs in the hot area and " << NumColdStubs
<< " stubs in the cold area. Shared " << NumSharedStubs
<< " times, iterated " << Iterations << " times.\n";
+ return Error::success();
}
} // namespace bolt
} // namespace llvm
diff --git a/bolt/lib/Passes/LoopInversionPass.cpp b/bolt/lib/Passes/LoopInversionPass.cpp
index f30e1a8f7450ff..10df715993f893 100644
--- a/bolt/lib/Passes/LoopInversionPass.cpp
+++ b/bolt/lib/Passes/LoopInversionPass.cpp
@@ -84,11 +84,11 @@ bool LoopInversionPass::runOnFunction(BinaryFunction &BF) {
return IsChanged;
}
-void LoopInversionPass::runOnFunctions(BinaryContext &BC) {
+Error LoopInversionPass::runOnFunctions(BinaryContext &BC) {
std::atomic<uint64_t> ModifiedFuncCount{0};
if (opts::ReorderBlocks == ReorderBasicBlocks::LT_NONE ||
opts::LoopReorder == false)
- return;
+ return Error::success();
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
if (runOnFunction(BF))
@@ -105,6 +105,7 @@ void LoopInversionPass::runOnFunctions(BinaryContext &BC) {
outs() << "BOLT-INFO: " << ModifiedFuncCount
<< " Functions were reordered by LoopInversionPass\n";
+ return Error::success();
}
} // end namespace bolt
diff --git a/bolt/lib/Passes/PLTCall.cpp b/bolt/lib/Passes/PLTCall.cpp
index aec75be84bfa32..c02f2c3ef367a9 100644
--- a/bolt/lib/Passes/PLTCall.cpp
+++ b/bolt/lib/Passes/PLTCall.cpp
@@ -43,9 +43,9 @@ PLT("plt",
namespace llvm {
namespace bolt {
-void PLTCall::runOnFunctions(BinaryContext &BC) {
+Error PLTCall::runOnFunctions(BinaryContext &BC) {
if (opts::PLT == OT_NONE)
- return;
+ return Error::success();
uint64_t NumCallsOptimized = 0;
for (auto &It : BC.getBinaryFunctions()) {
@@ -83,6 +83,7 @@ void PLTCall::runOnFunctions(BinaryContext &BC) {
outs() << "BOLT-INFO: " << NumCallsOptimized
<< " PLT calls in the binary were optimized.\n";
}
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/PatchEntries.cpp b/bolt/lib/Passes/PatchEntries.cpp
index ee7512d89962f6..0b0e15f1b5bd0d 100644
--- a/bolt/lib/Passes/PatchEntries.cpp
+++ b/bolt/lib/Passes/PatchEntries.cpp
@@ -31,7 +31,7 @@ llvm::cl::opt<bool>
namespace llvm {
namespace bolt {
-void PatchEntries::runOnFunctions(BinaryContext &BC) {
+Error PatchEntries::runOnFunctions(BinaryContext &BC) {
if (!opts::ForcePatch) {
// Mark the binary for patching if we did not create external references
// for original code in any of functions we are not going to emit.
@@ -42,7 +42,7 @@ void PatchEntries::runOnFunctions(BinaryContext &BC) {
});
if (!NeedsPatching)
- return;
+ return Error::success();
}
if (opts::Verbosity >= 1)
@@ -103,7 +103,7 @@ void PatchEntries::runOnFunctions(BinaryContext &BC) {
if (opts::ForcePatch) {
errs() << "BOLT-ERROR: unable to patch entries in " << Function
<< "\n";
- exit(1);
+ return createFatalBOLTError("");
}
continue;
@@ -138,6 +138,7 @@ void PatchEntries::runOnFunctions(BinaryContext &BC) {
Function.setIsPatched(true);
}
+ return Error::success();
}
} // end namespace bolt
diff --git a/bolt/lib/Passes/RegReAssign.cpp b/bolt/lib/Passes/RegReAssign.cpp
index 8b9dc9c1fdd506..5f0cddbdf7dcc0 100644
--- a/bolt/lib/Passes/RegReAssign.cpp
+++ b/bolt/lib/Passes/RegReAssign.cpp
@@ -452,7 +452,7 @@ void RegReAssign::setupConservativePass(
});
}
-void RegReAssign::runOnFunctions(BinaryContext &BC) {
+Error RegReAssign::runOnFunctions(BinaryContext &BC) {
RegScore = std::vector<int64_t>(BC.MRI->getNumRegs(), 0);
RankedRegs = std::vector<size_t>(BC.MRI->getNumRegs(), 0);
@@ -481,7 +481,7 @@ void RegReAssign::runOnFunctions(BinaryContext &BC) {
if (FuncsChanged.empty()) {
outs() << "BOLT-INFO: Reg Reassignment Pass: no changes were made.\n";
- return;
+ return Error::success();
}
if (opts::UpdateDebugSections)
outs() << "BOLT-WARNING: You used -reg-reassign and -update-debug-sections."
@@ -492,6 +492,7 @@ void RegReAssign::runOnFunctions(BinaryContext &BC) {
outs() << "\t " << FuncsChanged.size() << " functions affected.\n";
outs() << "\t " << StaticBytesSaved << " static bytes saved.\n";
outs() << "\t " << DynBytesSaved << " dynamic bytes saved.\n";
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/ReorderData.cpp b/bolt/lib/Passes/ReorderData.cpp
index 3a6654cf1e0b56..13e3e8001ba522 100644
--- a/bolt/lib/Passes/ReorderData.cpp
+++ b/bolt/lib/Passes/ReorderData.cpp
@@ -435,17 +435,17 @@ bool ReorderData::markUnmoveableSymbols(BinaryContext &BC,
return FoundUnmoveable;
}
-void ReorderData::runOnFunctions(BinaryContext &BC) {
+Error ReorderData::runOnFunctions(BinaryContext &BC) {
static const char *DefaultSections[] = {".rodata", ".data", ".bss", nullptr};
if (!BC.HasRelocations || opts::ReorderData.empty())
- return;
+ return Error::success();
// For now
if (opts::JumpTables > JTS_BASIC) {
outs() << "BOLT-WARNING: jump table support must be basic for "
<< "data reordering to work.\n";
- return;
+ return Error::success();
}
assignMemData(BC);
@@ -523,6 +523,7 @@ void ReorderData::runOnFunctions(BinaryContext &BC) {
setSectionOrder(BC, *Section, Order.begin(), Order.end());
}
}
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/ReorderFunctions.cpp b/bolt/lib/Passes/ReorderFunctions.cpp
index 2446524c1ab416..77e51c34746e38 100644
--- a/bolt/lib/Passes/ReorderFunctions.cpp
+++ b/bolt/lib/Passes/ReorderFunctions.cpp
@@ -250,21 +250,21 @@ void ReorderFunctions::printStats(const std::vector<Cluster> &Clusters,
TotalCalls2MB, 100 * TotalCalls2MB / TotalCalls);
}
-std::vector<std::string> ReorderFunctions::readFunctionOrderFile() {
- std::vector<std::string> FunctionNames;
+Error ReorderFunctions::readFunctionOrderFile(
+ std::vector<std::string> &FunctionNames) {
std::ifstream FuncsFile(opts::FunctionOrderFile, std::ios::in);
- if (!FuncsFile) {
- errs() << "Ordered functions file \"" << opts::FunctionOrderFile
- << "\" can't be opened.\n";
- exit(1);
- }
+ if (!FuncsFile)
+ return createFatalBOLTError(Twine("Ordered functions file \"") +
+ Twine(opts::FunctionOrderFile) +
+ Twine("\" can't be opened."));
+
std::string FuncName;
while (std::getline(FuncsFile, FuncName))
FunctionNames.push_back(FuncName);
- return FunctionNames;
+ return Error::success();
}
-void ReorderFunctions::runOnFunctions(BinaryContext &BC) {
+Error ReorderFunctions::runOnFunctions(BinaryContext &BC) {
auto &BFs = BC.getBinaryFunctions();
if (opts::ReorderFunctions != RT_NONE &&
opts::ReorderFunctions != RT_EXEC_COUNT &&
@@ -373,7 +373,11 @@ void ReorderFunctions::runOnFunctions(BinaryContext &BC) {
uint32_t Index = 0;
uint32_t InvalidEntries = 0;
- for (const std::string &Function : readFunctionOrderFile()) {
+ std::vector<std::string> FunctionNames;
+ if (Error E = readFunctionOrderFile(FunctionNames))
+ return Error(std::move(E));
+
+ for (const std::string &Function : FunctionNames) {
std::vector<uint64_t> FuncAddrs;
BinaryData *BD = BC.getBinaryDataByName(Function);
@@ -444,7 +448,7 @@ void ReorderFunctions::runOnFunctions(BinaryContext &BC) {
if (!FuncsFile) {
errs() << "BOLT-ERROR: ordered functions file "
<< opts::GenerateFunctionOrderFile << " cannot be opened\n";
- exit(1);
+ return createFatalBOLTError("");
}
}
@@ -455,7 +459,7 @@ void ReorderFunctions::runOnFunctions(BinaryContext &BC) {
if (!LinkSectionsFile) {
errs() << "BOLT-ERROR: link sections file " << opts::LinkSectionsFile
<< " cannot be opened\n";
- exit(1);
+ return createFatalBOLTError("");
}
}
@@ -515,6 +519,7 @@ void ReorderFunctions::runOnFunctions(BinaryContext &BC) {
<< opts::LinkSectionsFile << '\n';
}
}
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/RetpolineInsertion.cpp b/bolt/lib/Passes/RetpolineInsertion.cpp
index 97eedb882f5506..09ea3a853fbc74 100644
--- a/bolt/lib/Passes/RetpolineInsertion.cpp
+++ b/bolt/lib/Passes/RetpolineInsertion.cpp
@@ -271,9 +271,9 @@ IndirectBranchInfo::IndirectBranchInfo(MCInst &Inst, MCPlusBuilder &MIB) {
}
}
-void RetpolineInsertion::runOnFunctions(BinaryContext &BC) {
+Error RetpolineInsertion::runOnFunctions(BinaryContext &BC) {
if (!opts::InsertRetpolines)
- return;
+ return Error::success();
assert(BC.isX86() &&
"retpoline insertion not supported for target architecture");
@@ -331,6 +331,7 @@ void RetpolineInsertion::runOnFunctions(BinaryContext &BC) {
<< CreatedRetpolines.size()
<< "\nBOLT-INFO: The number of retpolined branches is : "
<< RetpolinedBranches << "\n";
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/ShrinkWrapping.cpp b/bolt/lib/Passes/ShrinkWrapping.cpp
index d7b25c1279dc8b..2f2405b9463a7c 100644
--- a/bolt/lib/Passes/ShrinkWrapping.cpp
+++ b/bolt/lib/Passes/ShrinkWrapping.cpp
@@ -1646,9 +1646,9 @@ void ShrinkWrapping::rebuildCFIForSP() {
++I;
}
-MCInst ShrinkWrapping::createStackAccess(int SPVal, int FPVal,
- const FrameIndexEntry &FIE,
- bool CreatePushOrPop) {
+Expected<MCInst> ShrinkWrapping::createStackAccess(int SPVal, int FPVal,
+ const FrameIndexEntry &FIE,
+ bool CreatePushOrPop) {
MCInst NewInst;
if (SPVal != StackPointerTracking::SUPERPOSITION &&
SPVal != StackPointerTracking::EMPTY) {
@@ -1656,15 +1656,15 @@ MCInst ShrinkWrapping::createStackAccess(int SPVal, int FPVal,
if (!BC.MIB->createRestoreFromStack(NewInst, BC.MIB->getStackPointer(),
FIE.StackOffset - SPVal, FIE.RegOrImm,
FIE.Size)) {
- errs() << "createRestoreFromStack: not supported on this platform\n";
- abort();
+ return createFatalBOLTError(
+ "createRestoreFromStack: not supported on this platform\n");
}
} else {
if (!BC.MIB->createSaveToStack(NewInst, BC.MIB->getStackPointer(),
FIE.StackOffset - SPVal, FIE.RegOrImm,
FIE.Size)) {
- errs() << "createSaveToStack: not supported on this platform\n";
- abort();
+ return createFatalBOLTError(
+ "createSaveToStack: not supported on this platform\n");
}
}
if (CreatePushOrPop)
@@ -1678,15 +1678,15 @@ MCInst ShrinkWrapping::createStackAccess(int SPVal, int FPVal,
if (!BC.MIB->createRestoreFromStack(NewInst, BC.MIB->getFramePointer(),
FIE.StackOffset - FPVal, FIE.RegOrImm,
FIE.Size)) {
- errs() << "createRestoreFromStack: not supported on this platform\n";
- abort();
+ return createFatalBOLTError(
+ "createRestoreFromStack: not supported on this platform\n");
}
} else {
if (!BC.MIB->createSaveToStack(NewInst, BC.MIB->getFramePointer(),
FIE.StackOffset - FPVal, FIE.RegOrImm,
FIE.Size)) {
- errs() << "createSaveToStack: not supported on this platform\n";
- abort();
+ return createFatalBOLTError(
+ "createSaveToStack: not supported on this platform\n");
}
}
return NewInst;
@@ -1743,10 +1743,11 @@ BBIterTy ShrinkWrapping::insertCFIsForPushOrPop(BinaryBasicBlock &BB,
return Pos;
}
-BBIterTy ShrinkWrapping::processInsertion(BBIterTy InsertionPoint,
- BinaryBasicBlock *CurBB,
- const WorklistItem &Item,
- int64_t SPVal, int64_t FPVal) {
+Expected<BBIterTy> ShrinkWrapping::processInsertion(BBIterTy InsertionPoint,
+ BinaryBasicBlock *CurBB,
+ const WorklistItem &Item,
+ int64_t SPVal,
+ int64_t FPVal) {
// Trigger CFI reconstruction for this CSR if necessary - writing to
// PushOffsetByReg/PopOffsetByReg *will* trigger CFI update
if ((Item.FIEToInsert.IsStore &&
@@ -1772,9 +1773,12 @@ BBIterTy ShrinkWrapping::processInsertion(BBIterTy InsertionPoint,
<< " Is push = " << (Item.Action == WorklistItem::InsertPushOrPop)
<< "\n";
});
- MCInst NewInst =
+ Expected<MCInst> NewInstOrErr =
createStackAccess(SPVal, FPVal, Item.FIEToInsert,
Item.Action == WorklistItem::InsertPushOrPop);
+ if (auto E = NewInstOrErr.takeError())
+ return Error(std::move(E));
+ MCInst &NewInst = *NewInstOrErr;
if (InsertionPoint != CurBB->end()) {
LLVM_DEBUG({
dbgs() << "Adding before Inst: ";
@@ -1791,7 +1795,7 @@ BBIterTy ShrinkWrapping::processInsertion(BBIterTy InsertionPoint,
return CurBB->end();
}
-BBIterTy ShrinkWrapping::processInsertionsList(
+Expected<BBIterTy> ShrinkWrapping::processInsertionsList(
BBIterTy InsertionPoint, BinaryBasicBlock *CurBB,
std::vector<WorklistItem> &TodoList, int64_t SPVal, int64_t FPVal) {
bool HasInsertions = llvm::any_of(TodoList, [&](WorklistItem &Item) {
@@ -1840,8 +1844,11 @@ BBIterTy ShrinkWrapping::processInsertionsList(
Item.Action == WorklistItem::ChangeToAdjustment)
continue;
- InsertionPoint =
+ auto InsertionPointOrErr =
processInsertion(InsertionPoint, CurBB, Item, SPVal, FPVal);
+ if (auto E = InsertionPointOrErr.takeError())
+ return Error(std::move(E));
+ InsertionPoint = *InsertionPointOrErr;
if (Item.Action == WorklistItem::InsertPushOrPop &&
Item.FIEToInsert.IsStore)
SPVal -= Item.FIEToInsert.Size;
@@ -1852,7 +1859,7 @@ BBIterTy ShrinkWrapping::processInsertionsList(
return InsertionPoint;
}
-bool ShrinkWrapping::processInsertions() {
+Expected<bool> ShrinkWrapping::processInsertions() {
PredictiveStackPointerTracking PSPT(BF, Todo, Info, AllocatorId);
PSPT.run();
@@ -1875,14 +1882,20 @@ bool ShrinkWrapping::processInsertions() {
auto Iter = I;
std::pair<int, int> SPTState =
*PSPT.getStateAt(Iter == BB.begin() ? (ProgramPoint)&BB : &*(--Iter));
- I = processInsertionsList(I, &BB, List, SPTState.first, SPTState.second);
+ auto IterOrErr =
+ processInsertionsList(I, &BB, List, SPTState.first, SPTState.second);
+ if (auto E = IterOrErr.takeError())
+ return Error(std::move(E));
+ I = *IterOrErr;
}
// Process insertions at the end of bb
auto WRI = Todo.find(&BB);
if (WRI != Todo.end()) {
std::pair<int, int> SPTState = *PSPT.getStateAt(*BB.rbegin());
- processInsertionsList(BB.end(), &BB, WRI->second, SPTState.first,
- SPTState.second);
+ if (auto E = processInsertionsList(BB.end(), &BB, WRI->second,
+ SPTState.first, SPTState.second)
+ .takeError())
+ return Error(std::move(E));
Changes = true;
}
}
@@ -1945,7 +1958,7 @@ void ShrinkWrapping::rebuildCFI() {
}
}
-bool ShrinkWrapping::perform(bool HotOnly) {
+Expected<bool> ShrinkWrapping::perform(bool HotOnly) {
HasDeletedOffsetCFIs = BitVector(BC.MRI->getNumRegs(), false);
PushOffsetByReg = std::vector<int64_t>(BC.MRI->getNumRegs(), 0LL);
PopOffsetByReg = std::vector<int64_t>(BC.MRI->getNumRegs(), 0LL);
@@ -1998,7 +2011,11 @@ bool ShrinkWrapping::perform(bool HotOnly) {
});
SLM.performChanges();
// Early exit if processInsertions doesn't detect any todo items
- if (!processInsertions())
+ auto ModifiedOrErr = processInsertions();
+ if (auto E = ModifiedOrErr.takeError())
+ return Error(std::move(E));
+ const bool Modified = *ModifiedOrErr;
+ if (!Modified)
return false;
processDeletions();
if (foldIdenticalSplitEdges()) {
diff --git a/bolt/lib/Passes/SplitFunctions.cpp b/bolt/lib/Passes/SplitFunctions.cpp
index 5de07597300483..26dd4b66eb9a16 100644
--- a/bolt/lib/Passes/SplitFunctions.cpp
+++ b/bolt/lib/Passes/SplitFunctions.cpp
@@ -712,15 +712,15 @@ bool SplitFunctions::shouldOptimize(const BinaryFunction &BF) const {
return BinaryFunctionPass::shouldOptimize(BF);
}
-void SplitFunctions::runOnFunctions(BinaryContext &BC) {
+Error SplitFunctions::runOnFunctions(BinaryContext &BC) {
if (!opts::SplitFunctions)
- return;
+ return Error::success();
// If split strategy is not CDSplit, then a second run of the pass is not
// needed after function reordering.
if (BC.HasFinalizedFunctionOrder &&
opts::SplitStrategy != SplitFunctionsStrategy::CDSplit)
- return;
+ return Error::success();
std::unique_ptr<SplitStrategy> Strategy;
bool ForceSequential = false;
@@ -770,6 +770,7 @@ void SplitFunctions::runOnFunctions(BinaryContext &BC) {
<< " hot bytes from " << SplitBytesCold << " cold bytes "
<< format("(%.2lf%% of split functions is hot).\n",
100.0 * SplitBytesHot / (SplitBytesHot + SplitBytesCold));
+ return Error::success();
}
void SplitFunctions::splitFunction(BinaryFunction &BF, SplitStrategy &S) {
diff --git a/bolt/lib/Passes/StokeInfo.cpp b/bolt/lib/Passes/StokeInfo.cpp
index 419ba236e1342b..df73293c824ea8 100644
--- a/bolt/lib/Passes/StokeInfo.cpp
+++ b/bolt/lib/Passes/StokeInfo.cpp
@@ -144,7 +144,7 @@ bool StokeInfo::checkFunction(BinaryFunction &BF, DataflowInfoManager &DInfo,
return true;
}
-void StokeInfo::runOnFunctions(BinaryContext &BC) {
+Error StokeInfo::runOnFunctions(BinaryContext &BC) {
outs() << "STOKE-INFO: begin of stoke pass\n";
std::ofstream Outfile;
@@ -152,7 +152,7 @@ void StokeInfo::runOnFunctions(BinaryContext &BC) {
Outfile.open(opts::StokeOutputDataFilename);
} else {
errs() << "STOKE-INFO: output file is required\n";
- return;
+ return Error::success();
}
// check some context meta data
@@ -186,6 +186,7 @@ void StokeInfo::runOnFunctions(BinaryContext &BC) {
}
outs() << "STOKE-INFO: end of stoke pass\n";
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/TailDuplication.cpp b/bolt/lib/Passes/TailDuplication.cpp
index e63d4be1392f4d..4f3082e28e4e03 100644
--- a/bolt/lib/Passes/TailDuplication.cpp
+++ b/bolt/lib/Passes/TailDuplication.cpp
@@ -633,9 +633,9 @@ void TailDuplication::runOnFunction(BinaryFunction &Function) {
ModifiedFunctions++;
}
-void TailDuplication::runOnFunctions(BinaryContext &BC) {
+Error TailDuplication::runOnFunctions(BinaryContext &BC) {
if (opts::TailDuplicationMode == TailDuplication::TD_NONE)
- return;
+ return Error::success();
for (auto &It : BC.getBinaryFunctions()) {
BinaryFunction &Function = It.second;
@@ -661,6 +661,7 @@ void TailDuplication::runOnFunctions(BinaryContext &BC) {
DynamicInstructionDeletionCount)
<< "\n";
}
+ return Error::success();
}
} // end namespace bolt
diff --git a/bolt/lib/Passes/ThreeWayBranch.cpp b/bolt/lib/Passes/ThreeWayBranch.cpp
index dc320d53fb6882..a30a2a016e59d7 100644
--- a/bolt/lib/Passes/ThreeWayBranch.cpp
+++ b/bolt/lib/Passes/ThreeWayBranch.cpp
@@ -147,7 +147,7 @@ void ThreeWayBranch::runOnFunction(BinaryFunction &Function) {
}
}
-void ThreeWayBranch::runOnFunctions(BinaryContext &BC) {
+Error ThreeWayBranch::runOnFunctions(BinaryContext &BC) {
for (auto &It : BC.getBinaryFunctions()) {
BinaryFunction &Function = It.second;
if (!shouldRunOnFunction(Function))
@@ -157,6 +157,7 @@ void ThreeWayBranch::runOnFunctions(BinaryContext &BC) {
outs() << "BOLT-INFO: number of three way branches order changed: "
<< BranchesAltered << "\n";
+ return Error::success();
}
} // end namespace bolt
diff --git a/bolt/lib/Passes/ValidateInternalCalls.cpp b/bolt/lib/Passes/ValidateInternalCalls.cpp
index 516f91acb50844..ce0b13bbff045a 100644
--- a/bolt/lib/Passes/ValidateInternalCalls.cpp
+++ b/bolt/lib/Passes/ValidateInternalCalls.cpp
@@ -302,9 +302,9 @@ bool ValidateInternalCalls::analyzeFunction(BinaryFunction &Function) const {
return true;
}
-void ValidateInternalCalls::runOnFunctions(BinaryContext &BC) {
+Error ValidateInternalCalls::runOnFunctions(BinaryContext &BC) {
if (!BC.isX86())
- return;
+ return Error::success();
// Look for functions that need validation. This should be pretty rare.
std::set<BinaryFunction *> NeedsValidation;
@@ -323,7 +323,7 @@ void ValidateInternalCalls::runOnFunctions(BinaryContext &BC) {
// Skip validation for non-relocation mode
if (!BC.HasRelocations)
- return;
+ return Error::success();
// Since few functions need validation, we can work with our most expensive
// algorithms here. Fix the CFG treating internal calls as unconditional
@@ -346,6 +346,7 @@ void ValidateInternalCalls::runOnFunctions(BinaryContext &BC) {
Function->setIgnored();
}
}
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Passes/ValidateMemRefs.cpp b/bolt/lib/Passes/ValidateMemRefs.cpp
index 3324776830d177..598a4c26c745d6 100644
--- a/bolt/lib/Passes/ValidateMemRefs.cpp
+++ b/bolt/lib/Passes/ValidateMemRefs.cpp
@@ -72,13 +72,13 @@ void ValidateMemRefs::runOnFunction(BinaryFunction &BF) {
}
}
-void ValidateMemRefs::runOnFunctions(BinaryContext &BC) {
+Error ValidateMemRefs::runOnFunctions(BinaryContext &BC) {
if (!BC.isX86())
- return;
+ return Error::success();
// Skip validation if not moving JT
if (opts::JumpTables == JTS_NONE || opts::JumpTables == JTS_BASIC)
- return;
+ return Error::success();
ParallelUtilities::WorkFuncWithAllocTy ProcessFunction =
[&](BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId) {
@@ -94,10 +94,11 @@ void ValidateMemRefs::runOnFunctions(BinaryContext &BC) {
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: memrefs validation is concluded\n");
if (!ReplacedReferences)
- return;
+ return Error::success();
outs() << "BOLT-INFO: validate-mem-refs updated " << ReplacedReferences
<< " object references\n";
+ return Error::success();
}
} // namespace llvm::bolt
diff --git a/bolt/lib/Passes/VeneerElimination.cpp b/bolt/lib/Passes/VeneerElimination.cpp
index 929c7360b7ffaf..d844a068184dd4 100644
--- a/bolt/lib/Passes/VeneerElimination.cpp
+++ b/bolt/lib/Passes/VeneerElimination.cpp
@@ -29,9 +29,9 @@ static llvm::cl::opt<bool>
namespace llvm {
namespace bolt {
-void VeneerElimination::runOnFunctions(BinaryContext &BC) {
+Error VeneerElimination::runOnFunctions(BinaryContext &BC) {
if (!opts::EliminateVeneers || !BC.isAArch64())
- return;
+ return Error::success();
std::map<uint64_t, BinaryFunction> &BFs = BC.getBinaryFunctions();
std::unordered_map<const MCSymbol *, const MCSymbol *> VeneerDestinations;
@@ -79,8 +79,8 @@ void VeneerElimination::runOnFunctions(BinaryContext &BC) {
VeneerCallers++;
if (!BC.MIB->replaceBranchTarget(
Instr, VeneerDestinations[TargetSymbol], BC.Ctx.get())) {
- errs() << "BOLT-ERROR: updating veneer call destination failed\n";
- exit(1);
+ return createFatalBOLTError(
+ "BOLT-ERROR: updating veneer call destination failed\n");
}
}
}
@@ -90,6 +90,7 @@ void VeneerElimination::runOnFunctions(BinaryContext &BC) {
dbgs() << "BOLT-INFO: number of linker-inserted veneers call sites: "
<< VeneerCallers << "\n");
(void)VeneerCallers;
+ return Error::success();
}
} // namespace bolt
diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp
index 9946608c96d8ee..cad80189c23b80 100644
--- a/bolt/lib/Rewrite/BinaryPassManager.cpp
+++ b/bolt/lib/Rewrite/BinaryPassManager.cpp
@@ -268,7 +268,7 @@ const char BinaryFunctionPassManager::TimerGroupName[] = "passman";
const char BinaryFunctionPassManager::TimerGroupDesc[] =
"Binary Function Pass Manager";
-void BinaryFunctionPassManager::runPasses() {
+Error BinaryFunctionPassManager::runPasses() {
auto &BFs = BC.getBinaryFunctions();
for (size_t PassIdx = 0; PassIdx < Passes.size(); PassIdx++) {
const std::pair<const bool, std::unique_ptr<BinaryFunctionPass>>
@@ -286,8 +286,14 @@ void BinaryFunctionPassManager::runPasses() {
NamedRegionTimer T(Pass->getName(), Pass->getName(), TimerGroupName,
TimerGroupDesc, TimeOpts);
- callWithDynoStats([this, &Pass] { Pass->runOnFunctions(BC); }, BFs,
- Pass->getName(), opts::DynoStatsAll, BC.isAArch64());
+ Error E = Error::success();
+ callWithDynoStats(
+ [this, &E, &Pass] {
+ E = joinErrors(std::move(E), Pass->runOnFunctions(BC));
+ },
+ BFs, Pass->getName(), opts::DynoStatsAll, BC.isAArch64());
+ if (E)
+ return Error(std::move(E));
if (opts::VerifyCFG &&
!std::accumulate(
@@ -296,9 +302,9 @@ void BinaryFunctionPassManager::runPasses() {
const std::pair<const uint64_t, BinaryFunction> &It) {
return Valid && It.second.validateCFG();
})) {
- errs() << "BOLT-ERROR: Invalid CFG detected after pass "
- << Pass->getName() << "\n";
- exit(1);
+ return createFatalBOLTError(
+ Twine("BOLT-ERROR: Invalid CFG detected after pass ") +
+ Twine(Pass->getName()) + Twine("\n"));
}
if (opts::Verbosity > 0)
@@ -321,9 +327,10 @@ void BinaryFunctionPassManager::runPasses() {
Function.dumpGraphForPass(PassIdName);
}
}
+ return Error::success();
}
-void BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
+Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
BinaryFunctionPassManager Manager(BC);
const DynoStats InitialDynoStats =
@@ -516,7 +523,7 @@ void BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
// in parallel and restore them
Manager.registerPass(std::make_unique<CleanMCState>(NeverPrint));
- Manager.runPasses();
+ return Manager.runPasses();
}
} // namespace bolt
diff --git a/bolt/lib/Rewrite/BoltDiff.cpp b/bolt/lib/Rewrite/BoltDiff.cpp
index 16a90510962e8e..0de5a3d0b402d2 100644
--- a/bolt/lib/Rewrite/BoltDiff.cpp
+++ b/bolt/lib/Rewrite/BoltDiff.cpp
@@ -294,9 +294,9 @@ class RewriteInstanceDiff {
}
PrintProgramStats PPS(opts::NeverPrint);
outs() << "* BOLT-DIFF: Starting print program stats pass for binary 1\n";
- PPS.runOnFunctions(*RI1.BC);
+ cantFail(PPS.runOnFunctions(*RI1.BC));
outs() << "* BOLT-DIFF: Starting print program stats pass for binary 2\n";
- PPS.runOnFunctions(*RI2.BC);
+ cantFail(PPS.runOnFunctions(*RI2.BC));
outs() << "=====\n";
outs() << "Inputs share " << BothHaveProfile
<< " functions with valid profile.\n";
@@ -700,9 +700,9 @@ void RewriteInstance::compare(RewriteInstance &RI2) {
if (opts::ICF) {
IdenticalCodeFolding ICF(opts::NeverPrint);
outs() << "BOLT-DIFF: Starting ICF pass for binary 1";
- ICF.runOnFunctions(*BC);
+ cantFail(ICF.runOnFunctions(*BC));
outs() << "BOLT-DIFF: Starting ICF pass for binary 2";
- ICF.runOnFunctions(*RI2.BC);
+ cantFail(ICF.runOnFunctions(*RI2.BC));
}
RewriteInstanceDiff RID(*this, RI2);
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index c909e31e93c959..cc994c213482d4 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -3133,7 +3133,13 @@ void RewriteInstance::disassembleFunctions() {
continue;
}
- if (!Function.disassemble()) {
+ bool DisasmFailed{false};
+ handleAllErrors(Function.disassemble(), [&](const BOLTError &E) {
+ DisasmFailed = true;
+ if (E.isFatal()) {
+ E.log(errs());
+ exit(1);
+ }
if (opts::processAllFunctions())
BC->exitWithBugReport("function cannot be properly disassembled. "
"Unable to continue in relocation mode.",
@@ -3143,8 +3149,10 @@ void RewriteInstance::disassembleFunctions() {
<< ". Will ignore.\n";
// Forcefully ignore the function.
Function.setIgnored();
+ });
+
+ if (DisasmFailed)
continue;
- }
if (opts::PrintAll || opts::PrintDisasm)
Function.print(outs(), "after disassembly");
@@ -3214,7 +3222,16 @@ void RewriteInstance::buildFunctionsCFG() {
ParallelUtilities::WorkFuncWithAllocTy WorkFun =
[&](BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId) {
- if (!BF.buildCFG(AllocId))
+ bool HadErrors{false};
+ handleAllErrors(BF.buildCFG(AllocId), [&](const BOLTError &E) {
+ if (!E.getMessage().empty())
+ E.log(errs());
+ if (E.isFatal())
+ exit(1);
+ HadErrors = true;
+ });
+
+ if (HadErrors)
return;
if (opts::PrintAll) {
diff --git a/bolt/lib/Target/X86/X86MCSymbolizer.cpp b/bolt/lib/Target/X86/X86MCSymbolizer.cpp
index ca7fe137152fd3..dead6856d2f699 100644
--- a/bolt/lib/Target/X86/X86MCSymbolizer.cpp
+++ b/bolt/lib/Target/X86/X86MCSymbolizer.cpp
@@ -134,7 +134,12 @@ bool X86MCSymbolizer::tryAddingSymbolicOperand(
// a PC-relative 8-byte fixup, which is what we need to cover this. The
// only way to do this is to use the symbol name _GLOBAL_OFFSET_TABLE_.
if (Relocation::isX86GOTPC64(Relocation->Type)) {
- auto [Sym, Addend] = handleGOTPC64(*Relocation, InstAddress);
+ auto PairOrErr = handleGOTPC64(*Relocation, InstAddress);
+ if (auto E = PairOrErr.takeError()) {
+ Function.setSimple(false);
+ return false;
+ }
+ auto [Sym, Addend] = *PairOrErr;
addOperand(Sym, Addend);
return true;
}
@@ -158,14 +163,16 @@ bool X86MCSymbolizer::tryAddingSymbolicOperand(
return true;
}
-std::pair<MCSymbol *, uint64_t>
+Expected<std::pair<MCSymbol *, uint64_t>>
X86MCSymbolizer::handleGOTPC64(const Relocation &R, uint64_t InstrAddr) {
BinaryContext &BC = Function.getBinaryContext();
const BinaryData *GOTSymBD = BC.getGOTSymbol();
if (!GOTSymBD || !GOTSymBD->getAddress()) {
- errs() << "BOLT-ERROR: R_X86_GOTPC64 relocation is present but we did "
- "not detect a valid _GLOBAL_OFFSET_TABLE_ in symbol table\n";
- exit(1);
+ // This error is pretty serious but we can't kill the disassembler
+ // because of it, so don't make it fatal. Log it and warn the user.
+ return createNonFatalBOLTError(
+ "R_X86_GOTPC64 relocation is present but we did not detect "
+ "a valid _GLOBAL_OFFSET_TABLE_ in symbol table\n");
}
// R_X86_GOTPC64 are not relative to the Reloc nor end of instruction,
// but the start of the MOVABSQ instruction. So the Target Address is
diff --git a/bolt/lib/Target/X86/X86MCSymbolizer.h b/bolt/lib/Target/X86/X86MCSymbolizer.h
index 9ed18b69c74ce4..189941e949e33a 100644
--- a/bolt/lib/Target/X86/X86MCSymbolizer.h
+++ b/bolt/lib/Target/X86/X86MCSymbolizer.h
@@ -20,8 +20,8 @@ class X86MCSymbolizer : public MCSymbolizer {
BinaryFunction &Function;
bool CreateNewSymbols{true};
- std::pair<MCSymbol *, uint64_t> handleGOTPC64(const Relocation &R,
- uint64_t InstrAddr);
+ Expected<std::pair<MCSymbol *, uint64_t>> handleGOTPC64(const Relocation &R,
+ uint64_t InstrAddr);
public:
X86MCSymbolizer(BinaryFunction &Function, bool CreateNewSymbols = true)
>From 4546a274e0ed5a5a239bf6373696cc3f499cda15 Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Mon, 12 Feb 2024 12:42:29 -0800
Subject: [PATCH 2/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
=?UTF-8?q?anges=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
[skip ci]
---
bolt/lib/Rewrite/MachORewriteInstance.cpp | 4 ++--
bolt/lib/Rewrite/RewriteInstance.cpp | 11 ++++++-----
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/bolt/lib/Rewrite/MachORewriteInstance.cpp b/bolt/lib/Rewrite/MachORewriteInstance.cpp
index 8be8257f15c1ce..c2a6c1f88ab070 100644
--- a/bolt/lib/Rewrite/MachORewriteInstance.cpp
+++ b/bolt/lib/Rewrite/MachORewriteInstance.cpp
@@ -337,7 +337,7 @@ void MachORewriteInstance::disassembleFunctions() {
BinaryFunction &Function = BFI.second;
if (!Function.isSimple())
continue;
- Function.disassemble();
+ cantFail(Function.disassemble());
if (opts::PrintDisasm)
Function.print(outs(), "after disassembly");
}
@@ -387,7 +387,7 @@ void MachORewriteInstance::runOptimizationPasses() {
Manager.registerPass(
std::make_unique<FinalizeFunctions>(opts::PrintFinalized));
- Manager.runPasses();
+ cantFail(Manager.runPasses());
}
void MachORewriteInstance::mapInstrumentationSection(
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index cc994c213482d4..06aed246de0cf2 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -1283,7 +1283,7 @@ void RewriteInstance::discoverFileObjects() {
/*UseMaxSize*/ true);
if (BF) {
assert(Rel.isRelative() && "Expected relative relocation for island");
- BF->markIslandDynamicRelocationAtAddress(RelAddress);
+ cantFail(BF->markIslandDynamicRelocationAtAddress(RelAddress));
}
}
}
@@ -2859,8 +2859,9 @@ void RewriteInstance::selectFunctionsToProcess() {
StringSet<> ReorderFunctionsUserSet;
StringSet<> ReorderFunctionsLTOCommonSet;
if (opts::ReorderFunctions == ReorderFunctions::RT_USER) {
- for (const std::string &Function :
- ReorderFunctions::readFunctionOrderFile()) {
+ std::vector<std::string> FunctionNames;
+ cantFail(ReorderFunctions::readFunctionOrderFile(FunctionNames));
+ for (const std::string &Function : FunctionNames) {
ReorderFunctionsUserSet.insert(Function);
if (std::optional<StringRef> LTOCommonName = getLTOCommonName(Function))
ReorderFunctionsLTOCommonSet.insert(*LTOCommonName);
@@ -3207,7 +3208,7 @@ void RewriteInstance::disassembleFunctions() {
check_error(LSDASection.getError(), "failed to get LSDA section");
ArrayRef<uint8_t> LSDAData = ArrayRef<uint8_t>(
LSDASection->getData(), LSDASection->getContents().size());
- Function.parseLSDA(LSDAData, LSDASection->getAddress());
+ cantFail(Function.parseLSDA(LSDAData, LSDASection->getAddress()));
}
}
}
@@ -3298,7 +3299,7 @@ void RewriteInstance::postProcessFunctions() {
void RewriteInstance::runOptimizationPasses() {
NamedRegionTimer T("runOptimizationPasses", "run optimization passes",
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
- BinaryFunctionPassManager::runAllPasses(*BC);
+ cantFail(BinaryFunctionPassManager::runAllPasses(*BC));
}
void RewriteInstance::preregisterSections() {
>From 255aba0be94213692cc142b46b6e4b97ce4ccfd1 Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Mon, 12 Feb 2024 13:52:51 -0800
Subject: [PATCH 3/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
=?UTF-8?q?anges=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
[skip ci]
---
bolt/lib/Rewrite/RewriteInstance.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 06aed246de0cf2..829568cefff01f 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -3299,7 +3299,11 @@ void RewriteInstance::postProcessFunctions() {
void RewriteInstance::runOptimizationPasses() {
NamedRegionTimer T("runOptimizationPasses", "run optimization passes",
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
- cantFail(BinaryFunctionPassManager::runAllPasses(*BC));
+ handleAllErrors(BinaryFunctionPassManager::runAllPasses(*BC),
+ [](const BOLTError &E) {
+ E.log(errs());
+ exit(1);
+ });
}
void RewriteInstance::preregisterSections() {
More information about the llvm-commits
mailing list