Update rustfmt to 0.9.0.

This commit is contained in:
Dan Gohman
2017-08-31 10:44:59 -07:00
parent 46fb64cbb4
commit 2efdc0ed37
111 changed files with 4692 additions and 3379 deletions

View File

@@ -98,9 +98,11 @@ fn legalize_entry_arguments(func: &mut Function, entry: Ebb) {
// Compute the value we want for `arg` from the legalized ABI arguments.
let mut get_arg = |dfg: &mut DataFlowGraph, ty| {
let abi_type = abi_types[abi_arg];
assert_eq!(abi_type.purpose,
ArgumentPurpose::Normal,
"Can't legalize special-purpose argument");
assert_eq!(
abi_type.purpose,
ArgumentPurpose::Normal,
"Can't legalize special-purpose argument"
);
if ty == abi_type.value_type {
abi_arg += 1;
Ok(dfg.append_ebb_arg(entry, ty))
@@ -159,14 +161,17 @@ fn legalize_entry_arguments(func: &mut Function, entry: Ebb) {
/// This function is very similar to the `legalize_entry_arguments` function above.
///
/// Returns the possibly new instruction representing the call.
fn legalize_inst_results<ResType>(dfg: &mut DataFlowGraph,
pos: &mut Cursor,
mut get_abi_type: ResType)
-> Inst
where ResType: FnMut(&DataFlowGraph, usize) -> ArgumentType
fn legalize_inst_results<ResType>(
dfg: &mut DataFlowGraph,
pos: &mut Cursor,
mut get_abi_type: ResType,
) -> Inst
where
ResType: FnMut(&DataFlowGraph, usize) -> ArgumentType,
{
let call = pos.current_inst()
.expect("Cursor must point to a call instruction");
let call = pos.current_inst().expect(
"Cursor must point to a call instruction",
);
// We theoretically allow for call instructions that return a number of fixed results before
// the call return values. In practice, it doesn't happen.
@@ -216,13 +221,15 @@ fn legalize_inst_results<ResType>(dfg: &mut DataFlowGraph,
/// - `Err(arg_type)` if further conversions are needed from the ABI argument `arg_type`.
///
/// If the `into_result` value is provided, the converted result will be written into that value.
fn convert_from_abi<GetArg>(dfg: &mut DataFlowGraph,
pos: &mut Cursor,
ty: Type,
into_result: Option<Value>,
get_arg: &mut GetArg)
-> Value
where GetArg: FnMut(&mut DataFlowGraph, Type) -> Result<Value, ArgumentType>
fn convert_from_abi<GetArg>(
dfg: &mut DataFlowGraph,
pos: &mut Cursor,
ty: Type,
into_result: Option<Value>,
get_arg: &mut GetArg,
) -> Value
where
GetArg: FnMut(&mut DataFlowGraph, Type) -> Result<Value, ArgumentType>,
{
// Terminate the recursion when we get the desired type.
let arg_type = match get_arg(dfg, ty) {
@@ -246,11 +253,13 @@ fn convert_from_abi<GetArg>(dfg: &mut DataFlowGraph,
let abi_ty = ty.half_width().expect("Invalid type for conversion");
let lo = convert_from_abi(dfg, pos, abi_ty, None, get_arg);
let hi = convert_from_abi(dfg, pos, abi_ty, None, get_arg);
dbg!("intsplit {}: {}, {}: {}",
lo,
dfg.value_type(lo),
hi,
dfg.value_type(hi));
dbg!(
"intsplit {}: {}, {}: {}",
lo,
dfg.value_type(lo),
hi,
dfg.value_type(hi)
);
dfg.ins(pos).with_results([into_result]).iconcat(lo, hi)
}
// Construct a `ty` by concatenating two halves of a vector.
@@ -296,12 +305,14 @@ fn convert_from_abi<GetArg>(dfg: &mut DataFlowGraph,
/// 2. If the suggested argument doesn't have the right value type, don't change anything, but
/// return the `Err(ArgumentType)` that is needed.
///
fn convert_to_abi<PutArg>(dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
value: Value,
put_arg: &mut PutArg)
where PutArg: FnMut(&mut DataFlowGraph, Value) -> Result<(), ArgumentType>
fn convert_to_abi<PutArg>(
dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
value: Value,
put_arg: &mut PutArg,
) where
PutArg: FnMut(&mut DataFlowGraph, Value) -> Result<(), ArgumentType>,
{
// Start by invoking the closure to either terminate the recursion or get the argument type
// we're trying to match.
@@ -360,7 +371,8 @@ fn check_call_signature(dfg: &DataFlowGraph, inst: Inst) -> Result<(), SigRef> {
let sig = &dfg.signatures[sig_ref];
if check_arg_types(dfg, args, &sig.argument_types[..]) &&
check_arg_types(dfg, dfg.inst_results(inst), &sig.return_types[..]) {
check_arg_types(dfg, dfg.inst_results(inst), &sig.return_types[..])
{
// All types check out.
Ok(())
} else {
@@ -380,20 +392,23 @@ fn check_return_signature(dfg: &DataFlowGraph, inst: Inst, sig: &Signature) -> b
/// - `get_abi_type` is a closure that can provide the desired `ArgumentType` for a given ABI
/// argument number in `0..abi_args`.
///
fn legalize_inst_arguments<ArgType>(dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
abi_args: usize,
mut get_abi_type: ArgType)
where ArgType: FnMut(&DataFlowGraph, usize) -> ArgumentType
fn legalize_inst_arguments<ArgType>(
dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
abi_args: usize,
mut get_abi_type: ArgType,
) where
ArgType: FnMut(&DataFlowGraph, usize) -> ArgumentType,
{
let inst = pos.current_inst()
.expect("Cursor must point to a call instruction");
let inst = pos.current_inst().expect(
"Cursor must point to a call instruction",
);
// Lift the value list out of the call instruction so we modify it.
let mut vlist = dfg[inst]
.take_value_list()
.expect("Call must have a value list");
let mut vlist = dfg[inst].take_value_list().expect(
"Call must have a value list",
);
// The value list contains all arguments to the instruction, including the callee on an
// indirect call which isn't part of the call arguments that must match the ABI signature.
@@ -474,23 +489,23 @@ pub fn handle_call_abi(mut inst: Inst, func: &mut Function, cfg: &ControlFlowGra
// OK, we need to fix the call arguments to match the ABI signature.
let abi_args = dfg.signatures[sig_ref].argument_types.len();
legalize_inst_arguments(dfg,
cfg,
pos,
abi_args,
|dfg, abi_arg| dfg.signatures[sig_ref].argument_types[abi_arg]);
legalize_inst_arguments(dfg, cfg, pos, abi_args, |dfg, abi_arg| {
dfg.signatures[sig_ref].argument_types[abi_arg]
});
if !dfg.signatures[sig_ref].return_types.is_empty() {
inst = legalize_inst_results(dfg,
pos,
|dfg, abi_res| dfg.signatures[sig_ref].return_types[abi_res]);
inst = legalize_inst_results(dfg, pos, |dfg, abi_res| {
dfg.signatures[sig_ref].return_types[abi_res]
});
}
debug_assert!(check_call_signature(dfg, inst).is_ok(),
"Signature still wrong: {}, {}{}",
dfg.display_inst(inst, None),
sig_ref,
dfg.signatures[sig_ref]);
debug_assert!(
check_call_signature(dfg, inst).is_ok(),
"Signature still wrong: {}, {}{}",
dfg.display_inst(inst, None),
sig_ref,
dfg.signatures[sig_ref]
);
// Go back and insert spills for any stack arguments.
pos.goto_inst(inst);
@@ -519,27 +534,30 @@ pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph
.iter()
.rev()
.take_while(|&rt| {
rt.purpose == ArgumentPurpose::Link ||
rt.purpose == ArgumentPurpose::StructReturn ||
rt.purpose == ArgumentPurpose::VMContext
})
rt.purpose == ArgumentPurpose::Link || rt.purpose == ArgumentPurpose::StructReturn ||
rt.purpose == ArgumentPurpose::VMContext
})
.count();
let abi_args = sig.return_types.len() - special_args;
legalize_inst_arguments(dfg,
cfg,
pos,
abi_args,
|_, abi_arg| sig.return_types[abi_arg]);
legalize_inst_arguments(
dfg,
cfg,
pos,
abi_args,
|_, abi_arg| sig.return_types[abi_arg],
);
assert_eq!(dfg.inst_variable_args(inst).len(), abi_args);
// Append special return arguments for any `sret`, `link`, and `vmctx` return values added to
// the legalized signature. These values should simply be propagated from the entry block
// arguments.
if special_args > 0 {
dbg!("Adding {} special-purpose arguments to {}",
special_args,
dfg.display_inst(inst, None));
dbg!(
"Adding {} special-purpose arguments to {}",
special_args,
dfg.display_inst(inst, None)
);
let mut vlist = dfg[inst].take_value_list().unwrap();
for arg in &sig.return_types[abi_args..] {
match arg.purpose {
@@ -565,10 +583,12 @@ pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph
dfg[inst].put_value_list(vlist);
}
debug_assert!(check_return_signature(dfg, inst, sig),
"Signature still wrong: {} / signature {}",
dfg.display_inst(inst, None),
sig);
debug_assert!(
check_return_signature(dfg, inst, sig),
"Signature still wrong: {} / signature {}",
dfg.display_inst(inst, None),
sig
);
// Yes, we changed stuff.
true
@@ -579,10 +599,10 @@ pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph
/// Values that are passed into the function on the stack must be assigned to an `IncomingArg`
/// stack slot already during legalization.
fn spill_entry_arguments(func: &mut Function, entry: Ebb) {
for (abi, &arg) in func.signature
.argument_types
.iter()
.zip(func.dfg.ebb_args(entry)) {
for (abi, &arg) in func.signature.argument_types.iter().zip(
func.dfg.ebb_args(entry),
)
{
if let ArgumentLoc::Stack(offset) = abi.location {
let ss = func.stack_slots.make_incoming_arg(abi.value_type, offset);
func.locations[arg] = ValueLoc::Stack(ss);
@@ -598,15 +618,18 @@ fn spill_entry_arguments(func: &mut Function, entry: Ebb) {
/// TODO: The outgoing stack slots can be written a bit earlier, as long as there are no branches
/// or calls between writing the stack slots and the call instruction. Writing the slots earlier
/// could help reduce register pressure before the call.
fn spill_call_arguments(dfg: &mut DataFlowGraph,
locations: &mut ValueLocations,
stack_slots: &mut StackSlots,
pos: &mut Cursor)
-> bool {
let inst = pos.current_inst()
.expect("Cursor must point to a call instruction");
let sig_ref = dfg.call_signature(inst)
.expect("Call instruction expected.");
fn spill_call_arguments(
dfg: &mut DataFlowGraph,
locations: &mut ValueLocations,
stack_slots: &mut StackSlots,
pos: &mut Cursor,
) -> bool {
let inst = pos.current_inst().expect(
"Cursor must point to a call instruction",
);
let sig_ref = dfg.call_signature(inst).expect(
"Call instruction expected.",
);
// Start by building a list of stack slots and arguments to be replaced.
// This requires borrowing `dfg`, so we can't change anything.

View File

@@ -35,12 +35,14 @@ pub fn expand_heap_addr(inst: ir::Inst, func: &mut ir::Function, _cfg: &mut Cont
}
/// Expand a `heap_addr` for a dynamic heap.
fn dynamic_addr(inst: ir::Inst,
heap: ir::Heap,
offset: ir::Value,
size: u32,
bound_gv: ir::GlobalVar,
func: &mut ir::Function) {
fn dynamic_addr(
inst: ir::Inst,
heap: ir::Heap,
offset: ir::Value,
size: u32,
bound_gv: ir::GlobalVar,
func: &mut ir::Function,
) {
let size = size as i64;
let offset_ty = func.dfg.value_type(offset);
let addr_ty = func.dfg.value_type(func.dfg.first_result(inst));
@@ -54,21 +56,30 @@ fn dynamic_addr(inst: ir::Inst,
let oob;
if size == 1 {
// `offset > bound - 1` is the same as `offset >= bound`.
oob = pos.ins()
.icmp(IntCC::UnsignedGreaterThanOrEqual, offset, bound);
oob = pos.ins().icmp(
IntCC::UnsignedGreaterThanOrEqual,
offset,
bound,
);
} else if size <= min_size {
// We know that bound >= min_size, so here we can compare `offset > bound - size` without
// wrapping.
let adj_bound = pos.ins().iadd_imm(bound, -size);
oob = pos.ins()
.icmp(IntCC::UnsignedGreaterThan, offset, adj_bound);
oob = pos.ins().icmp(
IntCC::UnsignedGreaterThan,
offset,
adj_bound,
);
} else {
// We need an overflow check for the adjusted offset.
let size_val = pos.ins().iconst(offset_ty, size);
let (adj_offset, overflow) = pos.ins().iadd_cout(offset, size_val);
pos.ins().trapnz(overflow);
oob = pos.ins()
.icmp(IntCC::UnsignedGreaterThan, adj_offset, bound);
oob = pos.ins().icmp(
IntCC::UnsignedGreaterThan,
adj_offset,
bound,
);
}
pos.ins().trapnz(oob);
@@ -76,12 +87,14 @@ fn dynamic_addr(inst: ir::Inst,
}
/// Expand a `heap_addr` for a static heap.
fn static_addr(inst: ir::Inst,
heap: ir::Heap,
offset: ir::Value,
size: u32,
bound: i64,
func: &mut ir::Function) {
fn static_addr(
inst: ir::Inst,
heap: ir::Heap,
offset: ir::Value,
size: u32,
bound: i64,
func: &mut ir::Function,
) {
let size = size as i64;
let offset_ty = func.dfg.value_type(offset);
let addr_ty = func.dfg.value_type(func.dfg.first_result(inst));
@@ -104,11 +117,17 @@ fn static_addr(inst: ir::Inst,
let oob = if limit & 1 == 1 {
// Prefer testing `offset >= limit - 1` when limit is odd because an even number is
// likely to be a convenient constant on ARM and other RISC architectures.
pos.ins()
.icmp_imm(IntCC::UnsignedGreaterThanOrEqual, offset, limit - 1)
pos.ins().icmp_imm(
IntCC::UnsignedGreaterThanOrEqual,
offset,
limit - 1,
)
} else {
pos.ins()
.icmp_imm(IntCC::UnsignedGreaterThan, offset, limit)
pos.ins().icmp_imm(
IntCC::UnsignedGreaterThan,
offset,
limit,
)
};
pos.ins().trapnz(oob);
}
@@ -119,12 +138,14 @@ fn static_addr(inst: ir::Inst,
/// Emit code for the base address computation of a `heap_addr` instruction.
///
///
fn offset_addr(inst: ir::Inst,
heap: ir::Heap,
addr_ty: ir::Type,
mut offset: ir::Value,
offset_ty: ir::Type,
func: &mut ir::Function) {
fn offset_addr(
inst: ir::Inst,
heap: ir::Heap,
addr_ty: ir::Type,
mut offset: ir::Value,
offset_ty: ir::Type,
func: &mut ir::Function,
) {
let mut pos = FuncCursor::new(func).at_inst(inst);
// Convert `offset` to `addr_ty`.

View File

@@ -66,9 +66,11 @@ pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, is
split::simplify_branch_arguments(&mut pos.func.dfg, inst);
}
match isa.encode(&pos.func.dfg,
&pos.func.dfg[inst],
pos.func.dfg.ctrl_typevar(inst)) {
match isa.encode(
&pos.func.dfg,
&pos.func.dfg[inst],
pos.func.dfg.ctrl_typevar(inst),
) {
Ok(encoding) => pos.func.encodings[inst] = encoding,
Err(action) => {
// We should transform the instruction into legal equivalents.

View File

@@ -71,21 +71,23 @@ use std::iter;
/// Split `value` into two values using the `isplit` semantics. Do this by reusing existing values
/// if possible.
pub fn isplit(dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
value: Value)
-> (Value, Value) {
pub fn isplit(
dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
value: Value,
) -> (Value, Value) {
split_any(dfg, cfg, pos, value, Opcode::Iconcat)
}
/// Split `value` into halves using the `vsplit` semantics. Do this by reusing existing values if
/// possible.
pub fn vsplit(dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
value: Value)
-> (Value, Value) {
pub fn vsplit(
dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
value: Value,
) -> (Value, Value) {
split_any(dfg, cfg, pos, value, Opcode::Vconcat)
}
@@ -107,12 +109,13 @@ struct Repair {
}
/// Generic version of `isplit` and `vsplit` controlled by the `concat` opcode.
fn split_any(dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
value: Value,
concat: Opcode)
-> (Value, Value) {
fn split_any(
dfg: &mut DataFlowGraph,
cfg: &ControlFlowGraph,
pos: &mut Cursor,
value: Value,
concat: Opcode,
) -> (Value, Value) {
let saved_pos = pos.position();
let mut repairs = Vec::new();
let result = split_value(dfg, pos, value, concat, &mut repairs);
@@ -121,17 +124,20 @@ fn split_any(dfg: &mut DataFlowGraph,
while let Some(repair) = repairs.pop() {
for &(_, inst) in cfg.get_predecessors(repair.ebb) {
let branch_opc = dfg[inst].opcode();
assert!(branch_opc.is_branch(),
"Predecessor not a branch: {}",
dfg.display_inst(inst, None));
assert!(
branch_opc.is_branch(),
"Predecessor not a branch: {}",
dfg.display_inst(inst, None)
);
let fixed_args = branch_opc.constraints().fixed_value_arguments();
let mut args = dfg[inst]
.take_value_list()
.expect("Branches must have value lists.");
let mut args = dfg[inst].take_value_list().expect(
"Branches must have value lists.",
);
let num_args = args.len(&dfg.value_lists);
// Get the old value passed to the EBB argument we're repairing.
let old_arg = args.get(fixed_args + repair.num, &dfg.value_lists)
.expect("Too few branch arguments");
let old_arg = args.get(fixed_args + repair.num, &dfg.value_lists).expect(
"Too few branch arguments",
);
// It's possible that the CFG's predecessor list has duplicates. Detect them here.
if dfg.value_type(old_arg) == repair.split_type {
@@ -145,19 +151,21 @@ fn split_any(dfg: &mut DataFlowGraph,
// The `lo` part replaces the original argument.
*args.get_mut(fixed_args + repair.num, &mut dfg.value_lists)
.unwrap() = lo;
.unwrap() = lo;
// The `hi` part goes at the end. Since multiple repairs may have been scheduled to the
// same EBB, there could be multiple arguments missing.
if num_args > fixed_args + repair.hi_num {
*args.get_mut(fixed_args + repair.hi_num, &mut dfg.value_lists)
.unwrap() = hi;
.unwrap() = hi;
} else {
// We need to append one or more arguments. If we're adding more than one argument,
// there must be pending repairs on the stack that will fill in the correct values
// instead of `hi`.
args.extend(iter::repeat(hi).take(1 + fixed_args + repair.hi_num - num_args),
&mut dfg.value_lists);
args.extend(
iter::repeat(hi).take(1 + fixed_args + repair.hi_num - num_args),
&mut dfg.value_lists,
);
}
// Put the value list back after manipulating it.
@@ -175,12 +183,13 @@ fn split_any(dfg: &mut DataFlowGraph,
/// instruction.
///
/// Return the two new values representing the parts of `value`.
fn split_value(dfg: &mut DataFlowGraph,
pos: &mut Cursor,
value: Value,
concat: Opcode,
repairs: &mut Vec<Repair>)
-> (Value, Value) {
fn split_value(
dfg: &mut DataFlowGraph,
pos: &mut Cursor,
value: Value,
concat: Opcode,
repairs: &mut Vec<Repair>,
) -> (Value, Value) {
let value = dfg.resolve_copies(value);
let mut reuse = None;
@@ -228,9 +237,12 @@ fn split_value(dfg: &mut DataFlowGraph,
// need to insert a split instruction before returning.
pos.goto_top(ebb);
pos.next_inst();
dfg.ins(pos)
.with_result(value)
.Binary(concat, split_type, lo, hi);
dfg.ins(pos).with_result(value).Binary(
concat,
split_type,
lo,
hi,
);
// Finally, splitting the EBB argument is not enough. We also have to repair all
// of the predecessor instructions that branch here.
@@ -254,19 +266,21 @@ fn split_value(dfg: &mut DataFlowGraph,
}
// Add a repair entry to the work list.
fn add_repair(concat: Opcode,
split_type: Type,
ebb: Ebb,
num: usize,
hi_num: usize,
repairs: &mut Vec<Repair>) {
fn add_repair(
concat: Opcode,
split_type: Type,
ebb: Ebb,
num: usize,
hi_num: usize,
repairs: &mut Vec<Repair>,
) {
repairs.push(Repair {
concat,
split_type,
ebb,
num,
hi_num,
});
concat,
split_type,
ebb,
num,
hi_num,
});
}
/// Strip concat-split chains. Return a simpler way of computing the same value.