[MergeICmps][NFC] Improve doc.

llvm-svn: 354128
This commit is contained in:
Clement Courbet 2019-02-15 12:58:06 +00:00
parent 55725785d2
commit cc004df7eb
1 changed files with 28 additions and 5 deletions

View File

@ -10,15 +10,35 @@
// later typically inlined as a chain of efficient hardware comparisons). This // later typically inlined as a chain of efficient hardware comparisons). This
// typically benefits c++ member or nonmember operator==(). // typically benefits c++ member or nonmember operator==().
// //
// The basic idea is to replace a larger chain of integer comparisons loaded // The basic idea is to replace a longer chain of integer comparisons loaded
// from contiguous memory locations into a smaller chain of such integer // from contiguous memory locations into a shorter chain of larger integer
// comparisons. Benefits are double: // comparisons. Benefits are double:
// - There are less jumps, and therefore less opportunities for mispredictions // - There are less jumps, and therefore less opportunities for mispredictions
// and I-cache misses. // and I-cache misses.
// - Code size is smaller, both because jumps are removed and because the // - Code size is smaller, both because jumps are removed and because the
// encoding of a 2*n byte compare is smaller than that of two n-byte // encoding of a 2*n byte compare is smaller than that of two n-byte
// compares. // compares.
//
// Example:
//
// struct S {
// int a;
// char b;
// char c;
// uint16_t d;
// bool operator==(const S& o) const {
// return a == o.a && b == o.b && c == o.c && d == o.d;
// }
// };
//
// Is optimized as :
//
// bool S::operator==(const S& o) const {
// return memcmp(this, &o, 8) == 0;
// }
//
// Which will later be expanded (ExpandMemCmp) as a single 8-bytes icmp.
//
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include <algorithm> #include <algorithm>
@ -49,7 +69,9 @@ static bool isSimpleLoadOrStore(const Instruction *I) {
return false; return false;
} }
// A BCE atom. // A BCE atom "Binary Compare Expression Atom" represents an integer load
// that is a constant offset from a base value, e.g. `a` or `o.c` in the example
// at the top.
struct BCEAtom { struct BCEAtom {
BCEAtom() : GEP(nullptr), LoadI(nullptr), Offset() {} BCEAtom() : GEP(nullptr), LoadI(nullptr), Offset() {}
@ -118,7 +140,8 @@ BCEAtom visitICmpLoadOperand(Value *const Val) {
return Result; return Result;
} }
// A basic block with a comparison between two BCE atoms. // A basic block with a comparison between two BCE atoms, e.g. `a == o.a` in the
// example at the top.
// The block might do extra work besides the atom comparison, in which case // The block might do extra work besides the atom comparison, in which case
// doesOtherWork() returns true. Under some conditions, the block can be // doesOtherWork() returns true. Under some conditions, the block can be
// split into the atom comparison part and the "other work" part // split into the atom comparison part and the "other work" part