Rollup merge of #38557 - michaelwoerister:inline-asm-ich, r=nikomatsakis
incr. comp.: Improve InlineAsm hashing and add test case r? @nikomatsakis
This commit is contained in:
commit
8836a9da72
@ -28,7 +28,7 @@
|
||||
use rustc::hir::intravisit as visit;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_data_structures::fnv;
|
||||
use std::hash::Hash;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use super::def_path_hash::DefPathHashes;
|
||||
use super::caching_codemap_view::CachingCodemapView;
|
||||
@ -264,7 +264,7 @@ enum SawExprComponent<'a> {
|
||||
SawExprPath,
|
||||
SawExprAddrOf(hir::Mutability),
|
||||
SawExprRet,
|
||||
SawExprInlineAsm(&'a hir::InlineAsm),
|
||||
SawExprInlineAsm(StableInlineAsm<'a>),
|
||||
SawExprStruct,
|
||||
SawExprRepeat,
|
||||
}
|
||||
@ -340,7 +340,7 @@ fn saw_expr<'a>(node: &'a Expr_,
|
||||
ExprBreak(label, _) => (SawExprBreak(label.map(|l| l.name.as_str())), false),
|
||||
ExprAgain(label) => (SawExprAgain(label.map(|l| l.name.as_str())), false),
|
||||
ExprRet(..) => (SawExprRet, false),
|
||||
ExprInlineAsm(ref a,..) => (SawExprInlineAsm(a), false),
|
||||
ExprInlineAsm(ref a,..) => (SawExprInlineAsm(StableInlineAsm(a)), false),
|
||||
ExprStruct(..) => (SawExprStruct, false),
|
||||
ExprRepeat(..) => (SawExprRepeat, false),
|
||||
}
|
||||
@ -491,6 +491,46 @@ enum SawSpanExpnKind {
|
||||
SomeExpansion,
|
||||
}
|
||||
|
||||
/// A wrapper that provides a stable Hash implementation.
|
||||
struct StableInlineAsm<'a>(&'a InlineAsm);
|
||||
|
||||
impl<'a> Hash for StableInlineAsm<'a> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
let InlineAsm {
|
||||
asm,
|
||||
asm_str_style,
|
||||
ref outputs,
|
||||
ref inputs,
|
||||
ref clobbers,
|
||||
volatile,
|
||||
alignstack,
|
||||
dialect,
|
||||
expn_id: _, // This is used for error reporting
|
||||
} = *self.0;
|
||||
|
||||
asm.as_str().hash(state);
|
||||
asm_str_style.hash(state);
|
||||
outputs.len().hash(state);
|
||||
for output in outputs {
|
||||
let InlineAsmOutput { constraint, is_rw, is_indirect } = *output;
|
||||
constraint.as_str().hash(state);
|
||||
is_rw.hash(state);
|
||||
is_indirect.hash(state);
|
||||
}
|
||||
inputs.len().hash(state);
|
||||
for input in inputs {
|
||||
input.as_str().hash(state);
|
||||
}
|
||||
clobbers.len().hash(state);
|
||||
for clobber in clobbers {
|
||||
clobber.as_str().hash(state);
|
||||
}
|
||||
volatile.hash(state);
|
||||
alignstack.hash(state);
|
||||
dialect.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! hash_attrs {
|
||||
($visitor:expr, $attrs:expr) => ({
|
||||
let attrs = $attrs;
|
||||
|
265
src/test/incremental/hashes/inline_asm.rs
Normal file
265
src/test/incremental/hashes/inline_asm.rs
Normal file
@ -0,0 +1,265 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
// This test case tests the incremental compilation hash (ICH) implementation
|
||||
// for inline asm.
|
||||
|
||||
// The general pattern followed here is: Change one thing between rev1 and rev2
|
||||
// and make sure that the hash has changed, then change nothing between rev2 and
|
||||
// rev3 and make sure that the hash has not changed.
|
||||
|
||||
// must-compile-successfully
|
||||
// revisions: cfail1 cfail2 cfail3
|
||||
// compile-flags: -Z query-dep-graph
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(asm)]
|
||||
#![crate_type="rlib"]
|
||||
|
||||
|
||||
|
||||
// Change template -------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_template(a: i32) -> i32 {
|
||||
let c: i32;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(c)
|
||||
: "0"(a)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
c
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_template(a: i32) -> i32 {
|
||||
let c: i32;
|
||||
unsafe {
|
||||
asm!("add 2, $0"
|
||||
: "=r"(c)
|
||||
: "0"(a)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
c
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Change output -------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_output(a: i32) -> i32 {
|
||||
let mut _out1: i32 = 0;
|
||||
let mut _out2: i32 = 0;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out1)
|
||||
: "0"(a)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
_out1
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_output(a: i32) -> i32 {
|
||||
let mut _out1: i32 = 0;
|
||||
let mut _out2: i32 = 0;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out2)
|
||||
: "0"(a)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
_out1
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Change input -------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_input(_a: i32, _b: i32) -> i32 {
|
||||
let _out;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out)
|
||||
: "0"(_a)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
_out
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_input(_a: i32, _b: i32) -> i32 {
|
||||
let _out;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out)
|
||||
: "0"(_b)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
_out
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Change input constraint -----------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_input_constraint(_a: i32, _b: i32) -> i32 {
|
||||
let _out;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out)
|
||||
: "0"(_a), "r"(_b)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
_out
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_input_constraint(_a: i32, _b: i32) -> i32 {
|
||||
let _out;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out)
|
||||
: "r"(_a), "0"(_b)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
_out
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Change clobber --------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_clobber(_a: i32) -> i32 {
|
||||
let _out;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out)
|
||||
: "0"(_a)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
_out
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_clobber(_a: i32) -> i32 {
|
||||
let _out;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out)
|
||||
: "0"(_a)
|
||||
: "eax"
|
||||
:
|
||||
);
|
||||
}
|
||||
_out
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Change options --------------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_options(_a: i32) -> i32 {
|
||||
let _out;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out)
|
||||
: "0"(_a)
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
_out
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn change_options(_a: i32) -> i32 {
|
||||
let _out;
|
||||
unsafe {
|
||||
asm!("add 1, $0"
|
||||
: "=r"(_out)
|
||||
: "0"(_a)
|
||||
:
|
||||
: "volatile"
|
||||
);
|
||||
}
|
||||
_out
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user