From 30a4f2376a392e50ade48685f92e930385ebb68f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 16 Oct 2018 19:17:55 +0200 Subject: [PATCH] fix(armv7): split record_header_indices loop to work around rustc/LLVM bug rustc issue: https://github.com/rust-lang/rust/issues/55105 Steps to reproduce: ``` rustup target add armv7-linux-androideabi RUSTFLAGS="-Ctarget-feature=+neon" cargo build --target armv7-linux-androideabi --release ``` Output without this change: ``` Compiling hyper v0.12.11 (/home/simon/projects/servo-deps/hyper) LLVM ERROR: ran out of registers during register allocation error: Could not compile `hyper`. ``` --- src/proto/h1/role.rs | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/proto/h1/role.rs b/src/proto/h1/role.rs index 78ac0db90c..7f20f323f5 100644 --- a/src/proto/h1/role.rs +++ b/src/proto/h1/role.rs @@ -920,13 +920,41 @@ struct HeaderIndices { fn record_header_indices(bytes: &[u8], headers: &[httparse::Header], indices: &mut [HeaderIndices]) { let bytes_ptr = bytes.as_ptr() as usize; - for (header, indices) in headers.iter().zip(indices.iter_mut()) { - let name_start = header.name.as_ptr() as usize - bytes_ptr; - let name_end = name_start + header.name.len(); - indices.name = (name_start, name_end); - let value_start = header.value.as_ptr() as usize - bytes_ptr; - let value_end = value_start + header.value.len(); - indices.value = (value_start, value_end); + + // FIXME: This should be a single plain `for` loop. + // Splitting it is a work-around for https://github.com/rust-lang/rust/issues/55105 + macro_rules! split_loops_if { + ( + cfg($($cfg: tt)+) + for $i: pat in ($iter: expr) { + $body1: block + $body2: block + } + ) => { + for $i in $iter { + $body1 + #[cfg(not($($cfg)+))] $body2 + } + #[cfg($($cfg)+)] + for $i in $iter { + $body2 + } + } + } + split_loops_if! { + cfg(all(target_arch = "arm", target_feature = "v7", target_feature = "neon")) + for (header, indices) in (headers.iter().zip(indices.iter_mut())) { + { + let name_start = header.name.as_ptr() as usize - bytes_ptr; + let name_end = name_start + header.name.len(); + indices.name = (name_start, name_end); + } + { + let value_start = header.value.as_ptr() as usize - bytes_ptr; + let value_end = value_start + header.value.len(); + indices.value = (value_start, value_end); + } + } } }