<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - [Attributor?] Smart noalias deduction"
href="https://bugs.llvm.org/show_bug.cgi?id=44663">44663</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[Attributor?] Smart noalias deduction
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Global Analyses
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>lebedev.ri@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>In this example `sink()` is static, we know all it's call sites.
We should be able to tell in all the call sites,
it's third argument (`highpass.data`) does not alias
with any other pointers used in `sink()` (namely `highhigh.data` and
`lowhigh.data`),
because we should be able to see how `highpass.data`
is being set to a fresh noalias pointer.
<a href="https://godbolt.org/z/32edkj">https://godbolt.org/z/32edkj</a>
#include <cassert> // for assert
#include <type_traits>
#include <vector> // for vector
#include <cstddef> // for vector
#include <cstdint> // for vector
template <class T> class Array2DRef {
int _pitch = 0;
T* _data = nullptr;
friend Array2DRef<const T>; // We need to be able to convert to const
version.
inline T& operator[](int row) const;
public:
using value_type = T;
using cvless_value_type = typename std::remove_cv<value_type>::type;
int width = 0, height = 0;
Array2DRef() = default;
Array2DRef(T* data, int dataWidth, int dataHeight, int dataPitch = 0);
// Conversion from Array2DRef<T> to Array2DRef<const T>.
template <class T2, typename = std::enable_if_t<std::is_same<
typename std::remove_const<T>::type, T2>::value>>
Array2DRef(Array2DRef<T2> RHS) { // NOLINT google-explicit-constructor
_data = RHS._data;
_pitch = RHS._pitch;
width = RHS.width;
height = RHS.height;
}
template <typename AllocatorType =
typename std::vector<cvless_value_type>::allocator_type>
static Array2DRef<T>
create(std::vector<cvless_value_type, AllocatorType>* storage, int width,
int height) {
storage->resize(width * height);
return {storage->data(), width, height};
}
inline T& operator()(int row, int col) const;
};
template <class T>
Array2DRef<T>::Array2DRef(T* data, const int dataWidth, const int dataHeight,
const int dataPitch /* = 0 */)
: _data(data), width(dataWidth), height(dataHeight) {
assert(width >= 0);
assert(height >= 0);
_pitch = (dataPitch == 0 ? dataWidth : dataPitch);
}
template <class T> T& Array2DRef<T>::operator[](const int row) const {
assert(_data);
assert(row >= 0);
assert(row < height);
return _data[row * _pitch];
}
template <class T>
T& Array2DRef<T>::operator()(const int row, const int col) const {
assert(col >= 0);
assert(col < width);
return (&(operator[](row)))[col];
}
static __attribute__((noinline)) void sink(const Array2DRef<const int16_t>
highhigh, const Array2DRef<const int16_t> lowhigh, Array2DRef<int16_t>
highpass) {
for(int row = 0; row < highpass.height; ++row) {
for(int col = 0; col < highpass.width; ++col) {
// highpass does not alias highhigh/lowhigh !
// this should nicely vectorize.
highpass(row, col) = 24 * highhigh(row, col) + 18 * lowhigh (row,
col);
}
}
}
void foo(int width, int height, const Array2DRef<const int16_t> highhigh, const
Array2DRef<const int16_t> lowhigh, std::vector<int16_t>& highpass_storage) {
Array2DRef<int16_t> highpass = Array2DRef<int16_t>::create(&highpass_storage,
width, height);
sink(highhigh, lowhigh, highpass);
}</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>