Mike Lui
2017-06-21 18:28:36 UTC
I noticed there's several tools which differentiate inverted jumps from
normal jumps in the IR.
Notably Lackey, Cachegrind, and Callgrind do this instrumentation.
They all use the same heuristic:
Lackey:
// The condition of a branch was inverted by VEX if a taken
// branch is in fact a fall through according to client address
Callgrind:
/* VEX code generation sometimes inverts conditional branches.
* As Callgrind counts (conditional) jumps, it has to correct
* inversions. The heuristic is the following:
* (1) Callgrind switches off SB chasing and unrolling, and
* therefore it assumes that a candidate for inversion only is
* the last conditional branch in an SB.
* (2) inversion is assumed if the branch jumps to the address of
* the next guest instruction in memory.
* This heuristic is precalculated in CLG_(collectBlockInfo)().
*
* Branching behavior is also used for branch prediction. Note that
* above heuristic is different from what Cachegrind does.
* Cachegrind uses (2) for all branches.
*/
Could someone elaborate on this? So VEX IR produces something like the
following?:
ORIGINAL:
cmp %rax %rcx
jl LABEL
<more stuff 1>
LABEL:
<more stuff 2>
AFTER VEX:
cmp %rax %rcx
jge LABEL
LABEL:
<more stuff 1>
I don't see a reason for doing this; I may be conflating concepts here.
Is this fundamentally different than my understanding of conditional
inversions in, for example, source C code?:
void foo() {
if (condition) { }
}
goes to
void foo() {
if (!condition) return;
{}
}
Any insights would be helpful.
normal jumps in the IR.
Notably Lackey, Cachegrind, and Callgrind do this instrumentation.
They all use the same heuristic:
Lackey:
// The condition of a branch was inverted by VEX if a taken
// branch is in fact a fall through according to client address
Callgrind:
/* VEX code generation sometimes inverts conditional branches.
* As Callgrind counts (conditional) jumps, it has to correct
* inversions. The heuristic is the following:
* (1) Callgrind switches off SB chasing and unrolling, and
* therefore it assumes that a candidate for inversion only is
* the last conditional branch in an SB.
* (2) inversion is assumed if the branch jumps to the address of
* the next guest instruction in memory.
* This heuristic is precalculated in CLG_(collectBlockInfo)().
*
* Branching behavior is also used for branch prediction. Note that
* above heuristic is different from what Cachegrind does.
* Cachegrind uses (2) for all branches.
*/
Could someone elaborate on this? So VEX IR produces something like the
following?:
ORIGINAL:
cmp %rax %rcx
jl LABEL
<more stuff 1>
LABEL:
<more stuff 2>
AFTER VEX:
cmp %rax %rcx
jge LABEL
LABEL:
<more stuff 1>
I don't see a reason for doing this; I may be conflating concepts here.
Is this fundamentally different than my understanding of conditional
inversions in, for example, source C code?:
void foo() {
if (condition) { }
}
goes to
void foo() {
if (!condition) return;
{}
}
Any insights would be helpful.