From c9bbc1e86edb4364d22aa9671f0e6cd8942eeaba Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 19 Jul 2017 09:30:04 -0700 Subject: [PATCH] Don't require that the fallthrough instruction has an encoding. A fallthrough jump is actually represented as 0 bytes, so no encoding is needed. Also allow for unencoded instructions in the generated emit_inst implementations. The verifier has stricter rules for when this is allowed. --- cranelift/filetests/wasm/control.cton | 11 +++++++++++ lib/cretonne/meta/gen_binemit.py | 8 ++++++-- lib/cretonne/src/verifier/mod.rs | 8 +++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cranelift/filetests/wasm/control.cton b/cranelift/filetests/wasm/control.cton index f29c19b5c5..0e82b05245 100644 --- a/cranelift/filetests/wasm/control.cton +++ b/cranelift/filetests/wasm/control.cton @@ -32,3 +32,14 @@ ebb1(v2: i32): ebb2: jump ebb1(v0) } + +function %br_if_fallthrough(i32) -> i32 { +ebb0(v0: i32): + v1 = iconst.i32 1 + brz v0, ebb1(v1) + ; This jump gets converted to a fallthrough. + jump ebb1(v0) + +ebb1(v2: i32): + return v2 +} diff --git a/lib/cretonne/meta/gen_binemit.py b/lib/cretonne/meta/gen_binemit.py index 8e734c5ff1..fddadf64e5 100644 --- a/lib/cretonne/meta/gen_binemit.py +++ b/lib/cretonne/meta/gen_binemit.py @@ -135,14 +135,18 @@ def gen_isa(isa, fmt): 'pub fn emit_inst' '(func: &Function, inst: Inst, ' 'divert: &mut RegDiversions, sink: &mut CS) {', '}'): - fmt.line('let bits = func.encodings[inst].bits();') + fmt.line('let encoding = func.encodings[inst];') + fmt.line('let bits = encoding.bits();') with fmt.indented('match func.encodings[inst].recipe() {', '}'): for i, recipe in enumerate(isa.all_recipes): fmt.comment(recipe.name) with fmt.indented('{} => {{'.format(i), '}'): gen_recipe(recipe, fmt) fmt.line('_ => {}') - fmt.line('bad_encoding(func, inst);') + # Allow for un-encoded ghost instructions. + # Verifier checks the details. + with fmt.indented('if encoding.is_legal() {', '}'): + fmt.line('bad_encoding(func, inst);') def generate(isas, out_dir): diff --git a/lib/cretonne/src/verifier/mod.rs b/lib/cretonne/src/verifier/mod.rs index 2652579020..518c9a703f 100644 --- a/lib/cretonne/src/verifier/mod.rs +++ b/lib/cretonne/src/verifier/mod.rs @@ -57,7 +57,7 @@ use flowgraph::ControlFlowGraph; use ir::entities::AnyEntity; use ir::instructions::{InstructionFormat, BranchInfo, ResolvedConstraint, CallInfo}; use ir::{types, Function, ValueDef, Ebb, Inst, SigRef, FuncRef, ValueList, JumpTable, StackSlot, - Value, Type}; + Value, Type, Opcode}; use isa::TargetIsa; use std::error as std_error; use std::fmt::{self, Display, Formatter}; @@ -711,6 +711,12 @@ impl<'a> Verifier<'a> { // Instructions with side effects are not allowed to be ghost instructions. let opcode = self.func.dfg[inst].opcode(); + // The `fallthrough` instruction is marked as a terminator and a branch, but it is not + // required to have an encoding. + if opcode == Opcode::Fallthrough { + return Ok(()); + } + if opcode.is_branch() { return err!(inst, "Branch must have an encoding"); }