Skip to content

Commit

Permalink
BOLT: Add ud2 after indirect tailcalls.
Browse files Browse the repository at this point in the history
Summary:
Insert ud2 instructions after indirect tailcalls to prevent the CPU from
decoding instructions following the callsite.

A simple counter in the peephole pass shows 3260 tail call traps inserted.

(cherry picked from FBD3859737)
  • Loading branch information
Bill Nell authored and maksfb committed Sep 13, 2016
1 parent 2f1341b commit ecc4b9e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
16 changes: 16 additions & 0 deletions bolt/BinaryPasses.cpp
Expand Up @@ -1087,6 +1087,20 @@ void Peepholes::fixDoubleJumps(BinaryContext &BC,
}
}

void Peepholes::addTailcallTraps(BinaryContext &BC,
BinaryFunction &Function) {
for (auto &BB : Function) {
auto *Inst = BB.findLastNonPseudoInstruction();
if (Inst && BC.MIA->isTailCall(*Inst) && BC.MIA->isIndirectBranch(*Inst)) {
MCInst Trap;
if (BC.MIA->createTrap(Trap)) {
BB.addInstruction(Trap);
++TailCallTraps;
}
}
}
}

void Peepholes::runOnFunctions(BinaryContext &BC,
std::map<uint64_t, BinaryFunction> &BFs,
std::set<uint64_t> &LargeFunctions) {
Expand All @@ -1095,9 +1109,11 @@ void Peepholes::runOnFunctions(BinaryContext &BC,
if (shouldOptimize(Function)) {
shortenInstructions(BC, Function);
fixDoubleJumps(BC, Function);
addTailcallTraps(BC, Function);
}
}
outs() << "BOLT-INFO: " << NumDoubleJumps << " double jumps patched.\n";
outs() << "BOLT-INFO: " << TailCallTraps << " tail call traps inserted.\n";
}

bool SimplifyRODataLoads::simplifyRODataLoads(
Expand Down
12 changes: 12 additions & 0 deletions bolt/BinaryPasses.h
Expand Up @@ -257,8 +257,20 @@ class SimplifyConditionalTailCalls : public BinaryFunctionPass {
/// Perform simple peephole optimizations.
class Peepholes : public BinaryFunctionPass {
uint64_t NumDoubleJumps{0};
uint64_t TailCallTraps{0};

/// Attempt to use the minimum operand width for arithmetic, branch and
/// move instructions.
void shortenInstructions(BinaryContext &BC, BinaryFunction &Function);

/// Replace double jumps with a jump directly to the target, i.e.
/// jmp/jcc L1; L1: jmp L2 -> jmp/jcc L2.
void fixDoubleJumps(BinaryContext &BC, BinaryFunction &Function);

/// Add trap instructions immediately after indirect tail calls to prevent
/// the processor from decoding instructions immediate following the
/// tailcall.
void addTailcallTraps(BinaryContext &BC, BinaryFunction &Function);
public:
explicit Peepholes(const cl::opt<bool> &PrintPass)
: BinaryFunctionPass(PrintPass) { }
Expand Down

0 comments on commit ecc4b9e

Please sign in to comment.