This patch adds support for propagating matrix expressions along the

inlined-at chain and emitting remarks at the traversed function scopes.

To motivate this new behavior, consider the example below. Without the

remark 'up-leveling', we would only get remarks in load.h and store.h,

but we cannot generate a remark describing the full expression in

toplevel.cpp, which is the place where the user has the best chance of

spotting/fixing potential problems.

With this patch, we generate a remark for the load in load.h, one for

the store in store.h and one for the complete expression in

toplevel.cpp. For a bigger example, please see remarks-inlining.ll.

load.h: template <typename Ty, unsigned R, unsigned C> Matrix<Ty, R, C> load(Ty *Ptr) { Matrix<Ty, R, C> Result; Result.value = *reinterpret_cast <typename Matrix<Ty, R, C>::matrix_t *>(Ptr); return Result; } store.h: template <typename Ty, unsigned R, unsigned C> void store(Matrix<Ty, R, C> M1, Ty *Ptr) { *reinterpret_cast<typename decltype(M1)::matrix_t *>(Ptr) = M1.value; } toplevel.cpp void test(double *A, double *B, double *C) { store(add(load<double, 3, 5>(A), load<double, 3, 5>(B)), C); }

For a given function, we traverse the inlined-at chain for each

matrix instruction (= instructions with shape information). We collect

the matrix instructions in each DISubprogram we visit. This produces a

mapping of DISubprogram -> (List of matrix instructions visible in the

subpogram). We then generate remarks using the list of instructions for

each subprogram. This allows surfacing the remarks at a level useful to

users.

Please note that the current approach may create a lot of extra remarks.

Additional heuristics to cut-off the traversal can be implemented in the

future. For example, it might make sense to stop 'up-leveling' once all

matrix instructions are at the same debug location.