Skip to content

Commit ba7257c

Browse files
Merge branch 'main' into pr/7787
2 parents f195efa + e8df5cf commit ba7257c

25 files changed

+337
-42
lines changed

cmake/FindHexagonSDK.cmake

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
include(FindPackageHandleStandardArgs)
2+
3+
##
4+
# Find the Hexagon SDK root
5+
6+
# We use the presense of the hexagon toolchain file to determine the SDK
7+
# root. Other files have names that are too generic (like readme.txt) or
8+
# are platform-specific (like setup_sdk_env.source) to and so can't be
9+
# used to autodetect the path. Plus, we need to find this file anyway.
10+
11+
find_path(
12+
HEXAGON_SDK_ROOT build/cmake/hexagon_toolchain.cmake
13+
HINTS ENV HEXAGON_SDK_ROOT
14+
)
15+
16+
##
17+
# Detect the installed Hexagon tools version
18+
19+
if (NOT DEFINED HEXAGON_TOOLS_VER AND DEFINED ENV{HEXAGON_TOOLS_VER})
20+
set(HEXAGON_TOOLS_VER "$ENV{HEXAGON_TOOLS_VER}")
21+
endif ()
22+
23+
if (NOT DEFINED HEXAGON_TOOLS_VER)
24+
# No other way to list a directory; no need for CONFIGURE_DEPENDS here
25+
# since this is just used to initialize a cache variable.
26+
file(
27+
GLOB tools_versions
28+
RELATIVE "${HEXAGON_SDK_ROOT}/tools/HEXAGON_Tools"
29+
"${HEXAGON_SDK_ROOT}/tools/HEXAGON_Tools/*"
30+
)
31+
if (NOT tools_versions STREQUAL "")
32+
list(GET tools_versions 0 HEXAGON_TOOLS_VER)
33+
endif ()
34+
endif ()
35+
36+
set(HEXAGON_TOOLS_VER "${HEXAGON_TOOLS_VER}"
37+
CACHE STRING "Version of the Hexagon tools to use")
38+
39+
set(HEXAGON_TOOLS_ROOT "${HEXAGON_SDK_ROOT}/tools/HEXAGON_Tools/${HEXAGON_TOOLS_VER}")
40+
41+
##
42+
# Set known paths
43+
44+
set(HEXAGON_TOOLCHAIN ${HEXAGON_SDK_ROOT}/build/cmake/hexagon_toolchain.cmake)
45+
set(HEXAGON_QAIC ${HEXAGON_SDK_ROOT}/ipc/fastrpc/qaic/Ubuntu16/qaic)
46+
47+
set(ANDROID_NDK_ROOT ${HEXAGON_SDK_ROOT}/tools/android-ndk-r19c)
48+
set(ANDROID_NDK_TOOLCHAIN ${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake)
49+
50+
##
51+
# Find ISS wrapper library and headers
52+
53+
find_library(
54+
HEXAGON_ISS_WRAPPER_LIBRARY
55+
NAMES wrapper
56+
HINTS "${HEXAGON_TOOLS_ROOT}"
57+
PATH_SUFFIXES Tools/lib/iss lib/iss iss
58+
)
59+
60+
find_path(
61+
HEXAGON_ISS_WRAPPER_INCLUDE_DIRECTORY
62+
NAMES HexagonWrapper.h
63+
HINTS "${HEXAGON_TOOLS_ROOT}"
64+
PATH_SUFFIXES Tools/include/iss include/iss iss
65+
)
66+
67+
##
68+
# Validate we found everything correctly
69+
70+
find_package_handle_standard_args(
71+
HexagonSDK
72+
REQUIRED_VARS
73+
HEXAGON_SDK_ROOT
74+
HEXAGON_TOOLS_ROOT
75+
HEXAGON_TOOLCHAIN
76+
HEXAGON_ISS_WRAPPER_LIBRARY
77+
HEXAGON_ISS_WRAPPER_INCLUDE_DIRECTORY
78+
HANDLE_COMPONENTS
79+
)
80+
81+
##
82+
# Create imported targets
83+
84+
if (HexagonSDK_FOUND AND NOT TARGET HexagonSDK::wrapper)
85+
add_library(HexagonSDK::wrapper UNKNOWN IMPORTED)
86+
set_target_properties(
87+
HexagonSDK::wrapper
88+
PROPERTIES
89+
IMPORTED_LOCATION "${HEXAGON_ISS_WRAPPER_LIBRARY}"
90+
INTERFACE_INCLUDE_DIRECTORIES "${HEXAGON_ISS_WRAPPER_INCLUDE_DIRECTORY}"
91+
)
92+
endif ()

src/FindIntrinsics.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,19 @@ Expr to_rounding_shift(const Call *c) {
157157
return rounding_shift(cast(add->type, add->args[0]), b);
158158
}
159159
}
160-
// Also need to handle the annoying case of a reinterpret wrapping a widen_right_add
160+
161+
// Also need to handle the annoying case of a reinterpret cast wrapping a widen_right_add
161162
// TODO: this pattern makes me want to change the semantics of this op.
162-
if (const Reinterpret *reinterp = a.as<Reinterpret>()) {
163-
if (reinterp->type.bits() == reinterp->value.type().bits()) {
164-
if (const Call *add = Call::as_intrinsic(reinterp->value, {Call::widen_right_add})) {
163+
if (const Cast *cast = a.as<Cast>()) {
164+
if (cast->is_reinterpret()) {
165+
if (const Call *add = Call::as_intrinsic(cast->value, {Call::widen_right_add})) {
165166
if (can_prove(lower_intrinsics(add->args[1] == round))) {
166-
// We expect the first operand to be a reinterpet.
167-
const Reinterpret *reinterp_a = add->args[0].as<Reinterpret>();
168-
internal_assert(reinterp_a) << "Failed: " << add->args[0] << "\n";
169-
return rounding_shift(reinterp_a->value, b);
167+
// We expect the first operand to be a reinterpet cast.
168+
if (const Cast *cast_a = add->args[0].as<Cast>()) {
169+
if (cast_a->is_reinterpret()) {
170+
return rounding_shift(cast_a->value, b);
171+
}
172+
}
170173
}
171174
}
172175
}
@@ -245,9 +248,9 @@ class FindIntrinsics : public IRMutator {
245248
if (b.type().code() != narrow_a.type().code()) {
246249
// Need to do a safe reinterpret.
247250
Type t = b.type().with_code(code);
248-
result = widen_right_add(reinterpret(t, b), narrow_a);
251+
result = widen_right_add(cast(t, b), narrow_a);
249252
internal_assert(result.type() != op->type);
250-
result = reinterpret(op->type, result);
253+
result = cast(op->type, result);
251254
} else {
252255
result = widen_right_add(b, narrow_a);
253256
}
@@ -258,9 +261,9 @@ class FindIntrinsics : public IRMutator {
258261
if (a.type().code() != narrow_b.type().code()) {
259262
// Need to do a safe reinterpret.
260263
Type t = a.type().with_code(code);
261-
result = widen_right_add(reinterpret(t, a), narrow_b);
264+
result = widen_right_add(cast(t, a), narrow_b);
262265
internal_assert(result.type() != op->type);
263-
result = reinterpret(op->type, result);
266+
result = cast(op->type, result);
264267
} else {
265268
result = widen_right_add(a, narrow_b);
266269
}
@@ -328,9 +331,9 @@ class FindIntrinsics : public IRMutator {
328331
if (a.type().code() != narrow_b.type().code()) {
329332
// Need to do a safe reinterpret.
330333
Type t = a.type().with_code(code);
331-
result = widen_right_sub(reinterpret(t, a), narrow_b);
334+
result = widen_right_sub(cast(t, a), narrow_b);
332335
internal_assert(result.type() != op->type);
333-
result = reinterpret(op->type, result);
336+
result = cast(op->type, result);
334337
} else {
335338
result = widen_right_sub(a, narrow_b);
336339
}
@@ -410,9 +413,9 @@ class FindIntrinsics : public IRMutator {
410413
if (b.type().code() != narrow_a.type().code()) {
411414
// Need to do a safe reinterpret.
412415
Type t = b.type().with_code(code);
413-
result = widen_right_mul(reinterpret(t, b), narrow_a);
416+
result = widen_right_mul(cast(t, b), narrow_a);
414417
internal_assert(result.type() != op->type);
415-
result = reinterpret(op->type, result);
418+
result = cast(op->type, result);
416419
} else {
417420
result = widen_right_mul(b, narrow_a);
418421
}
@@ -423,9 +426,9 @@ class FindIntrinsics : public IRMutator {
423426
if (a.type().code() != narrow_b.type().code()) {
424427
// Need to do a safe reinterpret.
425428
Type t = a.type().with_code(code);
426-
result = widen_right_mul(reinterpret(t, a), narrow_b);
429+
result = widen_right_mul(cast(t, a), narrow_b);
427430
internal_assert(result.type() != op->type);
428-
result = reinterpret(op->type, result);
431+
result = cast(op->type, result);
429432
} else {
430433
result = widen_right_mul(a, narrow_b);
431434
}
@@ -1261,8 +1264,8 @@ Expr lower_saturating_add(const Expr &a, const Expr &b) {
12611264
return select(sum < a, a.type().max(), sum);
12621265
} else if (a.type().is_int()) {
12631266
Type u = a.type().with_code(halide_type_uint);
1264-
Expr ua = reinterpret(u, a);
1265-
Expr ub = reinterpret(u, b);
1267+
Expr ua = cast(u, a);
1268+
Expr ub = cast(u, b);
12661269
Expr upper = make_const(u, (uint64_t(1) << (a.type().bits() - 1)) - 1);
12671270
Expr lower = make_const(u, (uint64_t(1) << (a.type().bits() - 1)));
12681271
Expr sum = ua + ub;
@@ -1272,7 +1275,7 @@ Expr lower_saturating_add(const Expr &a, const Expr &b) {
12721275
// a + b >= 0 === a >= -b === a >= ~b + 1 === a > ~b
12731276
Expr pos_result = min(sum, upper);
12741277
Expr neg_result = max(sum, lower);
1275-
return simplify(reinterpret(a.type(), select(~b < a, pos_result, neg_result)));
1278+
return simplify(cast(a.type(), select(~b < a, pos_result, neg_result)));
12761279
} else {
12771280
internal_error << "Bad type for saturating_add: " << a.type() << "\n";
12781281
return Expr();
@@ -1288,8 +1291,8 @@ Expr lower_saturating_sub(const Expr &a, const Expr &b) {
12881291
} else if (a.type().is_int()) {
12891292
// Do the math in unsigned, to avoid overflow in the simplifier.
12901293
Type u = a.type().with_code(halide_type_uint);
1291-
Expr ua = reinterpret(u, a);
1292-
Expr ub = reinterpret(u, b);
1294+
Expr ua = cast(u, a);
1295+
Expr ub = cast(u, b);
12931296
Expr upper = make_const(u, (uint64_t(1) << (a.type().bits() - 1)) - 1);
12941297
Expr lower = make_const(u, (uint64_t(1) << (a.type().bits() - 1)));
12951298
Expr diff = ua - ub;
@@ -1300,7 +1303,7 @@ Expr lower_saturating_sub(const Expr &a, const Expr &b) {
13001303
// and saturate the negative difference to be at least -2^31 + 2^32 = 2^31
13011304
Expr neg_diff = max(lower, diff);
13021305
// Then select between them, and cast back to the signed type.
1303-
return simplify(reinterpret(a.type(), select(b <= a, pos_diff, neg_diff)));
1306+
return simplify(cast(a.type(), select(b <= a, pos_diff, neg_diff)));
13041307
} else if (a.type().is_uint()) {
13051308
return simplify(select(b < a, a - b, make_zero(a.type())));
13061309
} else {

src/IR.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ struct Cast : public ExprNode<Cast> {
3232
static Expr make(Type t, Expr v);
3333

3434
static const IRNodeType _node_type = IRNodeType::Cast;
35+
36+
/** Check if the cast is equivalent to a reinterpret. */
37+
bool is_reinterpret() const {
38+
return (type.is_int_or_uint() &&
39+
value.type().is_int_or_uint() &&
40+
type.bits() == value.type().bits());
41+
}
3542
};
3643

3744
/** Reinterpret value as another type, without affecting any of the bits

src/IRMatch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,6 +2101,7 @@ struct SliceOp {
21012101
}
21022102
const Shuffle &v = (const Shuffle &)e;
21032103
return v.vectors.size() == 1 &&
2104+
v.is_slice() &&
21042105
vec.template match<bound>(*v.vectors[0].get(), state) &&
21052106
base.template match<bound | bindings<Vec>::mask>(v.slice_begin(), state) &&
21062107
stride.template match<bound | bindings<Vec>::mask | bindings<Base>::mask>(v.slice_stride(), state) &&

src/LLVM_Output.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,11 @@ void create_static_library(const std::vector<std::string> &src_files_in, const T
593593
return;
594594
}
595595

596+
#if LLVM_VERSION >= 180
597+
const llvm::SymtabWritingMode write_symtab = llvm::SymtabWritingMode::NormalSymtab;
598+
#else
596599
const bool write_symtab = true;
600+
#endif
597601
const auto kind = Internal::get_triple_for_target(target).isOSDarwin() ? llvm::object::Archive::K_BSD : llvm::object::Archive::K_GNU;
598602
const bool thin = false;
599603
auto result = llvm::writeArchive(dst_file, new_members,

src/Simplify_Exprs.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -314,23 +314,26 @@ Expr Simplify::visit(const Load *op, ExprInfo *bounds) {
314314
ExprInfo index_info;
315315
Expr index = mutate(op->index, &index_info);
316316

317-
// If the load is fully out of bounds, replace it with undef.
318-
// This should only occur inside branches that make the load unreachable,
319-
// but perhaps the branch was hard to prove constant true or false. This
320-
// provides an alternative mechanism to simplify these unreachable loads.
321-
string alloc_extent_name = op->name + ".total_extent_bytes";
322-
if (bounds_and_alignment_info.contains(alloc_extent_name)) {
323-
if (index_info.max_defined && index_info.max < 0) {
324-
in_unreachable = true;
325-
return unreachable(op->type);
326-
}
327-
const ExprInfo &alloc_info = bounds_and_alignment_info.get(alloc_extent_name);
328-
if (alloc_info.max_defined && index_info.min_defined) {
329-
int index_min_bytes = index_info.min * op->type.bytes();
330-
if (index_min_bytes > alloc_info.max) {
317+
// If an unpredicated load is fully out of bounds, replace it with an
318+
// unreachable intrinsic. This should only occur inside branches that make
319+
// the load unreachable, but perhaps the branch was hard to prove constant
320+
// true or false. This provides an alternative mechanism to simplify these
321+
// unreachable loads.
322+
if (is_const_one(op->predicate)) {
323+
string alloc_extent_name = op->name + ".total_extent_bytes";
324+
if (bounds_and_alignment_info.contains(alloc_extent_name)) {
325+
if (index_info.max_defined && index_info.max < 0) {
331326
in_unreachable = true;
332327
return unreachable(op->type);
333328
}
329+
const ExprInfo &alloc_info = bounds_and_alignment_info.get(alloc_extent_name);
330+
if (alloc_info.max_defined && index_info.min_defined) {
331+
int index_min_bytes = index_info.min * op->type.bytes();
332+
if (index_min_bytes > alloc_info.max) {
333+
in_unreachable = true;
334+
return unreachable(op->type);
335+
}
336+
}
334337
}
335338
}
336339

@@ -347,7 +350,7 @@ Expr Simplify::visit(const Load *op, ExprInfo *bounds) {
347350
const Shuffle *s_index = index.as<Shuffle>();
348351
if (is_const_zero(predicate)) {
349352
// Predicate is always false
350-
return undef(op->type);
353+
return make_zero(op->type);
351354
} else if (b_index && is_const_one(predicate)) {
352355
// Load of a broadcast should be broadcast of the load
353356
Expr new_index = b_index->value;

src/runtime/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,4 +338,8 @@ add_library(Halide_Runtime INTERFACE)
338338
add_library(Halide::Runtime ALIAS Halide_Runtime)
339339
target_include_directories(Halide_Runtime INTERFACE $<BUILD_INTERFACE:${Halide_BINARY_DIR}/include>)
340340
set_target_properties(Halide_Runtime PROPERTIES EXPORT_NAME Runtime)
341+
option(Halide_BUILD_HEXAGON_REMOTE_RUNTIME "Build the hexagon remote runtime for offloading to Hexagon (HVX)" OFF)
341342

343+
if (Halide_BUILD_HEXAGON_REMOTE_RUNTIME AND NOT Halide_CLANG_TIDY_BUILD)
344+
add_subdirectory(hexagon_remote)
345+
endif ()

src/runtime/hexagon_host.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,11 @@ WEAK int init_hexagon_runtime(void *user_context) {
147147
if (!host_lib) {
148148
host_lib = halide_load_library("libhalide_hexagon_host.dll");
149149
}
150-
150+
if (!host_lib) {
151+
// This will now cause a more specific error 'halide_error_code_symbol_not_found' down the line.
152+
// So, just print this message and continue on instead of returning a generic error here.
153+
error(user_context) << "Hexagon: unable to load libhalide_hexagon_host.so";
154+
}
151155
debug(user_context) << "Hexagon: init_hexagon_runtime (user_context: " << user_context << ")\n";
152156

153157
// Get the symbols we need from the library.

0 commit comments

Comments
 (0)