Skip to content

Commit 8836a9d

Browse files
authored
Rollup merge of #38557 - michaelwoerister:inline-asm-ich, r=nikomatsakis
incr. comp.: Improve InlineAsm hashing and add test case r? @nikomatsakis
2 parents abf4784 + 6a51d37 commit 8836a9d

File tree

2 files changed

+308
-3
lines changed

2 files changed

+308
-3
lines changed

src/librustc_incremental/calculate_svh/svh_visitor.rs

+43-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc::hir::def_id::DefId;
2828
use rustc::hir::intravisit as visit;
2929
use rustc::ty::TyCtxt;
3030
use rustc_data_structures::fnv;
31-
use std::hash::Hash;
31+
use std::hash::{Hash, Hasher};
3232

3333
use super::def_path_hash::DefPathHashes;
3434
use super::caching_codemap_view::CachingCodemapView;
@@ -264,7 +264,7 @@ enum SawExprComponent<'a> {
264264
SawExprPath,
265265
SawExprAddrOf(hir::Mutability),
266266
SawExprRet,
267-
SawExprInlineAsm(&'a hir::InlineAsm),
267+
SawExprInlineAsm(StableInlineAsm<'a>),
268268
SawExprStruct,
269269
SawExprRepeat,
270270
}
@@ -340,7 +340,7 @@ fn saw_expr<'a>(node: &'a Expr_,
340340
ExprBreak(label, _) => (SawExprBreak(label.map(|l| l.name.as_str())), false),
341341
ExprAgain(label) => (SawExprAgain(label.map(|l| l.name.as_str())), false),
342342
ExprRet(..) => (SawExprRet, false),
343-
ExprInlineAsm(ref a,..) => (SawExprInlineAsm(a), false),
343+
ExprInlineAsm(ref a,..) => (SawExprInlineAsm(StableInlineAsm(a)), false),
344344
ExprStruct(..) => (SawExprStruct, false),
345345
ExprRepeat(..) => (SawExprRepeat, false),
346346
}
@@ -491,6 +491,46 @@ enum SawSpanExpnKind {
491491
SomeExpansion,
492492
}
493493

494+
/// A wrapper that provides a stable Hash implementation.
495+
struct StableInlineAsm<'a>(&'a InlineAsm);
496+
497+
impl<'a> Hash for StableInlineAsm<'a> {
498+
fn hash<H: Hasher>(&self, state: &mut H) {
499+
let InlineAsm {
500+
asm,
501+
asm_str_style,
502+
ref outputs,
503+
ref inputs,
504+
ref clobbers,
505+
volatile,
506+
alignstack,
507+
dialect,
508+
expn_id: _, // This is used for error reporting
509+
} = *self.0;
510+
511+
asm.as_str().hash(state);
512+
asm_str_style.hash(state);
513+
outputs.len().hash(state);
514+
for output in outputs {
515+
let InlineAsmOutput { constraint, is_rw, is_indirect } = *output;
516+
constraint.as_str().hash(state);
517+
is_rw.hash(state);
518+
is_indirect.hash(state);
519+
}
520+
inputs.len().hash(state);
521+
for input in inputs {
522+
input.as_str().hash(state);
523+
}
524+
clobbers.len().hash(state);
525+
for clobber in clobbers {
526+
clobber.as_str().hash(state);
527+
}
528+
volatile.hash(state);
529+
alignstack.hash(state);
530+
dialect.hash(state);
531+
}
532+
}
533+
494534
macro_rules! hash_attrs {
495535
($visitor:expr, $attrs:expr) => ({
496536
let attrs = $attrs;
+265
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
12+
// This test case tests the incremental compilation hash (ICH) implementation
13+
// for inline asm.
14+
15+
// The general pattern followed here is: Change one thing between rev1 and rev2
16+
// and make sure that the hash has changed, then change nothing between rev2 and
17+
// rev3 and make sure that the hash has not changed.
18+
19+
// must-compile-successfully
20+
// revisions: cfail1 cfail2 cfail3
21+
// compile-flags: -Z query-dep-graph
22+
23+
#![allow(warnings)]
24+
#![feature(rustc_attrs)]
25+
#![feature(asm)]
26+
#![crate_type="rlib"]
27+
28+
29+
30+
// Change template -------------------------------------------------------------
31+
#[cfg(cfail1)]
32+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
33+
fn change_template(a: i32) -> i32 {
34+
let c: i32;
35+
unsafe {
36+
asm!("add 1, $0"
37+
: "=r"(c)
38+
: "0"(a)
39+
:
40+
:
41+
);
42+
}
43+
c
44+
}
45+
46+
#[cfg(not(cfail1))]
47+
#[rustc_clean(label="Hir", cfg="cfail2")]
48+
#[rustc_clean(label="Hir", cfg="cfail3")]
49+
#[rustc_dirty(label="HirBody", cfg="cfail2")]
50+
#[rustc_clean(label="HirBody", cfg="cfail3")]
51+
#[rustc_metadata_clean(cfg="cfail2")]
52+
#[rustc_metadata_clean(cfg="cfail3")]
53+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
54+
fn change_template(a: i32) -> i32 {
55+
let c: i32;
56+
unsafe {
57+
asm!("add 2, $0"
58+
: "=r"(c)
59+
: "0"(a)
60+
:
61+
:
62+
);
63+
}
64+
c
65+
}
66+
67+
68+
69+
// Change output -------------------------------------------------------------
70+
#[cfg(cfail1)]
71+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
72+
fn change_output(a: i32) -> i32 {
73+
let mut _out1: i32 = 0;
74+
let mut _out2: i32 = 0;
75+
unsafe {
76+
asm!("add 1, $0"
77+
: "=r"(_out1)
78+
: "0"(a)
79+
:
80+
:
81+
);
82+
}
83+
_out1
84+
}
85+
86+
#[cfg(not(cfail1))]
87+
#[rustc_clean(label="Hir", cfg="cfail2")]
88+
#[rustc_clean(label="Hir", cfg="cfail3")]
89+
#[rustc_dirty(label="HirBody", cfg="cfail2")]
90+
#[rustc_clean(label="HirBody", cfg="cfail3")]
91+
#[rustc_metadata_clean(cfg="cfail2")]
92+
#[rustc_metadata_clean(cfg="cfail3")]
93+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
94+
fn change_output(a: i32) -> i32 {
95+
let mut _out1: i32 = 0;
96+
let mut _out2: i32 = 0;
97+
unsafe {
98+
asm!("add 1, $0"
99+
: "=r"(_out2)
100+
: "0"(a)
101+
:
102+
:
103+
);
104+
}
105+
_out1
106+
}
107+
108+
109+
110+
// Change input -------------------------------------------------------------
111+
#[cfg(cfail1)]
112+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
113+
fn change_input(_a: i32, _b: i32) -> i32 {
114+
let _out;
115+
unsafe {
116+
asm!("add 1, $0"
117+
: "=r"(_out)
118+
: "0"(_a)
119+
:
120+
:
121+
);
122+
}
123+
_out
124+
}
125+
126+
#[cfg(not(cfail1))]
127+
#[rustc_clean(label="Hir", cfg="cfail2")]
128+
#[rustc_clean(label="Hir", cfg="cfail3")]
129+
#[rustc_dirty(label="HirBody", cfg="cfail2")]
130+
#[rustc_clean(label="HirBody", cfg="cfail3")]
131+
#[rustc_metadata_clean(cfg="cfail2")]
132+
#[rustc_metadata_clean(cfg="cfail3")]
133+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
134+
fn change_input(_a: i32, _b: i32) -> i32 {
135+
let _out;
136+
unsafe {
137+
asm!("add 1, $0"
138+
: "=r"(_out)
139+
: "0"(_b)
140+
:
141+
:
142+
);
143+
}
144+
_out
145+
}
146+
147+
148+
149+
// Change input constraint -----------------------------------------------------
150+
#[cfg(cfail1)]
151+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
152+
fn change_input_constraint(_a: i32, _b: i32) -> i32 {
153+
let _out;
154+
unsafe {
155+
asm!("add 1, $0"
156+
: "=r"(_out)
157+
: "0"(_a), "r"(_b)
158+
:
159+
:
160+
);
161+
}
162+
_out
163+
}
164+
165+
#[cfg(not(cfail1))]
166+
#[rustc_clean(label="Hir", cfg="cfail2")]
167+
#[rustc_clean(label="Hir", cfg="cfail3")]
168+
#[rustc_dirty(label="HirBody", cfg="cfail2")]
169+
#[rustc_clean(label="HirBody", cfg="cfail3")]
170+
#[rustc_metadata_clean(cfg="cfail2")]
171+
#[rustc_metadata_clean(cfg="cfail3")]
172+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
173+
fn change_input_constraint(_a: i32, _b: i32) -> i32 {
174+
let _out;
175+
unsafe {
176+
asm!("add 1, $0"
177+
: "=r"(_out)
178+
: "r"(_a), "0"(_b)
179+
:
180+
:
181+
);
182+
}
183+
_out
184+
}
185+
186+
187+
188+
// Change clobber --------------------------------------------------------------
189+
#[cfg(cfail1)]
190+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
191+
fn change_clobber(_a: i32) -> i32 {
192+
let _out;
193+
unsafe {
194+
asm!("add 1, $0"
195+
: "=r"(_out)
196+
: "0"(_a)
197+
:
198+
:
199+
);
200+
}
201+
_out
202+
}
203+
204+
#[cfg(not(cfail1))]
205+
#[rustc_clean(label="Hir", cfg="cfail2")]
206+
#[rustc_clean(label="Hir", cfg="cfail3")]
207+
#[rustc_dirty(label="HirBody", cfg="cfail2")]
208+
#[rustc_clean(label="HirBody", cfg="cfail3")]
209+
#[rustc_metadata_clean(cfg="cfail2")]
210+
#[rustc_metadata_clean(cfg="cfail3")]
211+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
212+
fn change_clobber(_a: i32) -> i32 {
213+
let _out;
214+
unsafe {
215+
asm!("add 1, $0"
216+
: "=r"(_out)
217+
: "0"(_a)
218+
: "eax"
219+
:
220+
);
221+
}
222+
_out
223+
}
224+
225+
226+
227+
// Change options --------------------------------------------------------------
228+
#[cfg(cfail1)]
229+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
230+
fn change_options(_a: i32) -> i32 {
231+
let _out;
232+
unsafe {
233+
asm!("add 1, $0"
234+
: "=r"(_out)
235+
: "0"(_a)
236+
:
237+
:
238+
);
239+
}
240+
_out
241+
}
242+
243+
#[cfg(not(cfail1))]
244+
#[rustc_clean(label="Hir", cfg="cfail2")]
245+
#[rustc_clean(label="Hir", cfg="cfail3")]
246+
#[rustc_dirty(label="HirBody", cfg="cfail2")]
247+
#[rustc_clean(label="HirBody", cfg="cfail3")]
248+
#[rustc_metadata_clean(cfg="cfail2")]
249+
#[rustc_metadata_clean(cfg="cfail3")]
250+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
251+
fn change_options(_a: i32) -> i32 {
252+
let _out;
253+
unsafe {
254+
asm!("add 1, $0"
255+
: "=r"(_out)
256+
: "0"(_a)
257+
:
258+
: "volatile"
259+
);
260+
}
261+
_out
262+
}
263+
264+
265+

0 commit comments

Comments
 (0)