The IR engine can now optimize kernels

With this pull request we make PyOP2 capable of optimizing input kernels. Currently, the supported optimizations, mainly tailored to CPU execution, are:

* Alignment and padding of data structures: for issuing aligned loads and stores.
* Loop trip count adjustment according to padding: useful for autovectorization when the trip count is not a multiple of the vector length
* Loop-invariant code motion and autovectorization of invariant code: this is particularly useful since trip counts are typically small, and hoisted code can still represent a significant proportion of the execution time
* Register tiling for rectangular iteration spaces
* Outer-product vectorization + unroll-and-jam of outer loops to improve register re-use or mitigate register pressure

The ffc_interface has been modified such that the user can specify a certain combination of optimizations. Soon, the documentation will be ready, describing in details how to set and compose specific optimizations.

Incidentally, the wrapper code generation in host.py has been considerably improved from the code quality point of view.