Download Summary
Transcript
Tools and Design
return N >= 64 ||
(-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
}
In this code, notice how the template has code that handles all bit width values, N. It
features an early comparison to return true whenever the bit width is greater than
64 bits. If not, it builds two expressions, which are the lower and upper bounds for
this bit width, checking whether x is between these bounds. Compare this code to the
following template specialization, which is used to get faster code for the common
case where the bit width is 8:
llvm/include/llvm/Support/MathExtras.h:
template<>
inline bool isInt<8>(int64_t x) {
return static_cast<int8_t>(x) == x;
}
This code brings down the number of comparisons from three to one, thereby
justifying the specialization.
Enforcing C++ best practices in LLVM
It is common to introduce bugs unintentionally when programming, but the
difference is in how you manage your bugs. The LLVM philosophy advises you to
use the assertion mechanism implemented in libLLVMSupport whenever possible.
Notice that debugging a compiler can be particularly difficult, because the product
of the compilation is another program. Therefore, if you can detect erratic behavior
earlier, before writing a complicated output that is not trivial in order to determine
whether it is correct, you are saving a lot of your time. For example, let's see the code
of an ARM backend pass that changes the layout of constant pools, redistributing
them across several smaller pools "islands" across a function. This strategy is
commonly used in ARM programs to load large constants with a limited PC-relative
addressing mechanism because a single, larger pool can be placed in a location that
is too far away from the instruction that uses it. This code lives at llvm/lib/Target/
ARM/ARMConstantIslandPass.cpp and we show an excerpt of it next:
const DataLayout &TD = *MF->getTarget().getDataLayout();
for (unsigned i = 0, e = CPs.size(); i != e; ++i) {
unsigned Size = TD.getTypeAllocSize(CPs[i].getType());
assert(Size >= 4 && "Too small constant pool entry");
unsigned Align = CPs[i].getAlignment();
assert(isPowerOf2_32(Align) && "Invalid alignment");
// Verify that all constant pool entries are a multiple of their
alignment.
// If not, we would have to pad them out so that instructions
stay aligned.
[ 60 ]