mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 01:58:44 +08:00
[BOLT] Limited "support" for AVX-512
Summary: In relocation mode trap on entry to any function that has AVX-512 instructions. This is controlled by "-trap-avx512" option which is on by default. If the option is disabled and AVX-512 instruction is seen in relocation mode, then we abort while re-writing the binary. (cherry picked from FBD6893165)
This commit is contained in:
@@ -154,6 +154,9 @@ public:
|
||||
/// True if the binary requires immediate relocation processing.
|
||||
bool RequiresZNow{false};
|
||||
|
||||
/// List of functions that always trap.
|
||||
std::vector<const BinaryFunction *> TrappedFunctions;
|
||||
|
||||
BinaryContext(std::unique_ptr<MCContext> Ctx,
|
||||
std::unique_ptr<DWARFContext> DwCtx,
|
||||
std::unique_ptr<Triple> TheTriple,
|
||||
|
||||
@@ -136,6 +136,15 @@ TimeBuild("time-build",
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
TrapOnAVX512("trap-avx512",
|
||||
cl::desc("in relocation mode trap upon entry to any function that uses "
|
||||
"AVX-512 instructions (on by default)"),
|
||||
cl::init(true),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
bool shouldPrint(const BinaryFunction &Function) {
|
||||
if (PrintOnly.empty() && PrintOnlyRegex.empty())
|
||||
return true;
|
||||
@@ -1005,7 +1014,14 @@ void BinaryFunction::disassemble(ArrayRef<uint8_t> FunctionData) {
|
||||
<< Twine::utohexstr(Offset) << " (address 0x"
|
||||
<< Twine::utohexstr(AbsoluteInstrAddr) << ") in function "
|
||||
<< *this << '\n';
|
||||
IsSimple = false;
|
||||
// Some AVX-512 instructions could not be disassembled at all.
|
||||
if (BC.HasRelocations && opts::TrapOnAVX512 &&
|
||||
BC.TheTriple->getArch() == llvm::Triple::x86_64) {
|
||||
setTrapOnEntry();
|
||||
BC.TrappedFunctions.push_back(this);
|
||||
} else {
|
||||
IsSimple = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1018,7 +1034,13 @@ void BinaryFunction::disassemble(ArrayRef<uint8_t> FunctionData) {
|
||||
<< Twine::utohexstr(Offset) << ". Disassembly could be wrong."
|
||||
" Skipping further processing.\n";
|
||||
}
|
||||
IsSimple = false;
|
||||
|
||||
if (BC.HasRelocations && opts::TrapOnAVX512) {
|
||||
setTrapOnEntry();
|
||||
BC.TrappedFunctions.push_back(this);
|
||||
} else {
|
||||
IsSimple = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2168,6 +2190,20 @@ void BinaryFunction::emitBodyRaw(MCStreamer *Streamer) {
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryFunction::setTrapOnEntry() {
|
||||
clearList(Instructions);
|
||||
clearList(IgnoredBranches);
|
||||
clearList(TakenBranches);
|
||||
|
||||
for (const auto EntryOffset : EntryOffsets) {
|
||||
MCInst TrapInstr;
|
||||
BC.MIA->createTrap(TrapInstr);
|
||||
addInstruction(EntryOffset, std::move(TrapInstr));
|
||||
}
|
||||
|
||||
TrapsOnEntry = true;
|
||||
}
|
||||
|
||||
void BinaryFunction::addConstantIslandDependency(BinaryFunction *OtherBF,
|
||||
MCSymbol *HotSymbol,
|
||||
MCSymbol *ColdSymbol) {
|
||||
|
||||
@@ -305,6 +305,9 @@ private:
|
||||
/// for ICF optimization without relocations.
|
||||
bool IsFolded{false};
|
||||
|
||||
/// Execution halts whenever this function is entered.
|
||||
bool TrapsOnEntry{false};
|
||||
|
||||
/// The address for the code for this function in codegen memory.
|
||||
uint64_t ImageAddress{0};
|
||||
|
||||
@@ -814,8 +817,9 @@ private:
|
||||
friend class BinaryContext;
|
||||
|
||||
/// Creation should be handled by RewriteInstance::createBinaryFunction().
|
||||
BinaryFunction(const std::string &Name, BinarySection &Section, uint64_t Address,
|
||||
uint64_t Size, BinaryContext &BC, bool IsSimple) :
|
||||
BinaryFunction(const std::string &Name, BinarySection &Section,
|
||||
uint64_t Address, uint64_t Size, BinaryContext &BC,
|
||||
bool IsSimple) :
|
||||
Names({Name}), Section(Section), Address(Address),
|
||||
Size(Size), BC(BC), IsSimple(IsSimple),
|
||||
CodeSectionName(".local.text." + Name),
|
||||
@@ -1292,6 +1296,15 @@ public:
|
||||
return StringRef(ColdCodeSectionName);
|
||||
}
|
||||
|
||||
/// Return true iif the function will halt execution on entry.
|
||||
bool trapsOnEntry() const {
|
||||
return TrapsOnEntry;
|
||||
}
|
||||
|
||||
/// Make the function always trap on entry. Other than the trap instruction,
|
||||
/// the function body will be empty.
|
||||
void setTrapOnEntry();
|
||||
|
||||
/// Return true if the function could be correctly processed.
|
||||
bool isSimple() const {
|
||||
return IsSimple;
|
||||
|
||||
@@ -1512,6 +1512,18 @@ PrintProgramStats::runOnFunctions(BinaryContext &BC,
|
||||
outs() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!BC.TrappedFunctions.empty()) {
|
||||
errs() << "BOLT-WARNING: " << BC.TrappedFunctions.size()
|
||||
<< " functions will trap on entry";
|
||||
if (opts::Verbosity >= 1) {
|
||||
errs() << ".\n";
|
||||
for (const auto *Function : BC.TrappedFunctions)
|
||||
errs() << " " << *Function << '\n';
|
||||
} else {
|
||||
errs() << " (use -v=1 to see the list).\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InstructionLowering::runOnFunctions(
|
||||
|
||||
@@ -2162,7 +2162,7 @@ void RewriteInstance::disassembleFunctions() {
|
||||
BC->InterproceduralReferences.clear();
|
||||
|
||||
// Fill in CFI information for this function
|
||||
if (Function.isSimple()) {
|
||||
if (Function.isSimple() && !Function.trapsOnEntry()) {
|
||||
if (!CFIRdWrt->fillCFIInfoFor(Function)) {
|
||||
errs() << "BOLT-ERROR: unable to fill CFI for function "
|
||||
<< Function << ".\n";
|
||||
|
||||
Reference in New Issue
Block a user