Remove most of cranelift-serde
This commit is contained in:
@@ -18,7 +18,7 @@ clap = "2.32.0"
|
|||||||
serde = "1.0.8"
|
serde = "1.0.8"
|
||||||
serde_derive = "1.0.75"
|
serde_derive = "1.0.75"
|
||||||
serde_json = "1.0.26"
|
serde_json = "1.0.26"
|
||||||
cranelift-codegen = { path = "../codegen", version = "0.70.0" }
|
cranelift-codegen = { path = "../codegen", version = "0.70.0", features = ["enable-serde"] }
|
||||||
cranelift-reader = { path = "../reader", version = "0.70.0" }
|
cranelift-reader = { path = "../reader", version = "0.70.0" }
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
|
|||||||
@@ -22,23 +22,21 @@
|
|||||||
)]
|
)]
|
||||||
|
|
||||||
use clap::{App, Arg, SubCommand};
|
use clap::{App, Arg, SubCommand};
|
||||||
|
use cranelift_codegen::ir::Function;
|
||||||
use cranelift_reader::parse_functions;
|
use cranelift_reader::parse_functions;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::process;
|
use std::process;
|
||||||
|
|
||||||
mod serde_clif_json;
|
|
||||||
|
|
||||||
fn call_ser(file: &str, pretty: bool) -> Result<(), String> {
|
fn call_ser(file: &str, pretty: bool) -> Result<(), String> {
|
||||||
let ret_of_parse = parse_functions(file);
|
let ret_of_parse = parse_functions(file);
|
||||||
match ret_of_parse {
|
match ret_of_parse {
|
||||||
Ok(funcs) => {
|
Ok(funcs) => {
|
||||||
let ser_funcs = serde_clif_json::SerObj::new(&funcs);
|
|
||||||
let ser_str = if pretty {
|
let ser_str = if pretty {
|
||||||
serde_json::to_string_pretty(&ser_funcs).unwrap()
|
serde_json::to_string_pretty(&funcs).unwrap()
|
||||||
} else {
|
} else {
|
||||||
serde_json::to_string(&ser_funcs).unwrap()
|
serde_json::to_string(&funcs).unwrap()
|
||||||
};
|
};
|
||||||
println!("{}", ser_str);
|
println!("{}", ser_str);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -48,7 +46,7 @@ fn call_ser(file: &str, pretty: bool) -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_de(file: &File) -> Result<(), String> {
|
fn call_de(file: &File) -> Result<(), String> {
|
||||||
let de: serde_clif_json::SerObj = match serde_json::from_reader(file) {
|
let de: Vec<Function> = match serde_json::from_reader(file) {
|
||||||
Result::Ok(val) => val,
|
Result::Ok(val) => val,
|
||||||
Result::Err(err) => panic!("{}", err),
|
Result::Err(err) => panic!("{}", err),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,978 +0,0 @@
|
|||||||
use cranelift_codegen::ir::{Block, Function, Inst, InstructionData, Signature};
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
/// Serializable version of the original Cranelift IR
|
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub enum SerInstData {
|
|
||||||
Unary {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
},
|
|
||||||
UnaryImm {
|
|
||||||
opcode: String,
|
|
||||||
imm: String,
|
|
||||||
},
|
|
||||||
UnaryIeee32 {
|
|
||||||
opcode: String,
|
|
||||||
imm: String,
|
|
||||||
},
|
|
||||||
UnaryIeee64 {
|
|
||||||
opcode: String,
|
|
||||||
imm: String,
|
|
||||||
},
|
|
||||||
UnaryBool {
|
|
||||||
opcode: String,
|
|
||||||
imm: bool,
|
|
||||||
},
|
|
||||||
UnaryGlobalValue {
|
|
||||||
opcode: String,
|
|
||||||
global_value: String,
|
|
||||||
},
|
|
||||||
Binary {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 2],
|
|
||||||
},
|
|
||||||
BinaryImm8 {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
imm: String,
|
|
||||||
},
|
|
||||||
BinaryImm64 {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
imm: String,
|
|
||||||
},
|
|
||||||
Ternary {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 3],
|
|
||||||
},
|
|
||||||
TernaryImm8 {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 2],
|
|
||||||
imm: String,
|
|
||||||
},
|
|
||||||
MultiAry {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
},
|
|
||||||
NullAry {
|
|
||||||
opcode: String,
|
|
||||||
},
|
|
||||||
Shuffle {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 2],
|
|
||||||
mask: String,
|
|
||||||
},
|
|
||||||
IntCompare {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 2],
|
|
||||||
cond: String,
|
|
||||||
},
|
|
||||||
IntCompareImm {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
cond: String,
|
|
||||||
imm: String,
|
|
||||||
},
|
|
||||||
IntCond {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
cond: String,
|
|
||||||
},
|
|
||||||
FloatCompare {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 2],
|
|
||||||
cond: String,
|
|
||||||
},
|
|
||||||
FloatCond {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
cond: String,
|
|
||||||
},
|
|
||||||
IntSelect {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 3],
|
|
||||||
cond: String,
|
|
||||||
},
|
|
||||||
Jump {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
destination: String,
|
|
||||||
},
|
|
||||||
Branch {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
destination: String,
|
|
||||||
},
|
|
||||||
BranchInt {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
cond: String,
|
|
||||||
destination: String,
|
|
||||||
},
|
|
||||||
BranchFloat {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
cond: String,
|
|
||||||
destination: String,
|
|
||||||
},
|
|
||||||
BranchIcmp {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
cond: String,
|
|
||||||
destination: String,
|
|
||||||
},
|
|
||||||
BranchTable {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
destination: String,
|
|
||||||
table: String,
|
|
||||||
},
|
|
||||||
BranchTableEntry {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 2],
|
|
||||||
imm: String,
|
|
||||||
table: String,
|
|
||||||
},
|
|
||||||
BranchTableBase {
|
|
||||||
opcode: String,
|
|
||||||
table: String,
|
|
||||||
},
|
|
||||||
IndirectJump {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
table: String,
|
|
||||||
},
|
|
||||||
Call {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
func_ref: String,
|
|
||||||
},
|
|
||||||
CallIndirect {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
sig_ref: String,
|
|
||||||
},
|
|
||||||
FuncAddr {
|
|
||||||
opcode: String,
|
|
||||||
func_ref: String,
|
|
||||||
},
|
|
||||||
Load {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
flags: String,
|
|
||||||
offset: String,
|
|
||||||
},
|
|
||||||
LoadComplex {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
flags: String,
|
|
||||||
offset: String,
|
|
||||||
},
|
|
||||||
Store {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 2],
|
|
||||||
flags: String,
|
|
||||||
offset: String,
|
|
||||||
},
|
|
||||||
StoreComplex {
|
|
||||||
opcode: String,
|
|
||||||
args: Vec<String>,
|
|
||||||
flags: String,
|
|
||||||
offset: String,
|
|
||||||
},
|
|
||||||
StackLoad {
|
|
||||||
opcode: String,
|
|
||||||
stack_slot: String,
|
|
||||||
offset: String,
|
|
||||||
},
|
|
||||||
StackStore {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
stack_slot: String,
|
|
||||||
offset: String,
|
|
||||||
},
|
|
||||||
HeapAddr {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
heap: String,
|
|
||||||
imm: String,
|
|
||||||
},
|
|
||||||
TableAddr {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
table: String,
|
|
||||||
offset: String,
|
|
||||||
},
|
|
||||||
RegMove {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
src: String,
|
|
||||||
dst: String,
|
|
||||||
},
|
|
||||||
CopySpecial {
|
|
||||||
opcode: String,
|
|
||||||
src: String,
|
|
||||||
dst: String,
|
|
||||||
},
|
|
||||||
CopyToSsa {
|
|
||||||
opcode: String,
|
|
||||||
src: String,
|
|
||||||
},
|
|
||||||
RegSpill {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
src: String,
|
|
||||||
dst: String,
|
|
||||||
},
|
|
||||||
RegFill {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
src: String,
|
|
||||||
dst: String,
|
|
||||||
},
|
|
||||||
Trap {
|
|
||||||
opcode: String,
|
|
||||||
code: String,
|
|
||||||
},
|
|
||||||
CondTrap {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
code: String,
|
|
||||||
},
|
|
||||||
IntCondTrap {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
cond: String,
|
|
||||||
code: String,
|
|
||||||
},
|
|
||||||
FloatCondTrap {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
cond: String,
|
|
||||||
code: String,
|
|
||||||
},
|
|
||||||
AtomicCas {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 3],
|
|
||||||
flags: String,
|
|
||||||
},
|
|
||||||
AtomicRmw {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 2],
|
|
||||||
flags: String,
|
|
||||||
op: String,
|
|
||||||
},
|
|
||||||
LoadNoOffset {
|
|
||||||
opcode: String,
|
|
||||||
arg: String,
|
|
||||||
flags: String,
|
|
||||||
},
|
|
||||||
StoreNoOffset {
|
|
||||||
opcode: String,
|
|
||||||
args: [String; 2],
|
|
||||||
flags: String,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert Cranelift IR instructions to JSON format.
|
|
||||||
pub fn get_inst_data(inst_index: Inst, func: &Function) -> SerInstData {
|
|
||||||
let inst = &func.dfg[inst_index];
|
|
||||||
match *inst {
|
|
||||||
InstructionData::Unary { opcode, arg } => SerInstData::Unary {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::UnaryImm { opcode, imm } => SerInstData::UnaryImm {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
imm: imm.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::UnaryIeee32 { opcode, imm } => SerInstData::UnaryIeee32 {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
imm: imm.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::UnaryIeee64 { opcode, imm } => SerInstData::UnaryIeee64 {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
imm: imm.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::UnaryBool { opcode, imm } => SerInstData::UnaryBool {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
imm,
|
|
||||||
},
|
|
||||||
InstructionData::UnaryGlobalValue {
|
|
||||||
opcode,
|
|
||||||
global_value,
|
|
||||||
} => SerInstData::UnaryGlobalValue {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
global_value: global_value.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::Binary { opcode, args } => {
|
|
||||||
let hold_args = [args[0].to_string(), args[1].to_string()];
|
|
||||||
SerInstData::Binary {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::BinaryImm8 { opcode, arg, imm } => SerInstData::BinaryImm8 {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
imm: imm.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::BinaryImm64 { opcode, arg, imm } => SerInstData::BinaryImm64 {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
imm: imm.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::Ternary { opcode, args } => {
|
|
||||||
let hold_args = [
|
|
||||||
args[0].to_string(),
|
|
||||||
args[1].to_string(),
|
|
||||||
args[2].to_string(),
|
|
||||||
];
|
|
||||||
SerInstData::Ternary {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::MultiAry { opcode, ref args } => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
SerInstData::MultiAry {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::NullAry { opcode } => SerInstData::NullAry {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::TernaryImm8 { opcode, args, imm } => {
|
|
||||||
let hold_args = [args[0].to_string(), args[1].to_string()];
|
|
||||||
SerInstData::TernaryImm8 {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
imm: imm.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::UnaryConst {
|
|
||||||
opcode,
|
|
||||||
constant_handle,
|
|
||||||
} => {
|
|
||||||
let constant = func.dfg.constants.get(constant_handle);
|
|
||||||
SerInstData::UnaryImm {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
imm: format!("{:?}", constant),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::Shuffle { opcode, args, mask } => {
|
|
||||||
let mask = func
|
|
||||||
.dfg
|
|
||||||
.immediates
|
|
||||||
.get(mask)
|
|
||||||
.expect("Expected shuffle mask to already be inserted in immediate mapping");
|
|
||||||
SerInstData::Shuffle {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: [args[0].to_string(), args[1].to_string()],
|
|
||||||
mask: format!("{:?}", mask),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::IntCompare { opcode, args, cond } => {
|
|
||||||
let hold_args = [args[0].to_string(), args[1].to_string()];
|
|
||||||
SerInstData::IntCompare {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
cond: cond.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::IntCompareImm {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
cond,
|
|
||||||
imm,
|
|
||||||
} => SerInstData::IntCompareImm {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
cond: cond.to_string(),
|
|
||||||
imm: imm.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::IntCond { opcode, arg, cond } => SerInstData::IntCond {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
cond: cond.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::FloatCompare { opcode, args, cond } => {
|
|
||||||
let hold_args = [args[0].to_string(), args[1].to_string()];
|
|
||||||
SerInstData::FloatCompare {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
cond: cond.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::FloatCond { opcode, arg, cond } => SerInstData::FloatCond {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
cond: cond.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::IntSelect { opcode, args, cond } => {
|
|
||||||
let hold_args = [
|
|
||||||
args[0].to_string(),
|
|
||||||
args[1].to_string(),
|
|
||||||
args[2].to_string(),
|
|
||||||
];
|
|
||||||
SerInstData::IntSelect {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
cond: cond.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::Jump {
|
|
||||||
opcode,
|
|
||||||
ref args,
|
|
||||||
destination,
|
|
||||||
} => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
SerInstData::Jump {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
destination: destination.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::Branch {
|
|
||||||
opcode,
|
|
||||||
ref args,
|
|
||||||
destination,
|
|
||||||
} => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
SerInstData::Branch {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
destination: destination.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::BranchInt {
|
|
||||||
opcode,
|
|
||||||
ref args,
|
|
||||||
cond,
|
|
||||||
destination,
|
|
||||||
} => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
SerInstData::BranchInt {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
cond: cond.to_string(),
|
|
||||||
destination: destination.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::BranchFloat {
|
|
||||||
opcode,
|
|
||||||
ref args,
|
|
||||||
cond,
|
|
||||||
destination,
|
|
||||||
} => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
SerInstData::BranchFloat {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
cond: cond.to_string(),
|
|
||||||
destination: destination.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::BranchIcmp {
|
|
||||||
opcode,
|
|
||||||
ref args,
|
|
||||||
cond,
|
|
||||||
destination,
|
|
||||||
} => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
SerInstData::BranchIcmp {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
cond: cond.to_string(),
|
|
||||||
destination: destination.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::BranchTable {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
destination,
|
|
||||||
table,
|
|
||||||
} => SerInstData::BranchTable {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
destination: destination.to_string(),
|
|
||||||
table: table.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::BranchTableBase { opcode, table } => SerInstData::BranchTableBase {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
table: table.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::BranchTableEntry {
|
|
||||||
opcode,
|
|
||||||
args,
|
|
||||||
imm,
|
|
||||||
table,
|
|
||||||
} => {
|
|
||||||
let hold_args = [args[0].to_string(), args[1].to_string()];
|
|
||||||
SerInstData::BranchTableEntry {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
imm: imm.to_string(),
|
|
||||||
table: table.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::IndirectJump { opcode, arg, table } => SerInstData::IndirectJump {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
table: table.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::Call {
|
|
||||||
opcode,
|
|
||||||
ref args,
|
|
||||||
func_ref,
|
|
||||||
} => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
SerInstData::Call {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
func_ref: func_ref.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::CallIndirect {
|
|
||||||
opcode,
|
|
||||||
ref args,
|
|
||||||
sig_ref,
|
|
||||||
} => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
SerInstData::CallIndirect {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
sig_ref: sig_ref.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::FuncAddr { opcode, func_ref } => SerInstData::FuncAddr {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
func_ref: func_ref.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::Load {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
flags,
|
|
||||||
offset,
|
|
||||||
} => SerInstData::Load {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
flags: flags.to_string(),
|
|
||||||
offset: offset.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::LoadComplex {
|
|
||||||
opcode,
|
|
||||||
ref args,
|
|
||||||
flags,
|
|
||||||
offset,
|
|
||||||
} => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
SerInstData::LoadComplex {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
flags: flags.to_string(),
|
|
||||||
offset: offset.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::Store {
|
|
||||||
opcode,
|
|
||||||
args,
|
|
||||||
flags,
|
|
||||||
offset,
|
|
||||||
} => {
|
|
||||||
let hold_args = [args[0].to_string(), args[1].to_string()];
|
|
||||||
SerInstData::Store {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
flags: flags.to_string(),
|
|
||||||
offset: offset.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::StoreComplex {
|
|
||||||
opcode,
|
|
||||||
ref args,
|
|
||||||
flags,
|
|
||||||
offset,
|
|
||||||
} => {
|
|
||||||
let mut hold_args = Vec::new();
|
|
||||||
let args_iter = args.as_slice(&func.dfg.value_lists);
|
|
||||||
for arg in args_iter {
|
|
||||||
hold_args.push(arg.to_string());
|
|
||||||
}
|
|
||||||
SerInstData::StoreComplex {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
flags: flags.to_string(),
|
|
||||||
offset: offset.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::StackLoad {
|
|
||||||
opcode,
|
|
||||||
stack_slot,
|
|
||||||
offset,
|
|
||||||
} => SerInstData::StackLoad {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
stack_slot: stack_slot.to_string(),
|
|
||||||
offset: offset.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::StackStore {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
stack_slot,
|
|
||||||
offset,
|
|
||||||
} => SerInstData::StackStore {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
stack_slot: stack_slot.to_string(),
|
|
||||||
offset: offset.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::HeapAddr {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
heap,
|
|
||||||
imm,
|
|
||||||
} => SerInstData::HeapAddr {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
heap: heap.to_string(),
|
|
||||||
imm: imm.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::TableAddr {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
table,
|
|
||||||
offset,
|
|
||||||
} => SerInstData::TableAddr {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
table: table.to_string(),
|
|
||||||
offset: offset.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::RegMove {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
src,
|
|
||||||
dst,
|
|
||||||
} => SerInstData::RegMove {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
src: src.to_string(),
|
|
||||||
dst: dst.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::CopySpecial { opcode, src, dst } => SerInstData::CopySpecial {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
src: src.to_string(),
|
|
||||||
dst: dst.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::CopyToSsa { opcode, src } => SerInstData::CopyToSsa {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
src: src.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::RegSpill {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
src,
|
|
||||||
dst,
|
|
||||||
} => SerInstData::RegSpill {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
src: src.to_string(),
|
|
||||||
dst: dst.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::RegFill {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
src,
|
|
||||||
dst,
|
|
||||||
} => SerInstData::RegFill {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
src: src.to_string(),
|
|
||||||
dst: dst.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::Trap { opcode, code } => SerInstData::Trap {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
code: code.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::CondTrap { opcode, arg, code } => SerInstData::CondTrap {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
code: code.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::IntCondTrap {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
cond,
|
|
||||||
code,
|
|
||||||
} => SerInstData::IntCondTrap {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
cond: cond.to_string(),
|
|
||||||
code: code.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::FloatCondTrap {
|
|
||||||
opcode,
|
|
||||||
arg,
|
|
||||||
cond,
|
|
||||||
code,
|
|
||||||
} => SerInstData::FloatCondTrap {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
cond: cond.to_string(),
|
|
||||||
code: code.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::AtomicCas {
|
|
||||||
opcode,
|
|
||||||
args,
|
|
||||||
flags,
|
|
||||||
} => {
|
|
||||||
let hold_args = [
|
|
||||||
args[0].to_string(),
|
|
||||||
args[1].to_string(),
|
|
||||||
args[2].to_string(),
|
|
||||||
];
|
|
||||||
SerInstData::AtomicCas {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
flags: flags.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::AtomicRmw {
|
|
||||||
opcode,
|
|
||||||
args,
|
|
||||||
flags,
|
|
||||||
op,
|
|
||||||
} => {
|
|
||||||
let hold_args = [args[0].to_string(), args[1].to_string()];
|
|
||||||
SerInstData::AtomicRmw {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
flags: flags.to_string(),
|
|
||||||
op: op.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InstructionData::LoadNoOffset { opcode, arg, flags } => SerInstData::LoadNoOffset {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
arg: arg.to_string(),
|
|
||||||
flags: flags.to_string(),
|
|
||||||
},
|
|
||||||
InstructionData::StoreNoOffset {
|
|
||||||
opcode,
|
|
||||||
args,
|
|
||||||
flags,
|
|
||||||
} => {
|
|
||||||
let hold_args = [args[0].to_string(), args[1].to_string()];
|
|
||||||
SerInstData::StoreNoOffset {
|
|
||||||
opcode: opcode.to_string(),
|
|
||||||
args: hold_args,
|
|
||||||
flags: flags.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serializable version of Cranelift IR instructions.
|
|
||||||
#[derive(Clone, Deserialize, Serialize, Debug)]
|
|
||||||
pub struct SerInst {
|
|
||||||
pub inst_name: String,
|
|
||||||
pub inst_data: SerInstData,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SerInst {
|
|
||||||
pub fn new(inst: Inst, func: &Function) -> Self {
|
|
||||||
Self {
|
|
||||||
inst_name: inst.to_string(),
|
|
||||||
inst_data: get_inst_data(inst, func),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serializable version of Cranelift IR Blocks.
|
|
||||||
#[derive(Clone, Deserialize, Serialize, Debug)]
|
|
||||||
pub struct SerBlock {
|
|
||||||
pub block: String,
|
|
||||||
pub params: Vec<String>,
|
|
||||||
pub insts: Vec<SerInst>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SerBlock {
|
|
||||||
pub fn new(name: String) -> Self {
|
|
||||||
Self {
|
|
||||||
block: name,
|
|
||||||
params: Vec::new(),
|
|
||||||
insts: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn populate_inst(func: &Function, block: Block) -> Vec<SerInst> {
|
|
||||||
let mut ser_vec: Vec<SerInst> = Vec::new();
|
|
||||||
let ret_iter = func.layout.block_insts(block);
|
|
||||||
for inst in ret_iter {
|
|
||||||
let ser_inst: SerInst = SerInst::new(inst, &func);
|
|
||||||
ser_vec.push(ser_inst);
|
|
||||||
}
|
|
||||||
ser_vec
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Translating Block parameters into serializable parameters.
|
|
||||||
pub fn populate_params(func: &Function, block: Block) -> Vec<String> {
|
|
||||||
let mut ser_vec: Vec<String> = Vec::new();
|
|
||||||
let parameters = func.dfg.block_params(block);
|
|
||||||
for param in parameters {
|
|
||||||
ser_vec.push(param.to_string());
|
|
||||||
}
|
|
||||||
ser_vec
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serializable Data Flow Graph.
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
|
||||||
pub struct SerDataFlowGraph {
|
|
||||||
blocks: Vec<SerBlock>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serialize all parts of the Cranelift Block data structure, this includes name, parameters, and
|
|
||||||
/// instructions.
|
|
||||||
pub fn populate_blocks(func: &Function) -> Vec<SerBlock> {
|
|
||||||
let mut block_vec: Vec<SerBlock> = Vec::new();
|
|
||||||
for block in func.layout.blocks() {
|
|
||||||
let mut ser_block: SerBlock = SerBlock::new(block.to_string());
|
|
||||||
ser_block.params = populate_params(&func, block);
|
|
||||||
ser_block.insts = populate_inst(&func, block);
|
|
||||||
block_vec.push(ser_block);
|
|
||||||
}
|
|
||||||
block_vec
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serializable Cranelift IR data flow graph, including all blocks.
|
|
||||||
impl SerDataFlowGraph {
|
|
||||||
pub fn create_new(func: &Function) -> Self {
|
|
||||||
Self {
|
|
||||||
blocks: populate_blocks(func),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(func: &Function) -> Self {
|
|
||||||
Self::create_new(func)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serializable signature including function parameters and returns.
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
|
||||||
pub struct SerSignature {
|
|
||||||
pub func_params: Vec<String>,
|
|
||||||
pub func_returns: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SerSignature {
|
|
||||||
/// Creating serializable signature data structure from all Cranelift IR functions.
|
|
||||||
fn create_new(sig: &Signature) -> Self {
|
|
||||||
let mut params_vec: Vec<String> = Vec::new();
|
|
||||||
let mut returns_vec: Vec<String> = Vec::new();
|
|
||||||
for param in &sig.params {
|
|
||||||
params_vec.push(param.to_string());
|
|
||||||
}
|
|
||||||
for ret in &sig.returns {
|
|
||||||
returns_vec.push(ret.to_string());
|
|
||||||
}
|
|
||||||
Self {
|
|
||||||
func_params: params_vec,
|
|
||||||
func_returns: returns_vec,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(func: &Function) -> Self {
|
|
||||||
Self::create_new(&func.signature)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serializable Function type, including name, signature, global values, and data flow graph.
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
|
||||||
pub struct SerFunction {
|
|
||||||
pub name: String,
|
|
||||||
pub signature: SerSignature,
|
|
||||||
pub globals: Vec<String>,
|
|
||||||
pub dfg: SerDataFlowGraph,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SerFunction {
|
|
||||||
/// Creates serializable global values, as well as the functions signature, name, and data flow
|
|
||||||
/// graph.
|
|
||||||
fn create_new(func: &Function) -> Self {
|
|
||||||
let mut global_vec: Vec<String> = Vec::new();
|
|
||||||
for (glob_name, _) in func.global_values.iter() {
|
|
||||||
global_vec.push(glob_name.to_string());
|
|
||||||
}
|
|
||||||
Self {
|
|
||||||
name: func.name.to_string(),
|
|
||||||
signature: SerSignature::new(&func),
|
|
||||||
globals: global_vec,
|
|
||||||
dfg: SerDataFlowGraph::new(&func),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(func: &Function) -> Self {
|
|
||||||
Self::create_new(func)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Must have SerObj for deserialization, contains all of the functions from inside the file to be
|
|
||||||
/// serialized. Files have one SerObj each, with all SerFunctions contained inside that SerObj.
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
|
||||||
pub struct SerObj {
|
|
||||||
pub functions: Vec<SerFunction>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SerObj {
|
|
||||||
fn create_new(funcs: Vec<SerFunction>) -> Self {
|
|
||||||
Self { functions: funcs }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(funcs: &[Function]) -> Self {
|
|
||||||
let mut func_vec: Vec<SerFunction> = Vec::new();
|
|
||||||
for func in funcs {
|
|
||||||
let ser_func: SerFunction = SerFunction::new(&func);
|
|
||||||
func_vec.push(ser_func);
|
|
||||||
}
|
|
||||||
Self::create_new(func_vec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user