Replace assert! with debug_assert! in production code paths.

This allows the assertions to be disabled in release builds, so that
the code is faster and smaller, at the expense of not performing the
checks. Assertions can be re-enabled in release builds with the
debug-assertions flag in Cargo.toml, as the top-level Cargo.toml
file does.
This commit is contained in:
Dan Gohman
2018-03-12 10:28:35 -07:00
parent e81a27fb5d
commit 30f8daa9d6
43 changed files with 165 additions and 164 deletions

View File

@@ -217,11 +217,11 @@ impl DataFlowGraph {
///
/// The `dest` value can't be attached to an instruction or EBB.
pub fn change_to_alias(&mut self, dest: Value, src: Value) {
assert!(!self.value_is_attached(dest));
debug_assert!(!self.value_is_attached(dest));
// Try to create short alias chains by finding the original source value.
// This also avoids the creation of loops.
let original = self.resolve_aliases(src);
assert_ne!(
debug_assert_ne!(
dest,
original,
"Aliasing {} to {} would create a loop",
@@ -229,7 +229,7 @@ impl DataFlowGraph {
src
);
let ty = self.value_type(original);
assert_eq!(
debug_assert_eq!(
self.value_type(dest),
ty,
"Aliasing {} to {} would change its type {} to {}",
@@ -273,7 +273,7 @@ impl DataFlowGraph {
{
let original = src;
let ty = self.value_type(original);
assert_eq!(
debug_assert_eq!(
self.value_type(dest),
ty,
"Aliasing {} to {} would change its type {} to {}",
@@ -498,9 +498,9 @@ impl DataFlowGraph {
/// This is a very low-level operation. Usually, instruction results with the correct types are
/// created automatically. The `res` value must not be attached to anything else.
pub fn attach_result(&mut self, inst: Inst, res: Value) {
assert!(!self.value_is_attached(res));
debug_assert!(!self.value_is_attached(res));
let num = self.results[inst].push(res, &mut self.value_lists);
assert!(num <= u16::MAX as usize, "Too many result values");
debug_assert!(num <= u16::MAX as usize, "Too many result values");
let ty = self.value_type(res);
self.values[res] = ValueData::Inst {
ty,
@@ -533,7 +533,7 @@ impl DataFlowGraph {
.expect("Replacing detached result"),
new_value,
);
assert_eq!(
debug_assert_eq!(
attached,
old_value,
"{} wasn't detached from {}",
@@ -547,7 +547,7 @@ impl DataFlowGraph {
pub fn append_result(&mut self, inst: Inst, ty: Type) -> Value {
let res = self.values.next_key();
let num = self.results[inst].push(res, &mut self.value_lists);
assert!(num <= u16::MAX as usize, "Too many result values");
debug_assert!(num <= u16::MAX as usize, "Too many result values");
self.make_value(ValueData::Inst {
ty,
inst,
@@ -684,7 +684,7 @@ impl DataFlowGraph {
pub fn append_ebb_param(&mut self, ebb: Ebb, ty: Type) -> Value {
let param = self.values.next_key();
let num = self.ebbs[ebb].params.push(param, &mut self.value_lists);
assert!(num <= u16::MAX as usize, "Too many parameters on EBB");
debug_assert!(num <= u16::MAX as usize, "Too many parameters on EBB");
self.make_value(ValueData::Param {
ty,
num: num as u16,
@@ -761,9 +761,9 @@ impl DataFlowGraph {
///
/// In almost all cases, you should be using `append_ebb_param()` instead of this method.
pub fn attach_ebb_param(&mut self, ebb: Ebb, param: Value) {
assert!(!self.value_is_attached(param));
debug_assert!(!self.value_is_attached(param));
let num = self.ebbs[ebb].params.push(param, &mut self.value_lists);
assert!(num <= u16::MAX as usize, "Too many parameters on EBB");
debug_assert!(num <= u16::MAX as usize, "Too many parameters on EBB");
let ty = self.value_type(param);
self.values[param] = ValueData::Param {
ty,
@@ -859,7 +859,7 @@ impl DataFlowGraph {
/// to create invalid values for index padding which may be reassigned later.
#[cold]
fn set_value_type_for_parser(&mut self, v: Value, t: Type) {
debug_assert!(
assert!(
self.value_type(v) == types::VOID,
"this function is only for assigning types to previously invalid values"
);
@@ -882,7 +882,7 @@ impl DataFlowGraph {
) -> usize {
// Get the call signature if this is a function call.
if let Some(sig) = self.call_signature(inst) {
debug_assert_eq!(self.insts[inst].opcode().constraints().fixed_results(), 0);
assert_eq!(self.insts[inst].opcode().constraints().fixed_results(), 0);
for res_idx in 0..self.signatures[sig].returns.len() {
let ty = self.signatures[sig].returns[res_idx].value_type;
if let Some(v) = reuse.get(res_idx) {

View File

@@ -490,7 +490,7 @@ fn parse_float(s: &str, w: u8, t: u8) -> Result<u64, &'static str> {
significand <<= adjust;
exponent -= i32::from(adjust);
}
assert_eq!(significand >> t, 1);
debug_assert_eq!(significand >> t, 1);
// Trailing significand excludes the high bit.
let t_bits = significand & ((1 << t) - 1);

View File

@@ -560,7 +560,7 @@ impl OpcodeConstraints {
/// Get the value type of result number `n`, having resolved the controlling type variable to
/// `ctrl_type`.
pub fn result_type(self, n: usize, ctrl_type: Type) -> Type {
assert!(n < self.fixed_results(), "Invalid result index");
debug_assert!(n < self.fixed_results(), "Invalid result index");
if let ResolvedConstraint::Bound(t) =
OPERAND_CONSTRAINTS[self.constraint_offset() + n].resolve(ctrl_type)
{
@@ -576,7 +576,7 @@ impl OpcodeConstraints {
/// Unlike results, it is possible for some input values to vary freely within a specific
/// `ValueTypeSet`. This is represented with the `ArgumentConstraint::Free` variant.
pub fn value_argument_constraint(self, n: usize, ctrl_type: Type) -> ResolvedConstraint {
assert!(
debug_assert!(
n < self.fixed_value_arguments(),
"Invalid value argument index"
);

View File

@@ -88,7 +88,7 @@ const LOCAL_LIMIT: SequenceNumber = 100 * MINOR_STRIDE;
// Compute the midpoint between `a` and `b`.
// Return `None` if the midpoint would be equal to either.
fn midpoint(a: SequenceNumber, b: SequenceNumber) -> Option<SequenceNumber> {
assert!(a < b);
debug_assert!(a < b);
// Avoid integer overflow.
let m = a + (b - a) / 2;
if m > a { Some(m) } else { None }
@@ -148,7 +148,7 @@ impl Layout {
/// Assign a valid sequence number to `ebb` such that the numbers are still monotonic. This may
/// require renumbering.
fn assign_ebb_seq(&mut self, ebb: Ebb) {
assert!(self.is_ebb_inserted(ebb));
debug_assert!(self.is_ebb_inserted(ebb));
// Get the sequence number immediately before `ebb`, or 0.
let prev_seq = self.ebbs[ebb]
@@ -334,13 +334,13 @@ impl Layout {
/// Insert `ebb` as the last EBB in the layout.
pub fn append_ebb(&mut self, ebb: Ebb) {
assert!(
debug_assert!(
!self.is_ebb_inserted(ebb),
"Cannot append EBB that is already in the layout"
);
{
let node = &mut self.ebbs[ebb];
assert!(node.first_inst.is_none() && node.last_inst.is_none());
debug_assert!(node.first_inst.is_none() && node.last_inst.is_none());
node.prev = self.last_ebb.into();
node.next = None.into();
}
@@ -355,11 +355,11 @@ impl Layout {
/// Insert `ebb` in the layout before the existing EBB `before`.
pub fn insert_ebb(&mut self, ebb: Ebb, before: Ebb) {
assert!(
debug_assert!(
!self.is_ebb_inserted(ebb),
"Cannot insert EBB that is already in the layout"
);
assert!(
debug_assert!(
self.is_ebb_inserted(before),
"EBB Insertion point not in the layout"
);
@@ -379,11 +379,11 @@ impl Layout {
/// Insert `ebb` in the layout *after* the existing EBB `after`.
pub fn insert_ebb_after(&mut self, ebb: Ebb, after: Ebb) {
assert!(
debug_assert!(
!self.is_ebb_inserted(ebb),
"Cannot insert EBB that is already in the layout"
);
assert!(
debug_assert!(
self.is_ebb_inserted(after),
"EBB Insertion point not in the layout"
);
@@ -403,8 +403,8 @@ impl Layout {
/// Remove `ebb` from the layout.
pub fn remove_ebb(&mut self, ebb: Ebb) {
assert!(self.is_ebb_inserted(ebb), "EBB not in the layout");
assert!(self.first_inst(ebb).is_none(), "EBB must be empty.");
debug_assert!(self.is_ebb_inserted(ebb), "EBB not in the layout");
debug_assert!(self.first_inst(ebb).is_none(), "EBB must be empty.");
// Clear the `ebb` node and extract links.
let prev;
@@ -521,8 +521,8 @@ impl Layout {
/// Append `inst` to the end of `ebb`.
pub fn append_inst(&mut self, inst: Inst, ebb: Ebb) {
assert_eq!(self.inst_ebb(inst), None);
assert!(
debug_assert_eq!(self.inst_ebb(inst), None);
debug_assert!(
self.is_ebb_inserted(ebb),
"Cannot append instructions to EBB not in layout"
);
@@ -532,7 +532,7 @@ impl Layout {
let inst_node = &mut self.insts[inst];
inst_node.ebb = ebb.into();
inst_node.prev = ebb_node.last_inst;
assert!(inst_node.next.is_none());
debug_assert!(inst_node.next.is_none());
}
if ebb_node.first_inst.is_none() {
ebb_node.first_inst = inst.into();
@@ -566,7 +566,7 @@ impl Layout {
/// Insert `inst` before the instruction `before` in the same EBB.
pub fn insert_inst(&mut self, inst: Inst, before: Inst) {
assert_eq!(self.inst_ebb(inst), None);
debug_assert_eq!(self.inst_ebb(inst), None);
let ebb = self.inst_ebb(before).expect(
"Instruction before insertion point not in the layout",
);
@@ -645,7 +645,7 @@ impl Layout {
let old_ebb = self.inst_ebb(before).expect(
"The `before` instruction must be in the layout",
);
assert!(!self.is_ebb_inserted(new_ebb));
debug_assert!(!self.is_ebb_inserted(new_ebb));
// Insert new_ebb after old_ebb.
let next_ebb = self.ebbs[old_ebb].next;

View File

@@ -19,7 +19,7 @@ pub struct ProgramPoint(u32);
impl From<Inst> for ProgramPoint {
fn from(inst: Inst) -> ProgramPoint {
let idx = inst.index();
assert!(idx < (u32::MAX / 2) as usize);
debug_assert!(idx < (u32::MAX / 2) as usize);
ProgramPoint((idx * 2) as u32)
}
}
@@ -27,7 +27,7 @@ impl From<Inst> for ProgramPoint {
impl From<Ebb> for ProgramPoint {
fn from(ebb: Ebb) -> ProgramPoint {
let idx = ebb.index();
assert!(idx < (u32::MAX / 2) as usize);
debug_assert!(idx < (u32::MAX / 2) as usize);
ProgramPoint((idx * 2 + 1) as u32)
}
}

View File

@@ -244,7 +244,7 @@ impl StackSlots {
/// Create a stack slot representing an incoming function argument.
pub fn make_incoming_arg(&mut self, ty: Type, offset: StackOffset) -> StackSlot {
let mut data = StackSlotData::new(StackSlotKind::IncomingArg, ty.bytes());
assert!(offset <= StackOffset::max_value() - data.size as StackOffset);
debug_assert!(offset <= StackOffset::max_value() - data.size as StackOffset);
data.offset = Some(offset);
self.push(data)
}
@@ -269,7 +269,7 @@ impl StackSlots {
// No existing slot found. Make one and insert it into `outgoing`.
let mut data = StackSlotData::new(StackSlotKind::OutgoingArg, size);
assert!(offset <= StackOffset::max_value() - size as StackOffset);
debug_assert!(offset <= StackOffset::max_value() - size as StackOffset);
data.offset = Some(offset);
let ss = self.slots.push(data);
self.outgoing.insert(inspos, ss);