Repository: bytecodealliance/wasmtime
Pull request #8875 (2024-06-26 19:02:01)

Various cleanups to the ABI handling code
I originally did these in the process of adding exception support to Cranelift, but I've extracted it out that branch and rebased it as these changes should be less controversial and it will help with rebasing the exception support branch in the future.

github-actions[bot]: #### Subscribe to Label Action

cc @cfallin, @fitzgen, @saulecabrera

<details>
This issue or pull request has been labeled: "cranelift", "cranelift:area:aarch64", "cranelift:area:machinst", "cranelift:area:x64", "isle", "winch"

Thus the following users have been cc'd because of the following labels:

* cfallin: isle
* fitzgen: isle
* saulecabrera: winch

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

[Learn more.](https://github.com/bytecodealliance/subscribe-to-label-action)
</details>
jameysharp: I'm excited to take a look next week if nobody else gets to this first!
jameysharp: I tried to review this and got kind of lost. I really appreciate that there are nicely separated commits, but I think this would be easier to review if those were fully separate PRs, if that's not too much trouble? It would be especially helpful if you can explain more about the motivation for each change in the commit/PR description.
bjorn3: Split out https://github.com/bytecodealliance/wasmtime/pull/8903. I will rebase this PR once it merges.
bjorn3: Rebased

Patch:
diff --git a/Cargo.lock b/Cargo.lock
index b986ee3a8..516122c26 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1973,9 +1973,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
 
 [[package]]
 name = "openvino"
-version = "0.6.0"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24bd3a7ef39968e6a4f1b1206c1c876f9bd50cf739ccbcd69f8539bbac5dcc7a"
+checksum = "aee013796927eec6012a344f10ecdc06bf26de79c626a2395e3f115464907ef6"
 dependencies = [
  "openvino-finder",
  "openvino-sys",
@@ -1984,9 +1984,9 @@ dependencies = [
 
 [[package]]
 name = "openvino-finder"
-version = "0.6.0"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05d234d1394a413ea8adaf0c40806b9ad1946be6310b441f688840654a331973"
+checksum = "af4c6841df4cd60fef743015f3348f81b6b225bd255ed0c4cab6e8c479e45eaa"
 dependencies = [
  "cfg-if",
  "log",
@@ -1994,9 +1994,9 @@ dependencies = [
 
 [[package]]
 name = "openvino-sys"
-version = "0.6.0"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c98acf37fc84ad9d7da4dc6c18f0f60ad209b43a6f555be01f9003d0a2a43d"
+checksum = "f62fc2bd6882f2300a6b5017eaad292586d70995d333582aabcf1f1121cd147c"
 dependencies = [
  "env_logger",
  "libloading",
diff --git a/cranelift/codegen/src/isa/aarch64/abi.rs b/cranelift/codegen/src/isa/aarch64/abi.rs
index 922e4ebfc..ff1ccd972 100644
--- a/cranelift/codegen/src/isa/aarch64/abi.rs
+++ b/cranelift/codegen/src/isa/aarch64/abi.rs
@@ -4,7 +4,6 @@ use crate::ir;
 use crate::ir::types;
 use crate::ir::types::*;
 use crate::ir::MemFlags;
-use crate::ir::Opcode;
 use crate::ir::{dynamic_to_fixed, ExternalName, LibCall, Signature};
 use crate::isa;
 use crate::isa::aarch64::{inst::*, settings as aarch64_settings};
@@ -1019,7 +1018,6 @@ impl ABIMachineSpec for AArch64MachineDeps {
         uses: CallArgList,
         defs: CallRetList,
         clobbers: PRegSet,
-        opcode: ir::Opcode,
         tmp: Writable<Reg>,
         callee_conv: isa::CallConv,
         caller_conv: isa::CallConv,
@@ -1033,7 +1031,6 @@ impl ABIMachineSpec for AArch64MachineDeps {
                     uses,
                     defs,
                     clobbers,
-                    opcode,
                     caller_callconv: caller_conv,
                     callee_callconv: callee_conv,
                     callee_pop_size,
@@ -1051,7 +1048,6 @@ impl ABIMachineSpec for AArch64MachineDeps {
                         uses,
                         defs,
                         clobbers,
-                        opcode,
                         caller_callconv: caller_conv,
                         callee_callconv: callee_conv,
                         callee_pop_size,
@@ -1064,7 +1060,6 @@ impl ABIMachineSpec for AArch64MachineDeps {
                     uses,
                     defs,
                     clobbers,
-                    opcode,
                     caller_callconv: caller_conv,
                     callee_callconv: callee_conv,
                     callee_pop_size,
@@ -1107,7 +1102,6 @@ impl ABIMachineSpec for AArch64MachineDeps {
                 ],
                 defs: smallvec![],
                 clobbers: Self::get_regs_clobbered_by_call(call_conv),
-                opcode: Opcode::Call,
                 caller_callconv: call_conv,
                 callee_callconv: call_conv,
                 callee_pop_size: 0,
@@ -1299,11 +1293,9 @@ impl AArch64CallSite {
         self.emit_stack_ret_arg_for_tail_call(ctx);
 
         let dest = self.dest().clone();
-        let opcode = self.opcode();
         let uses = self.take_uses();
         let info = Box::new(ReturnCallInfo {
             uses,
-            opcode,
             new_stack_arg_size,
             key: select_api_key(isa_flags, isa::CallConv::Tail, true),
         });
diff --git a/cranelift/codegen/src/isa/aarch64/inst/emit.rs b/cranelift/codegen/src/isa/aarch64/inst/emit.rs
index d231a3280..de63d7cef 100644
--- a/cranelift/codegen/src/isa/aarch64/inst/emit.rs
+++ b/cranelift/codegen/src/isa/aarch64/inst/emit.rs
@@ -2945,9 +2945,7 @@ impl MachInstEmit for Inst {
                     let offset = sink.cur_offset();
                     sink.push_user_stack_map(state, offset, s);
                 }
-                if info.opcode.is_call() {
-                    sink.add_call_site(info.opcode);
-                }
+                sink.add_call_site();
 
                 if info.callee_pop_size > 0 {
                     let callee_pop_size =
@@ -2968,9 +2966,7 @@ impl MachInstEmit for Inst {
                     let offset = sink.cur_offset();
                     sink.push_user_stack_map(state, offset, s);
                 }
-                if info.opcode.is_call() {
-                    sink.add_call_site(info.opcode);
-                }
+                sink.add_call_site();
 
                 if info.callee_pop_size > 0 {
                     let callee_pop_size =
@@ -2991,7 +2987,7 @@ impl MachInstEmit for Inst {
                 // for the target, but rather a function relocation.
                 sink.add_reloc(Reloc::Arm64Call, &**callee, 0);
                 sink.put4(enc_jump26(0b000101, 0));
-                sink.add_call_site(ir::Opcode::ReturnCall);
+                sink.add_call_site();
 
                 // `emit_return_call_common_sequence` emits an island if
                 // necessary, so we can safely disable the worst-case-size check
@@ -3006,7 +3002,7 @@ impl MachInstEmit for Inst {
                     targets: vec![],
                 }
                 .emit(sink, emit_info, state);
-                sink.add_call_site(ir::Opcode::ReturnCallIndirect);
+                sink.add_call_site();
 
                 // `emit_return_call_common_sequence` emits an island if
                 // necessary, so we can safely disable the worst-case-size check
@@ -3398,7 +3394,6 @@ impl MachInstEmit for Inst {
                         uses: smallvec![],
                         defs: smallvec![],
                         clobbers: PRegSet::empty(),
-                        opcode: Opcode::CallIndirect,
                         caller_callconv: CallConv::SystemV,
                         callee_callconv: CallConv::SystemV,
                         callee_pop_size: 0,
@@ -3459,7 +3454,6 @@ impl MachInstEmit for Inst {
                         uses: smallvec![],
                         defs: smallvec![],
                         clobbers: PRegSet::empty(),
-                        opcode: Opcode::CallIndirect,
                         caller_callconv: CallConv::AppleAarch64,
                         callee_callconv: CallConv::AppleAarch64,
                         callee_pop_size: 0,
diff --git a/cranelift/codegen/src/isa/aarch64/inst/mod.rs b/cranelift/codegen/src/isa/aarch64/inst/mod.rs
index 3098c4c98..8bb7c8529 100644
--- a/cranelift/codegen/src/isa/aarch64/inst/mod.rs
+++ b/cranelift/codegen/src/isa/aarch64/inst/mod.rs
@@ -2,7 +2,7 @@
 
 use crate::binemit::{Addend, CodeOffset, Reloc};
 use crate::ir::types::{F32, F64, I128, I16, I32, I64, I8, I8X16, R32, R64};
-use crate::ir::{types, ExternalName, MemFlags, Opcode, Type};
+use crate::ir::{types, ExternalName, MemFlags, Type};
 use crate::isa::{CallConv, FunctionAlignment};
 use crate::machinst::*;
 use crate::{settings, CodegenError, CodegenResult};
@@ -86,8 +86,6 @@ pub struct CallInfo {
     pub defs: CallRetList,
     /// Clobbers register set.
     pub clobbers: PRegSet,
-    /// Instruction opcode.
-    pub opcode: Opcode,
     /// Caller calling convention.
     pub caller_callconv: CallConv,
     /// Callee calling convention.
@@ -110,8 +108,6 @@ pub struct CallIndInfo {
     pub defs: SmallVec<[CallRetPair; 8]>,
     /// Clobbers register set.
     pub clobbers: PRegSet,
-    /// Instruction opcode.
-    pub opcode: Opcode,
     /// Caller calling convention.
     pub caller_callconv: CallConv,
     /// Callee calling convention.
@@ -128,8 +124,6 @@ pub struct CallIndInfo {
 pub struct ReturnCallInfo {
     /// Arguments to the call instruction.
     pub uses: CallArgList,
-    /// Instruction opcode.
-    pub opcode: Opcode,
     /// The size of the new stack frame's stack arguments. This is necessary
     /// for copying the frame over our current frame. It must already be
     /// allocated on the stack.
diff --git a/cranelift/codegen/src/isa/aarch64/lower/isle.rs b/cranelift/codegen/src/isa/aarch64/lower/isle.rs
index 88bbee635..0191e7cd5 100644
--- a/cranelift/codegen/src/isa/aarch64/lower/isle.rs
+++ b/cranelift/codegen/src/isa/aarch64/lower/isle.rs
@@ -27,7 +27,9 @@ use crate::{
     isa::aarch64::abi::AArch64CallSite,
     isa::aarch64::inst::args::{ShiftOp, ShiftOpShiftImm},
     isa::aarch64::inst::SImm7Scaled,
-    machinst::{abi::ArgPair, ty_bits, InstOutput, MachInst, VCodeConstant, VCodeConstantData},
+    machinst::{
+        abi::ArgPair, ty_bits, InstOutput, IsTailCall, MachInst, VCodeConstant, VCodeConstantData,
+    },
 };
 use regalloc2::PReg;
 use std::boxed::Box;
@@ -94,7 +96,7 @@ impl Context for IsleContext<'_, '_, MInst, AArch64Backend> {
             self.lower_ctx.sigs(),
             callee_sig,
             &callee,
-            Opcode::ReturnCall,
+            IsTailCall::Yes,
             distance,
             caller_conv,
             self.backend.flags().clone(),
@@ -123,7 +125,7 @@ impl Context for IsleContext<'_, '_, MInst, AArch64Backend> {
             self.lower_ctx.sigs(),
             callee_sig,
             callee,
-            Opcode::ReturnCallIndirect,
+            IsTailCall::Yes,
             caller_conv,
             self.backend.flags().clone(),
         );
diff --git a/cranelift/codegen/src/isa/riscv64/abi.rs b/cranelift/codegen/src/isa/riscv64/abi.rs
index 05f3f3a45..2a6b23f3a 100644
--- a/cranelift/codegen/src/isa/riscv64/abi.rs
+++ b/cranelift/codegen/src/isa/riscv64/abi.rs
@@ -433,7 +433,6 @@ impl ABIMachineSpec for Riscv64MachineDeps {
                 }],
                 defs: smallvec![],
                 clobbers: PRegSet::empty(),
-                opcode: Opcode::Call,
                 callee_callconv: CallConv::SystemV,
                 caller_callconv: CallConv::SystemV,
                 callee_pop_size: 0,
@@ -573,7 +572,6 @@ impl ABIMachineSpec for Riscv64MachineDeps {
         uses: CallArgList,
         defs: CallRetList,
         clobbers: PRegSet,
-        opcode: ir::Opcode,
         tmp: Writable<Reg>,
         callee_conv: isa::CallConv,
         caller_conv: isa::CallConv,
@@ -587,7 +585,6 @@ impl ABIMachineSpec for Riscv64MachineDeps {
                     uses,
                     defs,
                     clobbers,
-                    opcode,
                     caller_callconv: caller_conv,
                     callee_callconv: callee_conv,
                     callee_pop_size,
@@ -605,7 +602,6 @@ impl ABIMachineSpec for Riscv64MachineDeps {
                         uses,
                         defs,
                         clobbers,
-                        opcode,
                         caller_callconv: caller_conv,
                         callee_callconv: callee_conv,
                         callee_pop_size,
@@ -618,7 +614,6 @@ impl ABIMachineSpec for Riscv64MachineDeps {
                     uses,
                     defs,
                     clobbers,
-                    opcode,
                     caller_callconv: caller_conv,
                     callee_callconv: callee_conv,
                     callee_pop_size,
@@ -660,7 +655,6 @@ impl ABIMachineSpec for Riscv64MachineDeps {
                 ],
                 defs: smallvec![],
                 clobbers: Self::get_regs_clobbered_by_call(call_conv),
-                opcode: Opcode::Call,
                 caller_callconv: call_conv,
                 callee_callconv: call_conv,
                 callee_pop_size: 0,
@@ -778,11 +772,9 @@ impl Riscv64ABICallSite {
         self.emit_stack_ret_arg_for_tail_call(ctx);
 
         let dest = self.dest().clone();
-        let opcode = self.opcode();
         let uses = self.take_uses();
         let info = Box::new(ReturnCallInfo {
             uses,
-            opcode,
             new_stack_arg_size,
         });
 
diff --git a/cranelift/codegen/src/isa/riscv64/inst/emit.rs b/cranelift/codegen/src/isa/riscv64/inst/emit.rs
index fb63c355f..ea279b4f4 100644
--- a/cranelift/codegen/src/isa/riscv64/inst/emit.rs
+++ b/cranelift/codegen/src/isa/riscv64/inst/emit.rs
@@ -1144,9 +1144,7 @@ impl Inst {
             }
 
             &Inst::Call { ref info } => {
-                if info.opcode.is_call() {
-                    sink.add_call_site(info.opcode);
-                }
+                sink.add_call_site();
                 sink.add_reloc(Reloc::RiscvCallPlt, &info.dest, 0);
 
                 let (stack_map, user_stack_map) = state.take_stack_map();
@@ -1189,9 +1187,7 @@ impl Inst {
                     sink.push_user_stack_map(state, offset, s);
                 }
 
-                if info.opcode.is_call() {
-                    sink.add_call_site(info.opcode);
-                }
+                sink.add_call_site();
 
                 let callee_pop_size = i32::try_from(info.callee_pop_size).unwrap();
                 if callee_pop_size > 0 {
@@ -1207,7 +1203,7 @@ impl Inst {
             } => {
                 emit_return_call_common_sequence(sink, emit_info, state, info);
 
-                sink.add_call_site(ir::Opcode::ReturnCall);
+                sink.add_call_site();
                 sink.add_reloc(Reloc::RiscvCallPlt, &**callee, 0);
                 Inst::construct_auipc_and_jalr(None, writable_spilltmp_reg(), 0)
                     .into_iter()
@@ -2037,7 +2033,6 @@ impl Inst {
                         dest: ExternalName::LibCall(LibCall::ElfTlsGetAddr),
                         uses: smallvec![],
                         defs: smallvec![],
-                        opcode: crate::ir::Opcode::TlsValue,
                         caller_callconv: CallConv::SystemV,
                         callee_callconv: CallConv::SystemV,
                         callee_pop_size: 0,
diff --git a/cranelift/codegen/src/isa/riscv64/inst/mod.rs b/cranelift/codegen/src/isa/riscv64/inst/mod.rs
index f80ca99e2..80bd149b7 100644
--- a/cranelift/codegen/src/isa/riscv64/inst/mod.rs
+++ b/cranelift/codegen/src/isa/riscv64/inst/mod.rs
@@ -5,7 +5,7 @@ use crate::binemit::{Addend, CodeOffset, Reloc};
 pub use crate::ir::condcodes::IntCC;
 use crate::ir::types::{self, F32, F64, I128, I16, I32, I64, I8, I8X16, R32, R64};
 
-pub use crate::ir::{ExternalName, MemFlags, Opcode, Type};
+pub use crate::ir::{ExternalName, MemFlags, Type};
 use crate::isa::{CallConv, FunctionAlignment};
 use crate::machinst::*;
 use crate::{settings, CodegenError, CodegenResult};
@@ -58,7 +58,6 @@ pub struct CallInfo {
     pub dest: ExternalName,
     pub uses: CallArgList,
     pub defs: CallRetList,
-    pub opcode: Opcode,
     pub caller_callconv: CallConv,
     pub callee_callconv: CallConv,
     pub clobbers: PRegSet,
@@ -72,7 +71,6 @@ pub struct CallIndInfo {
     pub rn: Reg,
     pub uses: CallArgList,
     pub defs: CallRetList,
-    pub opcode: Opcode,
     pub caller_callconv: CallConv,
     pub callee_callconv: CallConv,
     pub clobbers: PRegSet,
@@ -84,7 +82,6 @@ pub struct CallIndInfo {
 #[derive(Clone, Debug)]
 pub struct ReturnCallInfo {
     pub uses: CallArgList,
-    pub opcode: Opcode,
     pub new_stack_arg_size: u32,
 }
 
diff --git a/cranelift/codegen/src/isa/riscv64/lower/isle.rs b/cranelift/codegen/src/isa/riscv64/lower/isle.rs
index 5da02a48c..5695700f4 100644
--- a/cranelift/codegen/src/isa/riscv64/lower/isle.rs
+++ b/cranelift/codegen/src/isa/riscv64/lower/isle.rs
@@ -21,7 +21,7 @@ use crate::{
         MemFlags, Opcode, TrapCode, Value, ValueList,
     },
     isa::riscv64::inst::*,
-    machinst::{ArgPair, InstOutput},
+    machinst::{ArgPair, InstOutput, IsTailCall},
 };
 use crate::{isa, isle_common_prelude_methods};
 use regalloc2::PReg;
@@ -79,7 +79,7 @@ impl generated_code::Context for RV64IsleContext<'_, '_, MInst, Riscv64Backend>
             self.lower_ctx.sigs(),
             callee_sig,
             &callee,
-            Opcode::ReturnCall,
+            IsTailCall::Yes,
             distance,
             caller_conv,
             self.backend.flags().clone(),
@@ -108,7 +108,7 @@ impl generated_code::Context for RV64IsleContext<'_, '_, MInst, Riscv64Backend>
             self.lower_ctx.sigs(),
             callee_sig,
             callee,
-            Opcode::ReturnCallIndirect,
+            IsTailCall::Yes,
             caller_conv,
             self.backend.flags().clone(),
         );
diff --git a/cranelift/codegen/src/isa/s390x/abi.rs b/cranelift/codegen/src/isa/s390x/abi.rs
index 16375be8b..dc01aa0fb 100644
--- a/cranelift/codegen/src/isa/s390x/abi.rs
+++ b/cranelift/codegen/src/isa/s390x/abi.rs
@@ -733,7 +733,6 @@ impl ABIMachineSpec for S390xMachineDeps {
         _uses: CallArgList,
         _defs: CallRetList,
         _clobbers: PRegSet,
-        _opcode: ir::Opcode,
         _tmp: Writable<Reg>,
         _callee_conv: isa::CallConv,
         _caller_conv: isa::CallConv,
diff --git a/cranelift/codegen/src/isa/s390x/inst.isle b/cranelift/codegen/src/isa/s390x/inst.isle
index bc0529abf..7f4599741 100644
--- a/cranelift/codegen/src/isa/s390x/inst.isle
+++ b/cranelift/codegen/src/isa/s390x/inst.isle
@@ -3535,22 +3535,22 @@
 (decl abi_first_ret (SigRef Sig) usize)
 (extern constructor abi_first_ret abi_first_ret)
 
-(decl abi_call_info (Sig ExternalName CallArgList CallRetList Opcode) BoxCallInfo)
+(decl abi_call_info (Sig ExternalName CallArgList CallRetList) BoxCallInfo)
 (extern constructor abi_call_info abi_call_info)
 
-(decl abi_call_ind_info (Sig Reg CallArgList CallRetList Opcode) BoxCallIndInfo)
+(decl abi_call_ind_info (Sig Reg CallArgList CallRetList) BoxCallIndInfo)
 (extern constructor abi_call_ind_info abi_call_ind_info)
 
 (decl writable_link_reg () WritableReg)
 (rule (writable_link_reg) (writable_gpr 14))
 
-(decl abi_call (Sig ExternalName CallArgList CallRetList Opcode) SideEffectNoResult)
-(rule (abi_call abi name uses defs opcode)
-      (call_impl (writable_link_reg) (abi_call_info abi name uses defs opcode)))
+(decl abi_call (Sig ExternalName CallArgList CallRetList) SideEffectNoResult)
+(rule (abi_call abi name uses defs)
+      (call_impl (writable_link_reg) (abi_call_info abi name uses defs)))
 
-(decl abi_call_ind (Sig Reg CallArgList CallRetList Opcode) SideEffectNoResult)
-(rule (abi_call_ind abi target uses defs opcode)
-      (call_ind_impl (writable_link_reg) (abi_call_ind_info abi target uses defs opcode)))
+(decl abi_call_ind (Sig Reg CallArgList CallRetList) SideEffectNoResult)
+(rule (abi_call_ind abi target uses defs)
+      (call_ind_impl (writable_link_reg) (abi_call_ind_info abi target uses defs)))
 
 (decl abi_accumulate_outgoing_args_size (Sig) Unit)
 (extern constructor abi_accumulate_outgoing_args_size abi_accumulate_outgoing_args_size)
diff --git a/cranelift/codegen/src/isa/s390x/inst/emit.rs b/cranelift/codegen/src/isa/s390x/inst/emit.rs
index 5c72b887e..dace88c89 100644
--- a/cranelift/codegen/src/isa/s390x/inst/emit.rs
+++ b/cranelift/codegen/src/isa/s390x/inst/emit.rs
@@ -3267,9 +3267,7 @@ impl Inst {
                 }
 
                 put(sink, &enc_ril_b(opcode, link.to_reg(), 0));
-                if info.opcode.is_call() {
-                    sink.add_call_site(info.opcode);
-                }
+                sink.add_call_site();
             }
             &Inst::CallInd { link, ref info } => {
                 debug_assert_eq!(link.to_reg(), gpr(14));
@@ -3286,9 +3284,7 @@ impl Inst {
 
                 let opcode = 0x0d; // BASR
                 put(sink, &enc_rr(opcode, link.to_reg(), rn));
-                if info.opcode.is_call() {
-                    sink.add_call_site(info.opcode);
-                }
+                sink.add_call_site();
             }
             &Inst::Args { .. } => {}
             &Inst::Rets { .. } => {}
diff --git a/cranelift/codegen/src/isa/s390x/inst/mod.rs b/cranelift/codegen/src/isa/s390x/inst/mod.rs
index 6b1d9f531..05a36e098 100644
--- a/cranelift/codegen/src/isa/s390x/inst/mod.rs
+++ b/cranelift/codegen/src/isa/s390x/inst/mod.rs
@@ -1,14 +1,14 @@
 //! This module defines s390x-specific machine instruction types.
 
 use crate::binemit::{Addend, CodeOffset, Reloc};
-use crate::ir::{types, ExternalName, Opcode, Type};
+use crate::ir::{types, ExternalName, Type};
 use crate::isa::s390x::abi::S390xMachineDeps;
 use crate::isa::{CallConv, FunctionAlignment};
 use crate::machinst::*;
 use crate::{settings, CodegenError, CodegenResult};
 use alloc::boxed::Box;
 use alloc::vec::Vec;
-use regalloc2::PRegSet;
+use regalloc2::{PReg, PRegSet};
 use smallvec::SmallVec;
 use std::fmt::Write;
 use std::string::{String, ToString};
@@ -42,7 +42,6 @@ pub struct CallInfo {
     pub uses: CallArgList,
     pub defs: CallRetList,
     pub clobbers: PRegSet,
-    pub opcode: Opcode,
     pub caller_callconv: CallConv,
     pub callee_callconv: CallConv,
     pub tls_symbol: Option<SymbolReloc>,
@@ -56,7 +55,6 @@ pub struct CallIndInfo {
     pub uses: CallArgList,
     pub defs: CallRetList,
     pub clobbers: PRegSet,
-    pub opcode: Opcode,
     pub caller_callconv: CallConv,
     pub callee_callconv: CallConv,
 }
@@ -885,28 +883,41 @@ fn s390x_get_operands(inst: &mut Inst, collector: &mut DenyReuseVisitor<impl Ope
             collector.reg_use(rn);
         }
         Inst::Call { link, info } => {
-            let CallInfo { uses, defs, .. } = &mut **info;
+            let CallInfo {
+                uses,
+                defs,
+                clobbers,
+                ..
+            } = &mut **info;
             for CallArgPair { vreg, preg } in uses {
                 collector.reg_fixed_use(vreg, *preg);
             }
+            let mut clobbers = clobbers.clone();
+            clobbers.add(link.to_reg().to_real_reg().unwrap().into());
             for CallRetPair { vreg, preg } in defs {
+                clobbers.remove(PReg::from(preg.to_real_reg().unwrap()));
                 collector.reg_fixed_def(vreg, *preg);
             }
-            let mut clobbers = info.clobbers.clone();
-            clobbers.add(link.to_reg().to_real_reg().unwrap().into());
             collector.reg_clobbers(clobbers);
         }
         Inst::CallInd { link, info } => {
-            let CallIndInfo { rn, uses, defs, .. } = &mut **info;
+            let CallIndInfo {
+                rn,
+                uses,
+                defs,
+                clobbers,
+                ..
+            } = &mut **info;
             collector.reg_use(rn);
             for CallArgPair { vreg, preg } in uses {
                 collector.reg_fixed_use(vreg, *preg);
             }
+            let mut clobbers = clobbers.clone();
+            clobbers.add(link.to_reg().to_real_reg().unwrap().into());
             for CallRetPair { vreg, preg } in defs {
+                clobbers.remove(PReg::from(preg.to_real_reg().unwrap()));
                 collector.reg_fixed_def(vreg, *preg);
             }
-            let mut clobbers = info.clobbers.clone();
-            clobbers.add(link.to_reg().to_real_reg().unwrap().into());
             collector.reg_clobbers(clobbers);
         }
         Inst::Args { args } => {
diff --git a/cranelift/codegen/src/isa/s390x/lower.isle b/cranelift/codegen/src/isa/s390x/lower.isle
index 977a28c02..c04d3fd8c 100644
--- a/cranelift/codegen/src/isa/s390x/lower.isle
+++ b/cranelift/codegen/src/isa/s390x/lower.isle
@@ -3900,7 +3900,7 @@
             (_ Unit (abi_accumulate_outgoing_args_size abi))
             (uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args))
             (defs CallRetList (defs_init abi))
-            (_ InstOutput (side_effect (abi_call abi name uses defs (Opcode.Call)))))
+            (_ InstOutput (side_effect (abi_call abi name uses defs))))
         (lower_call_rets abi defs (range (abi_first_ret sig_ref abi)
                                          (abi_num_rets abi)) (output_builder_new))))
 
@@ -3911,7 +3911,7 @@
             (uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args))
             (defs CallRetList (defs_init abi))
             (target Reg (load_symbol_reloc (SymbolReloc.Absolute name 0)))
-            (_ InstOutput (side_effect (abi_call_ind abi target uses defs (Opcode.Call)))))
+            (_ InstOutput (side_effect (abi_call_ind abi target uses defs))))
         (lower_call_rets abi defs (range (abi_first_ret sig_ref abi)
                                          (abi_num_rets abi)) (output_builder_new))))
 
@@ -3922,7 +3922,7 @@
             (_ Unit (abi_accumulate_outgoing_args_size abi))
             (uses CallArgList (lower_call_args abi (range 0 (abi_num_args abi)) args))
             (defs CallRetList (defs_init abi))
-            (_ InstOutput (side_effect (abi_call_ind abi target uses defs (Opcode.CallIndirect)))))
+            (_ InstOutput (side_effect (abi_call_ind abi target uses defs))))
         (lower_call_rets abi defs (range (abi_first_ret sig_ref abi)
                                          (abi_num_rets abi)) (output_builder_new))))
 
diff --git a/cranelift/codegen/src/isa/s390x/lower/isle.rs b/cranelift/codegen/src/isa/s390x/lower/isle.rs
index 17b55d0fa..f2937856b 100644
--- a/cranelift/codegen/src/isa/s390x/lower/isle.rs
+++ b/cranelift/codegen/src/isa/s390x/lower/isle.rs
@@ -193,15 +193,16 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, S390xBackend> {
         name: ExternalName,
         uses: &CallArgList,
         defs: &CallRetList,
-        opcode: &Opcode,
     ) -> BoxCallInfo {
-        let clobbers = self.lower_ctx.sigs().call_clobbers::<S390xMachineDeps>(abi);
+        let sig_data = &self.lower_ctx.sigs()[abi];
+        // Get clobbers: all caller-saves. These may include return value
+        // regs, which we will remove from the clobber set later.
+        let clobbers = S390xMachineDeps::get_regs_clobbered_by_call(sig_data.call_conv());
         Box::new(CallInfo {
             dest: name.clone(),
             uses: uses.clone(),
             defs: defs.clone(),
             clobbers,
-            opcode: *opcode,
             caller_callconv: self.lower_ctx.abi().call_conv(self.lower_ctx.sigs()),
             callee_callconv: self.lower_ctx.sigs()[abi].call_conv(),
             tls_symbol: None,
@@ -214,15 +215,16 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, S390xBackend> {
         target: Reg,
         uses: &CallArgList,
         defs: &CallRetList,
-        opcode: &Opcode,
     ) -> BoxCallIndInfo {
-        let clobbers = self.lower_ctx.sigs().call_clobbers::<S390xMachineDeps>(abi);
+        let sig_data = &self.lower_ctx.sigs()[abi];
+        // Get clobbers: all caller-saves. These may include return value
+        // regs, which we will remove from the clobber set later.
+        let clobbers = S390xMachineDeps::get_regs_clobbered_by_call(sig_data.call_conv());
         Box::new(CallIndInfo {
             rn: target,
             uses: uses.clone(),
             defs: defs.clone(),
             clobbers,
-            opcode: *opcode,
             caller_callconv: self.lower_ctx.abi().call_conv(self.lower_ctx.sigs()),
             callee_callconv: self.lower_ctx.sigs()[abi].call_conv(),
         })
@@ -288,18 +290,14 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, S390xBackend> {
         let caller_callconv = self.lower_ctx.abi().call_conv(self.lower_ctx.sigs());
         let callee_callconv = CallConv::for_libcall(&self.backend.flags, caller_callconv);
 
-        // Clobbers are defined by the calling convention.  Remove defs from clobbers.
-        let mut clobbers = S390xMachineDeps::get_regs_clobbered_by_call(callee_callconv);
-        for reg in &info.defs {
-            clobbers.remove(PReg::from(reg.preg.to_real_reg().unwrap()));
-        }
+        // Clobbers are defined by the calling convention. We will remove return value regs later.
+        let clobbers = S390xMachineDeps::get_regs_clobbered_by_call(callee_callconv);
 
         Box::new(CallInfo {
             dest: ExternalName::LibCall(info.libcall),
             uses: info.uses.clone(),
             defs: info.defs.clone(),
             clobbers,
-            opcode: Opcode::Call,
             caller_callconv,
             callee_callconv,
             tls_symbol: info.tls_symbol.clone(),
diff --git a/cranelift/codegen/src/isa/x64/abi.rs b/cranelift/codegen/src/isa/x64/abi.rs
index 6deb81b52..10d71f7aa 100644
--- a/cranelift/codegen/src/isa/x64/abi.rs
+++ b/cranelift/codegen/src/isa/x64/abi.rs
@@ -1,6 +1,6 @@
 //! Implementation of the standard x64 ABI.
 
-use crate::ir::{self, types, LibCall, MemFlags, Opcode, Signature, TrapCode};
+use crate::ir::{self, types, LibCall, MemFlags, Signature, TrapCode};
 use crate::ir::{types::*, ExternalName};
 use crate::isa;
 use crate::isa::{unwind::UnwindInst, x64::inst::*, x64::settings as x64_settings, CallConv};
@@ -591,7 +591,6 @@ impl ABIMachineSpec for X64ABIMachineSpec {
             Writable::from_reg(regs::rax()),
         ));
         insts.push(Inst::CallKnown {
-            opcode: Opcode::Call,
             dest: ExternalName::LibCall(LibCall::Probestack),
             info: Some(Box::new(CallInfo {
                 // No need to include arg here: we are post-regalloc
@@ -802,7 +801,6 @@ impl ABIMachineSpec for X64ABIMachineSpec {
         uses: CallArgList,
         defs: CallRetList,
         clobbers: PRegSet,
-        opcode: ir::Opcode,
         tmp: Writable<Reg>,
         callee_conv: isa::CallConv,
         _caller_conv: isa::CallConv,
@@ -816,7 +814,6 @@ impl ABIMachineSpec for X64ABIMachineSpec {
                     uses,
                     defs,
                     clobbers,
-                    opcode,
                     callee_pop_size,
                     callee_conv,
                 ));
@@ -833,7 +830,6 @@ impl ABIMachineSpec for X64ABIMachineSpec {
                     uses,
                     defs,
                     clobbers,
-                    opcode,
                     callee_pop_size,
                     callee_conv,
                 ));
@@ -844,7 +840,6 @@ impl ABIMachineSpec for X64ABIMachineSpec {
                     uses,
                     defs,
                     clobbers,
-                    opcode,
                     callee_pop_size,
                     callee_conv,
                 ));
@@ -896,7 +891,6 @@ impl ABIMachineSpec for X64ABIMachineSpec {
             ],
             /* defs = */ smallvec![],
             /* clobbers = */ Self::get_regs_clobbered_by_call(call_conv),
-            Opcode::Call,
             callee_pop_size,
             call_conv,
         ));
diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle
index bae6e211c..56a03c51c 100644
--- a/cranelift/codegen/src/isa/x64/inst.isle
+++ b/cranelift/codegen/src/isa/x64/inst.isle
@@ -532,12 +532,10 @@
 
        ;; Direct call: call simm32.
        (CallKnown (dest ExternalName)
-                  (opcode Opcode)
                   (info BoxCallInfo))
 
        ;; Indirect call: callq (reg mem)
        (CallUnknown (dest RegMem)
-                    (opcode Opcode)
                     (info BoxCallInfo))
 
        ;; Tail call to a direct destination.
diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs
index dd5dfc002..25534059d 100644
--- a/cranelift/codegen/src/isa/x64/inst/emit.rs
+++ b/cranelift/codegen/src/isa/x64/inst/emit.rs
@@ -1,4 +1,3 @@
-use crate::ir;
 use crate::ir::immediates::{Ieee32, Ieee64};
 use crate::ir::KnownSymbol;
 use crate::isa::x64::encoding::evex::{EvexInstruction, EvexVectorLength, RegisterOrAmode};
@@ -1596,8 +1595,8 @@ pub(crate) fn emit(
 
         Inst::CallKnown {
             dest,
-            opcode,
             info: call_info,
+            ..
         } => {
             let (stack_map, user_stack_map) = state.take_stack_map();
             if let Some(s) = stack_map {
@@ -1613,9 +1612,7 @@ pub(crate) fn emit(
             // beginning of the immediate field.
             emit_reloc(sink, Reloc::X86CallPCRel4, &dest, -4);
             sink.put4(0);
-            if opcode.is_call() {
-                sink.add_call_site(*opcode);
-            }
+            sink.add_call_site();
 
             // Reclaim the outgoing argument area that was released by the callee, to ensure that
             // StackAMode values are always computed from a consistent SP.
@@ -1648,7 +1645,7 @@ pub(crate) fn emit(
             // beginning of the immediate field.
             emit_reloc(sink, Reloc::X86CallPCRel4, &callee, -4);
             sink.put4(0);
-            sink.add_call_site(ir::Opcode::ReturnCall);
+            sink.add_call_site();
         }
 
         Inst::ReturnCallUnknown {
@@ -1663,13 +1660,13 @@ pub(crate) fn emit(
                 target: RegMem::reg(callee),
             }
             .emit(sink, info, state);
-            sink.add_call_site(ir::Opcode::ReturnCallIndirect);
+            sink.add_call_site();
         }
 
         Inst::CallUnknown {
             dest,
-            opcode,
             info: call_info,
+            ..
         } => {
             let dest = dest.clone();
 
@@ -1712,9 +1709,7 @@ pub(crate) fn emit(
                 sink.push_user_stack_map(state, offset, s);
             }
 
-            if opcode.is_call() {
-                sink.add_call_site(*opcode);
-            }
+            sink.add_call_site();
 
             // Reclaim the outgoing argument area that was released by the callee, to ensure that
             // StackAMode values are always computed from a consistent SP.
diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs
index fd8c375e6..ee79de792 100644
--- a/cranelift/codegen/src/isa/x64/inst/mod.rs
+++ b/cranelift/codegen/src/isa/x64/inst/mod.rs
@@ -3,7 +3,7 @@
 pub use emit_state::EmitState;
 
 use crate::binemit::{Addend, CodeOffset, Reloc, StackMap};
-use crate::ir::{types, ExternalName, LibCall, Opcode, TrapCode, Type};
+use crate::ir::{types, ExternalName, LibCall, TrapCode, Type};
 use crate::isa::x64::abi::X64ABIMachineSpec;
 use crate::isa::x64::inst::regs::{pretty_print_reg, show_ireg_sized};
 use crate::isa::x64::settings as x64_settings;
@@ -541,13 +541,11 @@ impl Inst {
         uses: CallArgList,
         defs: CallRetList,
         clobbers: PRegSet,
-        opcode: Opcode,
         callee_pop_size: u32,
         callee_conv: CallConv,
     ) -> Inst {
         Inst::CallKnown {
             dest,
-            opcode,
             info: Some(Box::new(CallInfo {
                 uses,
                 defs,
@@ -563,14 +561,12 @@ impl Inst {
         uses: CallArgList,
         defs: CallRetList,
         clobbers: PRegSet,
-        opcode: Opcode,
         callee_pop_size: u32,
         callee_conv: CallConv,
     ) -> Inst {
         dest.assert_regclass_is(RegClass::Int);
         Inst::CallUnknown {
             dest,
-            opcode,
             info: Some(Box::new(CallInfo {
                 uses,
                 defs,
diff --git a/cranelift/codegen/src/isa/x64/lower/isle.rs b/cranelift/codegen/src/isa/x64/lower/isle.rs
index b858eb800..f5a4f8f61 100644
--- a/cranelift/codegen/src/isa/x64/lower/isle.rs
+++ b/cranelift/codegen/src/isa/x64/lower/isle.rs
@@ -22,8 +22,8 @@ use crate::{
         inst::{args::*, regs, CallInfo, ReturnCallInfo},
     },
     machinst::{
-        isle::*, ArgPair, InsnInput, InstOutput, MachAtomicRmwOp, MachInst, VCodeConstant,
-        VCodeConstantData,
+        isle::*, ArgPair, InsnInput, InstOutput, IsTailCall, MachAtomicRmwOp, MachInst,
+        VCodeConstant, VCodeConstantData,
     },
 };
 use alloc::vec::Vec;
@@ -91,7 +91,7 @@ impl Context for IsleContext<'_, '_, MInst, X64Backend> {
             self.lower_ctx.sigs(),
             callee_sig,
             callee,
-            Opcode::ReturnCallIndirect,
+            IsTailCall::Yes,
             caller_conv,
             self.backend.flags().clone(),
         );
@@ -118,7 +118,7 @@ impl Context for IsleContext<'_, '_, MInst, X64Backend> {
             self.lower_ctx.sigs(),
             callee_sig,
             &callee,
-            Opcode::ReturnCall,
+            IsTailCall::Yes,
             distance,
             caller_conv,
             self.backend.flags().clone(),
diff --git a/cranelift/codegen/src/machinst/abi.rs b/cranelift/codegen/src/machinst/abi.rs
index 0b8ddd478..b5bee22ec 100644
--- a/cranelift/codegen/src/machinst/abi.rs
+++ b/cranelift/codegen/src/machinst/abi.rs
@@ -546,7 +546,6 @@ pub trait ABIMachineSpec {
         uses: CallArgList,
         defs: CallRetList,
         clobbers: PRegSet,
-        opcode: ir::Opcode,
         tmp: Writable<Reg>,
         callee_conv: isa::CallConv,
         caller_conv: isa::CallConv,
@@ -890,39 +889,6 @@ impl SigSet {
         self.rets(sig)[idx].clone()
     }
 
-    /// Return all clobbers for the callsite.
-    pub fn call_clobbers<M: ABIMachineSpec>(&self, sig: Sig) -> PRegSet {
-        let sig_data = &self.sigs[sig];
-        // Get clobbers: all caller-saves. These may include return value
-        // regs, which we will remove from the clobber set below.
-        let mut clobbers = M::get_regs_clobbered_by_call(sig_data.call_conv);
-
-        // Remove retval regs from clobbers. Skip StructRets: these
-        // are not, semantically, returns at the CLIF level, so we
-        // treat such a value as a clobber instead.
-        for ret in self.rets(sig) {
-            if let &ABIArg::Slots {
-                ref slots, purpose, ..
-            } = ret
-            {
-                if purpose == ir::ArgumentPurpose::StructReturn {
-                    continue;
-                }
-                for slot in slots {
-                    match slot {
-                        &ABIArgSlot::Reg { reg, .. } => {
-                            crate::trace!("call_clobbers: retval reg {:?}", reg);
-                            clobbers.remove(PReg::from(reg));
-                        }
-                        _ => {}
-                    }
-                }
-            }
-        }
-
-        clobbers
-    }
-
     /// Get the number of arguments expected.
     pub fn num_args(&self, sig: Sig) -> usize {
         let len = self.args(sig).len();
@@ -1956,6 +1922,11 @@ pub struct CallRetPair {
 pub type CallArgList = SmallVec<[CallArgPair; 8]>;
 pub type CallRetList = SmallVec<[CallRetPair; 8]>;
 
+pub enum IsTailCall {
+    Yes,
+    No,
+}
+
 /// ABI object for a callsite.
 pub struct CallSite<M: ABIMachineSpec> {
     /// The called function's signature.
@@ -1965,12 +1936,9 @@ pub struct CallSite<M: ABIMachineSpec> {
     uses: CallArgList,
     /// All defs for the callsite, i.e., return values.
     defs: CallRetList,
-    /// Caller-save clobbers.
-    clobbers: PRegSet,
     /// Call destination.
     dest: CallDest,
-    /// Actual call opcode; used to distinguish various types of calls.
-    opcode: ir::Opcode,
+    is_tail_call: IsTailCall,
     /// Caller's calling convention.
     caller_conv: isa::CallConv,
     /// The settings controlling this compilation.
@@ -1994,20 +1962,18 @@ impl<M: ABIMachineSpec> CallSite<M> {
         sigs: &SigSet,
         sig_ref: ir::SigRef,
         extname: &ir::ExternalName,
-        opcode: ir::Opcode,
+        is_tail_call: IsTailCall,
         dist: RelocDistance,
         caller_conv: isa::CallConv,
         flags: settings::Flags,
     ) -> CallSite<M> {
         let sig = sigs.abi_sig_for_sig_ref(sig_ref);
-        let clobbers = sigs.call_clobbers::<M>(sig);
         CallSite {
             sig,
             uses: smallvec![],
             defs: smallvec![],
-            clobbers,
             dest: CallDest::ExtName(extname.clone(), dist),
-            opcode,
+            is_tail_call,
             caller_conv,
             flags,
             _mach: PhantomData,
@@ -2025,14 +1991,12 @@ impl<M: ABIMachineSpec> CallSite<M> {
         flags: settings::Flags,
     ) -> CallSite<M> {
         let sig = sigs.abi_sig_for_signature(sig);
-        let clobbers = sigs.call_clobbers::<M>(sig);
         CallSite {
             sig,
             uses: smallvec![],
             defs: smallvec![],
-            clobbers,
             dest: CallDest::ExtName(extname.clone(), dist),
-            opcode: ir::Opcode::Call,
+            is_tail_call: IsTailCall::No,
             caller_conv,
             flags,
             _mach: PhantomData,
@@ -2045,19 +2009,17 @@ impl<M: ABIMachineSpec> CallSite<M> {
         sigs: &SigSet,
         sig_ref: ir::SigRef,
         ptr: Reg,
-        opcode: ir::Opcode,
+        is_tail_call: IsTailCall,
         caller_conv: isa::CallConv,
         flags: settings::Flags,
     ) -> CallSite<M> {
         let sig = sigs.abi_sig_for_sig_ref(sig_ref);
-        let clobbers = sigs.call_clobbers::<M>(sig);
         CallSite {
             sig,
             uses: smallvec![],
             defs: smallvec![],
-            clobbers,
             dest: CallDest::Reg(ptr),
-            opcode,
+            is_tail_call,
             caller_conv,
             flags,
             _mach: PhantomData,
@@ -2068,10 +2030,6 @@ impl<M: ABIMachineSpec> CallSite<M> {
         &self.dest
     }
 
-    pub(crate) fn opcode(&self) -> ir::Opcode {
-        self.opcode
-    }
-
     pub(crate) fn take_uses(self) -> CallArgList {
         self.uses
     }
@@ -2081,10 +2039,7 @@ impl<M: ABIMachineSpec> CallSite<M> {
     }
 
     pub(crate) fn is_tail_call(&self) -> bool {
-        matches!(
-            self.opcode,
-            ir::Opcode::ReturnCall | ir::Opcode::ReturnCallIndirect
-        )
+        matches!(self.is_tail_call, IsTailCall::Yes)
     }
 }
 
@@ -2382,6 +2337,18 @@ impl<M: ABIMachineSpec> CallSite<M> {
 
         let uses = mem::take(&mut self.uses);
         let defs = mem::take(&mut self.defs);
+        let clobbers = {
+            // Get clobbers: all caller-saves. These may include return value
+            // regs, which we will remove from the clobber set below.
+            let mut clobbers = <M>::get_regs_clobbered_by_call(ctx.sigs()[self.sig].call_conv);
+
+            // Remove retval regs from clobbers.
+            for def in &defs {
+                clobbers.remove(PReg::from(def.preg.to_real_reg().unwrap()));
+            }
+
+            clobbers
+        };
 
         let sig = &ctx.sigs()[self.sig];
         let callee_pop_size = if sig.call_conv() == isa::CallConv::Tail {
@@ -2413,8 +2380,7 @@ impl<M: ABIMachineSpec> CallSite<M> {
             &self.dest,
             uses,
             defs,
-            self.clobbers,
-            self.opcode,
+            clobbers,
             tmp,
             call_conv,
             self.caller_conv,
diff --git a/cranelift/codegen/src/machinst/buffer.rs b/cranelift/codegen/src/machinst/buffer.rs
index c02b8596d..5b631334b 100644
--- a/cranelift/codegen/src/machinst/buffer.rs
+++ b/cranelift/codegen/src/machinst/buffer.rs
@@ -172,7 +172,7 @@
 
 use crate::binemit::{Addend, CodeOffset, Reloc, StackMap};
 use crate::ir::function::FunctionParameters;
-use crate::ir::{ExternalName, Opcode, RelSourceLoc, SourceLoc, TrapCode};
+use crate::ir::{ExternalName, RelSourceLoc, SourceLoc, TrapCode};
 use crate::isa::unwind::UnwindInst;
 use crate::machinst::{
     BlockIndex, MachInstLabelUse, TextSectionBuilder, VCodeConstant, VCodeConstants, VCodeInst,
@@ -1620,14 +1620,9 @@ impl<I: VCodeInst> MachBuffer<I> {
     }
 
     /// Add a call-site record at the current offset.
-    pub fn add_call_site(&mut self, opcode: Opcode) {
-        debug_assert!(
-            opcode.is_call(),
-            "adding call site info for a non-call instruction."
-        );
+    pub fn add_call_site(&mut self) {
         self.call_sites.push(MachCallSite {
             ret_addr: self.data.len() as CodeOffset,
-            opcode,
         });
     }
 
@@ -1939,8 +1934,6 @@ pub struct MachTrap {
 pub struct MachCallSite {
     /// The offset of the call's return address, *relative to the containing section*.
     pub ret_addr: CodeOffset,
-    /// The call's opcode.
-    pub opcode: Opcode,
 }
 
 /// A source-location mapping resulting from a compilation.
@@ -2498,7 +2491,7 @@ mod test {
         buf.put1(2);
         buf.add_trap(TrapCode::IntegerOverflow);
         buf.add_trap(TrapCode::IntegerDivisionByZero);
-        buf.add_call_site(Opcode::Call);
+        buf.add_call_site();
         buf.add_reloc(
             Reloc::Abs4,
             &ExternalName::User(UserExternalNameRef::new(0)),
@@ -2529,9 +2522,9 @@ mod test {
         assert_eq!(
             buf.call_sites()
                 .iter()
-                .map(|call_site| (call_site.ret_addr, call_site.opcode))
+                .map(|call_site| call_site.ret_addr)
                 .collect::<Vec<_>>(),
-            vec![(2, Opcode::Call)]
+            vec![2]
         );
         assert_eq!(
             buf.relocs()
diff --git a/cranelift/codegen/src/machinst/isle.rs b/cranelift/codegen/src/machinst/isle.rs
index da3462a7c..54d88e249 100644
--- a/cranelift/codegen/src/machinst/isle.rs
+++ b/cranelift/codegen/src/machinst/isle.rs
@@ -762,7 +762,7 @@ macro_rules! isle_prelude_caller_methods {
                 self.lower_ctx.sigs(),
                 sig_ref,
                 &extname,
-                Opcode::Call,
+                IsTailCall::No,
                 dist,
                 caller_conv,
                 self.backend.flags().clone(),
@@ -790,7 +790,7 @@ macro_rules! isle_prelude_caller_methods {
                 self.lower_ctx.sigs(),
                 sig_ref,
                 ptr,
-                Opcode::CallIndirect,
+                IsTailCall::No,
                 caller_conv,
                 self.backend.flags().clone(),
             );
diff --git a/crates/wasi-nn/Cargo.toml b/crates/wasi-nn/Cargo.toml
index a5ace788d..371e721dd 100644
--- a/crates/wasi-nn/Cargo.toml
+++ b/crates/wasi-nn/Cargo.toml
@@ -29,7 +29,7 @@ wasmtime = { workspace = true, features = [
 # These dependencies are necessary for the wasi-nn implementation:
 tracing = { workspace = true }
 thiserror = { workspace = true }
-openvino = { version = "0.6.0", features = [
+openvino = { version = "0.7.2", features = [
     "runtime-linking",
 ], optional = true }
 
diff --git a/crates/wasi-nn/src/backend/mod.rs b/crates/wasi-nn/src/backend/mod.rs
index 710c93b98..0409ddf52 100644
--- a/crates/wasi-nn/src/backend/mod.rs
+++ b/crates/wasi-nn/src/backend/mod.rs
@@ -107,6 +107,8 @@ pub enum BackendError {
     InvalidNumberOfBuilders(usize, usize),
     #[error("Not enough memory to copy tensor data of size: {0}")]
     NotEnoughMemory(usize),
+    #[error("Unsupported tensor type: {0}")]
+    UnsupportedTensorType(String),
 }
 
 /// Read a file into a byte vector.
diff --git a/crates/wasi-nn/src/backend/openvino.rs b/crates/wasi-nn/src/backend/openvino.rs
index b24f93838..8be15bd25 100644
--- a/crates/wasi-nn/src/backend/openvino.rs
+++ b/crates/wasi-nn/src/backend/openvino.rs
@@ -3,9 +3,9 @@
 use super::{
     read, BackendError, BackendExecutionContext, BackendFromDir, BackendGraph, BackendInner, Id,
 };
-use crate::wit::{self, ExecutionTarget, GraphEncoding, Tensor, TensorType};
+use crate::wit::{ExecutionTarget, GraphEncoding, Tensor, TensorType};
 use crate::{ExecutionContext, Graph};
-use openvino::{InferenceError, Layout, Precision, SetupError, TensorDesc};
+use openvino::{DeviceType, ElementType, InferenceError, SetupError, Shape, Tensor as OvTensor};
 use std::path::Path;
 use std::sync::{Arc, Mutex};
 
@@ -23,41 +23,33 @@ impl BackendInner for OpenvinoBackend {
         if builders.len() != 2 {
             return Err(BackendError::InvalidNumberOfBuilders(2, builders.len()).into());
         }
-
         // Construct the context if none is present; this is done lazily (i.e.
         // upon actually loading a model) because it may fail to find and load
         // the OpenVINO libraries. The laziness limits the extent of the error
         // only to wasi-nn users, not all WASI users.
         if self.0.is_none() {
-            self.0.replace(openvino::Core::new(None)?);
+            self.0.replace(openvino::Core::new()?);
         }
-
         // Read the guest array.
-        let xml = &builders[0];
-        let weights = &builders[1];
+        let xml = builders[0];
+        let weights = builders[1];
 
-        // Construct OpenVINO graph structures: `cnn_network` contains the graph
-        // structure, `exec_network` can perform inference.
+        // Construct a new tensor for the model weights.
+        let shape = Shape::new(&[1, weights.len() as i64])?;
+        let mut weights_tensor = OvTensor::new(ElementType::U8, &shape)?;
+        let buffer = weights_tensor.get_raw_data_mut()?;
+        buffer.copy_from_slice(&weights);
+
+        // Construct OpenVINO graph structures: `model` contains the graph
+        // structure, `compiled_model` can perform inference.
         let core = self
             .0
             .as_mut()
             .expect("openvino::Core was previously constructed");
-        let mut cnn_network = core.read_network_from_buffer(&xml, &weights)?;
-
-        // TODO: this is a temporary workaround. We need a more elegant way to
-        // specify the layout in the long run. However, without this newer
-        // versions of OpenVINO will fail due to parameter mismatch.
-        for i in 0..cnn_network.get_inputs_len()? {
-            let name = cnn_network.get_input_name(i)?;
-            cnn_network.set_input_layout(&name, Layout::NHWC)?;
-        }
-
-        let exec_network =
-            core.load_network(&cnn_network, map_execution_target_to_string(target))?;
-        let box_: Box<dyn BackendGraph> = Box::new(OpenvinoGraph(
-            Arc::new(cnn_network),
-            Arc::new(Mutex::new(exec_network)),
-        ));
+        let model = core.read_model_from_buffer(&xml, Some(&weights_tensor))?;
+        let compiled_model = core.compile_model(&model, target.into())?;
+        let box_: Box<dyn BackendGraph> =
+            Box::new(OpenvinoGraph(Arc::new(Mutex::new(compiled_model))));
         Ok(box_.into())
     }
 
@@ -78,63 +70,62 @@ impl BackendFromDir for OpenvinoBackend {
     }
 }
 
-struct OpenvinoGraph(
-    Arc<openvino::CNNNetwork>,
-    Arc<Mutex<openvino::ExecutableNetwork>>,
-);
+struct OpenvinoGraph(Arc<Mutex<openvino::CompiledModel>>);
 
 unsafe impl Send for OpenvinoGraph {}
 unsafe impl Sync for OpenvinoGraph {}
 
 impl BackendGraph for OpenvinoGraph {
     fn init_execution_context(&self) -> Result<ExecutionContext, BackendError> {
-        let mut network = self.1.lock().unwrap();
-        let infer_request = network.create_infer_request()?;
+        let mut compiled_model = self.0.lock().unwrap();
+        let infer_request = compiled_model.create_infer_request()?;
         let box_: Box<dyn BackendExecutionContext> =
-            Box::new(OpenvinoExecutionContext(self.0.clone(), infer_request));
+            Box::new(OpenvinoExecutionContext(infer_request));
         Ok(box_.into())
     }
 }
 
-struct OpenvinoExecutionContext(Arc<openvino::CNNNetwork>, openvino::InferRequest);
+struct OpenvinoExecutionContext(openvino::InferRequest);
 
 impl BackendExecutionContext for OpenvinoExecutionContext {
     fn set_input(&mut self, id: Id, tensor: &Tensor) -> Result<(), BackendError> {
-        let input_name = match id {
-            Id::Index(i) => self.0.get_input_name(i as usize)?,
-            Id::Name(name) => name,
-        };
-
-        // Construct the blob structure. TODO: there must be some good way to
-        // discover the layout here; `desc` should not have to default to NHWC.
-        let precision = map_tensor_type_to_precision(tensor.ty);
+        // Construct the tensor.
+        let precision = tensor.ty.into();
         let dimensions = tensor
             .dimensions
             .iter()
-            .map(|&d| d as usize)
+            .map(|&d| d as i64)
             .collect::<Vec<_>>();
-        let desc = TensorDesc::new(Layout::NHWC, &dimensions, precision);
-        let blob = openvino::Blob::new(&desc, &tensor.data)?;
-
-        // Actually assign the blob to the request.
-        self.1.set_blob(&input_name, &blob)?;
+        let shape = Shape::new(&dimensions)?;
+        let mut new_tensor = OvTensor::new(precision, &shape)?;
+        let buffer = new_tensor.get_raw_data_mut()?;
+        buffer.copy_from_slice(&tensor.data);
+        // Assign the tensor to the request.
+        match id {
+            Id::Index(i) => self.0.set_input_tensor_by_index(i as usize, &new_tensor)?,
+            Id::Name(name) => self.0.set_tensor(&name, &new_tensor)?,
+        };
         Ok(())
     }
 
     fn compute(&mut self) -> Result<(), BackendError> {
-        self.1.infer()?;
+        self.0.infer()?;
         Ok(())
     }
 
     fn get_output(&mut self, id: Id) -> Result<Tensor, BackendError> {
         let output_name = match id {
-            Id::Index(i) => self.0.get_output_name(i as usize)?,
-            Id::Name(name) => name,
+            Id::Index(i) => self.0.get_output_tensor_by_index(i as usize)?,
+            Id::Name(name) => self.0.get_tensor(&name)?,
         };
-        let dimensions = vec![]; // TODO: get actual shape
-        let ty = wit::TensorType::Fp32; // TODO: get actual type.
-        let blob = self.1.get_blob(&output_name)?;
-        let data = blob.buffer()?.to_vec();
+        let dimensions = output_name
+            .get_shape()?
+            .get_dimensions()
+            .iter()
+            .map(|&dim| dim as u32)
+            .collect::<Vec<u32>>();
+        let ty = output_name.get_element_type()?.try_into()?;
+        let data = output_name.get_raw_data()?.to_vec();
         Ok(Tensor {
             dimensions,
             ty,
@@ -157,24 +148,49 @@ impl From<SetupError> for BackendError {
 
 /// Return the execution target string expected by OpenVINO from the
 /// `ExecutionTarget` enum provided by wasi-nn.
-fn map_execution_target_to_string(target: ExecutionTarget) -> &'static str {
-    match target {
-        ExecutionTarget::Cpu => "CPU",
-        ExecutionTarget::Gpu => "GPU",
-        ExecutionTarget::Tpu => unimplemented!("OpenVINO does not support TPU execution targets"),
+impl From<ExecutionTarget> for DeviceType<'static> {
+    fn from(target: ExecutionTarget) -> Self {
+        match target {
+            ExecutionTarget::Cpu => DeviceType::CPU,
+            ExecutionTarget::Gpu => DeviceType::GPU,
+            ExecutionTarget::Tpu => {
+                unimplemented!("OpenVINO does not support TPU execution targets")
+            }
+        }
     }
 }
 
 /// Return OpenVINO's precision type for the `TensorType` enum provided by
 /// wasi-nn.
-fn map_tensor_type_to_precision(tensor_type: TensorType) -> openvino::Precision {
-    match tensor_type {
-        TensorType::Fp16 => Precision::FP16,
-        TensorType::Fp32 => Precision::FP32,
-        TensorType::Fp64 => Precision::FP64,
-        TensorType::U8 => Precision::U8,
-        TensorType::I32 => Precision::I32,
-        TensorType::I64 => Precision::I64,
-        TensorType::Bf16 => todo!("not yet supported in `openvino` bindings"),
+impl From<TensorType> for ElementType {
+    fn from(tensor_type: TensorType) -> Self {
+        match tensor_type {
+            TensorType::Fp16 => ElementType::F16,
+            TensorType::Fp32 => ElementType::F32,
+            TensorType::Fp64 => ElementType::F64,
+            TensorType::U8 => ElementType::U8,
+            TensorType::I32 => ElementType::I32,
+            TensorType::I64 => ElementType::I64,
+            TensorType::Bf16 => ElementType::Bf16,
+        }
+    }
+}
+
+/// Return the `TensorType` enum provided by wasi-nn for OpenVINO's precision type
+impl TryFrom<ElementType> for TensorType {
+    type Error = BackendError;
+    fn try_from(element_type: ElementType) -> Result<Self, Self::Error> {
+        match element_type {
+            ElementType::F16 => Ok(TensorType::Fp16),
+            ElementType::F32 => Ok(TensorType::Fp32),
+            ElementType::F64 => Ok(TensorType::Fp64),
+            ElementType::U8 => Ok(TensorType::U8),
+            ElementType::I32 => Ok(TensorType::I32),
+            ElementType::I64 => Ok(TensorType::I64),
+            ElementType::Bf16 => Ok(TensorType::Bf16),
+            _ => Err(BackendError::UnsupportedTensorType(
+                element_type.to_string(),
+            )),
+        }
     }
 }
diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml
index 7cc1fa51a..65d4f780c 100644
--- a/supply-chain/audits.toml
+++ b/supply-chain/audits.toml
@@ -2109,6 +2109,11 @@ who = "Iceber Gu <caiwei95@hotmail.com>"
 criteria = "safe-to-deploy"
 delta = "0.5.0 -> 0.6.0"
 
+[[audits.openvino]]
+who = "Andrew Brown <andrew.brown@intel.com>"
+criteria = "safe-to-deploy"
+delta = "0.6.0 -> 0.7.2"
+
 [[audits.openvino-finder]]
 who = "Matthew Tamayo-Rios <matthew@geekbeast.com>"
 criteria = "safe-to-deploy"
@@ -2127,6 +2132,11 @@ who = "Iceber Gu <caiwei95@hotmail.com>"
 criteria = "safe-to-deploy"
 delta = "0.5.0 -> 0.6.0"
 
+[[audits.openvino-finder]]
+who = "Andrew Brown <andrew.brown@intel.com>"
+criteria = "safe-to-deploy"
+delta = "0.6.0 -> 0.7.2"
+
 [[audits.openvino-sys]]
 who = "Matthew Tamayo-Rios <matthew@geekbeast.com>"
 criteria = "safe-to-deploy"
@@ -2145,6 +2155,11 @@ who = "Iceber Gu <caiwei95@hotmail.com>"
 criteria = "safe-to-deploy"
 delta = "0.5.0 -> 0.6.0"
 
+[[audits.openvino-sys]]
+who = "Andrew Brown <andrew.brown@intel.com>"
+criteria = "safe-to-deploy"
+delta = "0.6.0 -> 0.7.2"
+
 [[audits.ort]]
 who = "Andrew Brown <andrew.brown@intel.com>"
 criteria = "safe-to-deploy"
diff --git a/winch/codegen/src/isa/x64/asm.rs b/winch/codegen/src/isa/x64/asm.rs
index 85a994c6f..40e804956 100644
--- a/winch/codegen/src/isa/x64/asm.rs
+++ b/winch/codegen/src/isa/x64/asm.rs
@@ -6,7 +6,7 @@ use crate::{
 };
 use cranelift_codegen::{
     ir::{
-        types, ConstantPool, ExternalName, LibCall, MemFlags, Opcode, SourceLoc, TrapCode,
+        types, ConstantPool, ExternalName, LibCall, MemFlags, SourceLoc, TrapCode,
         UserExternalNameRef,
     },
     isa::{
@@ -1251,7 +1251,6 @@ impl Assembler {
     pub fn call_with_reg(&mut self, callee: Reg) {
         self.emit(Inst::CallUnknown {
             dest: RegMem::reg(callee.into()),
-            opcode: Opcode::Call,
             info: None,
         });
     }
@@ -1259,11 +1258,7 @@ impl Assembler {
     /// Emit a call to a locally defined function through an index.
     pub fn call_with_name(&mut self, name: UserExternalNameRef) {
         let dest = ExternalName::user(name);
-        self.emit(Inst::CallKnown {
-            dest,
-            opcode: Opcode::Call,
-            info: None,
-        });
+        self.emit(Inst::CallKnown { dest, info: None });
     }
 
     /// Emit a call to a well-known libcall.


Test patch:
diff --git a/cranelift/codegen/src/isa/aarch64/inst/emit_tests.rs b/cranelift/codegen/src/isa/aarch64/inst/emit_tests.rs
index f4448b64b..8b9eea9f0 100644
--- a/cranelift/codegen/src/isa/aarch64/inst/emit_tests.rs
+++ b/cranelift/codegen/src/isa/aarch64/inst/emit_tests.rs
@@ -6061,7 +6061,6 @@ fn test_aarch64_binemit() {
                 uses: smallvec![],
                 defs: smallvec![],
                 clobbers: PRegSet::empty(),
-                opcode: Opcode::Call,
                 caller_callconv: CallConv::SystemV,
                 callee_callconv: CallConv::SystemV,
                 callee_pop_size: 0,
@@ -6078,7 +6077,6 @@ fn test_aarch64_binemit() {
                 uses: smallvec![],
                 defs: smallvec![],
                 clobbers: PRegSet::empty(),
-                opcode: Opcode::CallIndirect,
                 caller_callconv: CallConv::SystemV,
                 callee_callconv: CallConv::SystemV,
                 callee_pop_size: 0,
diff --git a/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs b/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs
index 4732a6173..7051f8d67 100644
--- a/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs
+++ b/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs
@@ -6989,7 +6989,6 @@ fn test_s390x_binemit() {
                 uses: smallvec![],
                 defs: smallvec![],
                 clobbers: PRegSet::empty(),
-                opcode: Opcode::Call,
                 caller_callconv: CallConv::SystemV,
                 callee_callconv: CallConv::SystemV,
                 tls_symbol: None,
@@ -7007,7 +7006,6 @@ fn test_s390x_binemit() {
                 uses: smallvec![],
                 defs: smallvec![],
                 clobbers: PRegSet::empty(),
-                opcode: Opcode::CallIndirect,
                 caller_callconv: CallConv::SystemV,
                 callee_callconv: CallConv::SystemV,
             }),
diff --git a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs
index 9a7993586..2b53fae95 100644
--- a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs
+++ b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs
@@ -3762,7 +3762,6 @@ fn test_x64_emit() {
             smallvec![],
             smallvec![],
             PRegSet::default(),
-            Opcode::Call,
             0,
             CallConv::SystemV,
         ),
@@ -3778,7 +3777,6 @@ fn test_x64_emit() {
             smallvec![],
             smallvec![],
             PRegSet::default(),
-            Opcode::CallIndirect,
             0,
             CallConv::SystemV,
         )
diff --git a/crates/wasi-nn/tests/check/openvino.rs b/crates/wasi-nn/tests/check/openvino.rs
index fccdc678d..4bf05ba09 100644
--- a/crates/wasi-nn/tests/check/openvino.rs
+++ b/crates/wasi-nn/tests/check/openvino.rs
@@ -4,8 +4,12 @@ use std::fs;
 
 /// Return `Ok` if we find a working OpenVINO installation.
 pub fn is_installed() -> Result<()> {
-    match std::panic::catch_unwind(|| println!("> found openvino version: {}", openvino::version()))
-    {
+    match std::panic::catch_unwind(|| {
+        println!(
+            "> found openvino version: {}",
+            openvino::version().build_number
+        )
+    }) {
         Ok(_) => Ok(()),
         Err(e) => bail!(
             "unable to find an OpenVINO installation: {:?}",