Support wire assignment in entity
This commit is contained in:
parent
848d9e48a8
commit
6c87b4d5f7
|
@ -2,7 +2,7 @@ use crate::cst::{Expression, ModuleContext, Statement, SymbolKind, Tag, Tools, U
|
|||
use json::JsonValue;
|
||||
use linked_hash_map::LinkedHashMap as HashMap;
|
||||
use llhd::{
|
||||
ir::{Block, Inst, Opcode, Signature, UnitId, UnitKind, UnitName, Value},
|
||||
ir::{Signature, UnitId, UnitKind, UnitName, Value},
|
||||
ty::{int_ty, signal_ty},
|
||||
};
|
||||
|
||||
|
@ -111,95 +111,12 @@ impl AlwaysStatement {
|
|||
Self::gen_event_expression_list(json_event_expression_list, context);
|
||||
Statement::codegen(json_statement, context);
|
||||
|
||||
Self::beautify(context);
|
||||
Tools::beautify(&mut context.unit_ctx);
|
||||
|
||||
context.unit_ctx.clear();
|
||||
context.module.add_unit(context.unit_ctx.drop_data())
|
||||
}
|
||||
|
||||
fn beautify(context: &mut ModuleContext) {
|
||||
let unit_ctx = &mut context.unit_ctx;
|
||||
let mut builder = UnitContext::builder(&mut unit_ctx.data);
|
||||
|
||||
let bb_first = builder.unit().first_block().unwrap();
|
||||
let bb_last = builder.unit().last_block().unwrap();
|
||||
builder.set_block_name(bb_last, String::from("end"));
|
||||
builder.append_to(bb_last);
|
||||
builder.ins().br(bb_first);
|
||||
|
||||
// remove blocks with a single jump
|
||||
{
|
||||
let single_inst_blocks: Vec<Block> = builder
|
||||
.unit()
|
||||
.blocks()
|
||||
.filter(|&x| builder.unit().insts(x).count() == 1)
|
||||
.collect();
|
||||
for block in single_inst_blocks {
|
||||
let inst = builder.unit().insts(block).last().unwrap();
|
||||
let inst_data = &builder[inst];
|
||||
if inst_data.opcode() == Opcode::Br {
|
||||
assert!(inst_data.args().len() == 0 && inst_data.blocks().len() == 1);
|
||||
let to_block = inst_data.blocks()[0];
|
||||
builder.replace_block_use(block, to_block);
|
||||
builder.delete_block(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove empty blocks
|
||||
{
|
||||
let empty_blocks: Vec<Block> = builder
|
||||
.unit()
|
||||
.blocks()
|
||||
.filter(|&x| builder.unit().insts(x).count() == 0)
|
||||
.collect();
|
||||
for block in empty_blocks {
|
||||
let next_block = builder.unit().next_block(block);
|
||||
assert!(next_block.is_some());
|
||||
builder.replace_block_use(block, next_block.unwrap());
|
||||
builder.delete_block(block);
|
||||
}
|
||||
}
|
||||
|
||||
// name values for 'prb' and 'ld' instructions
|
||||
{
|
||||
let mut prb_count = HashMap::<String, usize>::new();
|
||||
let mut ld_count = HashMap::<String, usize>::new();
|
||||
let get_name = |base_name: &String, count: &mut HashMap<String, usize>| -> String {
|
||||
if count.contains_key(base_name) {
|
||||
count.insert(base_name.clone(), count[base_name] + 1);
|
||||
format!("{}{}", base_name, count[base_name])
|
||||
} else {
|
||||
count.insert(base_name.clone(), 0);
|
||||
base_name.clone()
|
||||
}
|
||||
};
|
||||
let insts: Vec<Inst> = builder.unit().all_insts().collect();
|
||||
for inst in insts {
|
||||
let inst_data = &builder[inst];
|
||||
let output = builder.get_inst_result(inst);
|
||||
match inst_data.opcode() {
|
||||
Opcode::Prb => {
|
||||
let input = inst_data.args()[0];
|
||||
let input_name = builder.unit().get_name(input).unwrap();
|
||||
let skip = unit_ctx.raw_name_to_shadow.contains_key(input_name);
|
||||
if !skip {
|
||||
// skip shadows
|
||||
let base_name = &format!("{}.prb", input_name);
|
||||
builder.set_name(output.unwrap(), get_name(base_name, &mut prb_count));
|
||||
}
|
||||
}
|
||||
Opcode::Ld => {
|
||||
let input = inst_data.args()[0];
|
||||
let base_name = &format!("{}.ld", builder.unit().get_name(input).unwrap());
|
||||
builder.set_name(output.unwrap(), get_name(base_name, &mut ld_count));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_event_expression_list(json: &JsonValue, context: &mut ModuleContext) {
|
||||
let mut sensitivity_list = HashMap::new();
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ impl Expression {
|
|||
assert_eq!(symbol_info.kind, SymbolKind::Param);
|
||||
builder.ins().const_int(symbol_info.value.clone())
|
||||
} else {
|
||||
panic!("unknown error at CST node {}", json);
|
||||
panic!("unknown error at CST node '{}'", json);
|
||||
};
|
||||
|
||||
if range.is_some() {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use crate::cst::{
|
||||
AlwaysStatement, ModuleContext, SymbolDeclaration, SymbolKind, Tag, Tools, UnitContext,
|
||||
AlwaysStatement, ModuleContext, NetVariableAssignment, SymbolDeclaration, SymbolKind, Tag,
|
||||
Tools, UnitContext,
|
||||
};
|
||||
use json::JsonValue;
|
||||
use llhd::{
|
||||
ir::{ExtUnit, Module, Signature, UnitBuilder, UnitData, UnitId, UnitKind, Value},
|
||||
ir::{ExtUnit, Module, Signature, UnitId, UnitKind, UnitName, Value},
|
||||
ty::{int_ty, signal_ty},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
@ -17,12 +18,48 @@ impl ModuleDeclaration {
|
|||
pub fn codegen(json: &JsonValue) -> Module {
|
||||
let mut context = ModuleContext::new();
|
||||
|
||||
SymbolDeclaration::gen_port_info(json, &mut context);
|
||||
SymbolDeclaration::gen_reg_info(json, &mut context);
|
||||
SymbolDeclaration::gen_wire_info(json, &mut context);
|
||||
SymbolDeclaration::gen_param_info(json, &mut context);
|
||||
SymbolDeclaration::declare_port(json, &mut context);
|
||||
SymbolDeclaration::declare_reg(json, &mut context);
|
||||
SymbolDeclaration::declare_wire(json, &mut context);
|
||||
SymbolDeclaration::declare_param(json, &mut context);
|
||||
|
||||
Self::gen_entity_data(json, &mut context);
|
||||
Self::set_port_names(&mut context);
|
||||
Self::init_regs_and_wires(&mut context);
|
||||
Self::gen_assignment(json, &mut context);
|
||||
|
||||
let mut entity_ctx = context.unit_ctx.drop(); // clear UnitContext before declare processes
|
||||
|
||||
Self::gen_always(json, &mut entity_ctx, &mut context);
|
||||
Tools::beautify(&mut entity_ctx);
|
||||
|
||||
context.module.add_unit(entity_ctx.data.take().unwrap());
|
||||
|
||||
debug!(
|
||||
">>>>>>>>>{0}>>>>>>>>>\n{1}<<<<<<<<<{0}<<<<<<<<<",
|
||||
" module-codegen ",
|
||||
context.module.dump()
|
||||
);
|
||||
|
||||
context.module
|
||||
}
|
||||
|
||||
fn gen_entity_data(json: &JsonValue, context: &mut ModuleContext) {
|
||||
context.name = {
|
||||
let json_symbol_identifier = Tools::match_tags(
|
||||
vec![json],
|
||||
vec![
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_HEADER,
|
||||
Tag::SYMBOL_IDENTIFIER,
|
||||
],
|
||||
);
|
||||
assert_eq!(json_symbol_identifier.len(), 1);
|
||||
json_symbol_identifier[0]["text"].to_string()
|
||||
};
|
||||
|
||||
let entity_name = UnitName::global(context.name.clone());
|
||||
|
||||
let entity_name = SymbolDeclaration::gen_entity_name(json, &mut context);
|
||||
let entity_signature = {
|
||||
let mut signature = Signature::new();
|
||||
let raw_name_to_arg = &mut context.unit_ctx.raw_name_to_arg;
|
||||
|
@ -44,24 +81,29 @@ impl ModuleDeclaration {
|
|||
|
||||
signature
|
||||
};
|
||||
let mut entity_data = UnitData::new(UnitKind::Entity, entity_name, entity_signature);
|
||||
|
||||
// build entity
|
||||
{
|
||||
let mut entity_builder = UnitBuilder::new_anonymous(&mut entity_data);
|
||||
context
|
||||
.unit_ctx
|
||||
.new_data(UnitKind::Entity, entity_name, entity_signature);
|
||||
}
|
||||
|
||||
fn set_port_names(context: &mut ModuleContext) {
|
||||
let mut builder = UnitContext::builder(&mut context.unit_ctx.data);
|
||||
|
||||
// set input/output port names
|
||||
for (raw_name, &arg) in &context.unit_ctx.raw_name_to_arg {
|
||||
let arg_value = entity_builder.arg_value(arg);
|
||||
entity_builder.set_name(arg_value, raw_name.clone());
|
||||
let arg_value = builder.arg_value(arg);
|
||||
builder.set_name(arg_value, raw_name.clone());
|
||||
context
|
||||
.unit_ctx
|
||||
.raw_name_to_value
|
||||
.insert(raw_name.clone(), arg_value);
|
||||
debug!("found I/O port {}", raw_name);
|
||||
trace!("found I/O port {}", raw_name);
|
||||
}
|
||||
}
|
||||
|
||||
// initialize reg and wire
|
||||
fn init_regs_and_wires(context: &mut ModuleContext) {
|
||||
let mut builder = UnitContext::builder(&mut context.unit_ctx.data);
|
||||
|
||||
let mut zeros = HashMap::new();
|
||||
for (name, symbol) in &context.symbol {
|
||||
let width = symbol.value.width;
|
||||
|
@ -72,48 +114,47 @@ impl ModuleDeclaration {
|
|||
let zero = if zeros.contains_key(&w) {
|
||||
zeros[&w]
|
||||
} else {
|
||||
let z = entity_builder.ins().const_zero(&int_ty(w));
|
||||
let z = builder.ins().const_zero(&int_ty(w));
|
||||
zeros.insert(w, z);
|
||||
z
|
||||
};
|
||||
let value = entity_builder.ins().sig(zero);
|
||||
entity_builder.set_name(value, n);
|
||||
let value = builder.ins().sig(zero);
|
||||
builder.set_name(value, n);
|
||||
context
|
||||
.unit_ctx
|
||||
.raw_name_to_value
|
||||
.insert(name.clone(), value);
|
||||
debug!("found {} {}", symbol.kind, name);
|
||||
trace!("found {} {}", symbol.kind, name);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// clear UnitContext before declare processes
|
||||
let entity_ctx = context.unit_ctx.drop();
|
||||
|
||||
// declare and instantiate processes
|
||||
Self::instantiate_processes(json, &mut entity_builder, &entity_ctx, &mut context);
|
||||
|
||||
entity_builder.finish();
|
||||
}
|
||||
|
||||
context.module.add_unit(entity_data);
|
||||
debug!(
|
||||
">>>>>>>>>{0}>>>>>>>>>\n{1}<<<<<<<<<{0}<<<<<<<<<",
|
||||
" module-codegen ",
|
||||
context.module.dump()
|
||||
fn gen_assignment(json: &JsonValue, context: &mut ModuleContext) {
|
||||
let json_wire_assignments = &Tools::match_tags(
|
||||
vec![json],
|
||||
vec![
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_ITEM_LIST,
|
||||
Tag::CONTINUOUS_ASSIGNMENT_STATEMENT,
|
||||
Tag::ASSIGNMENT_LIST,
|
||||
Tag::NET_VARIABLE_ASSIGNMENT,
|
||||
],
|
||||
);
|
||||
|
||||
context.module
|
||||
let builder = UnitContext::builder(&mut context.unit_ctx.data);
|
||||
context.unit_ctx.bb_head.push(builder.unit().entry());
|
||||
|
||||
for json_wire_assignment in json_wire_assignments {
|
||||
NetVariableAssignment::codegen(json_wire_assignment, context);
|
||||
}
|
||||
|
||||
fn instantiate_processes(
|
||||
json: &JsonValue,
|
||||
entity_builder: &mut UnitBuilder,
|
||||
entity_ctx: &UnitContext,
|
||||
context: &mut ModuleContext,
|
||||
) {
|
||||
let json_always_statement = &Tools::match_tags(
|
||||
context.unit_ctx.bb_head.pop();
|
||||
}
|
||||
|
||||
fn gen_always(json: &JsonValue, entity_ctx: &mut UnitContext, context: &mut ModuleContext) {
|
||||
let json_always_statements = &Tools::match_tags(
|
||||
vec![json],
|
||||
vec![
|
||||
Tag::MODULE_DECLARATION,
|
||||
|
@ -122,17 +163,22 @@ impl ModuleDeclaration {
|
|||
],
|
||||
);
|
||||
|
||||
let mut builder = UnitContext::builder(&mut entity_ctx.data);
|
||||
let raw_name_to_value = &entity_ctx.raw_name_to_value;
|
||||
|
||||
// declare processes
|
||||
let ext_to_proc: Vec<(ExtUnit, UnitId)> = json_always_statement
|
||||
let ext_to_proc: Vec<(ExtUnit, UnitId)> = json_always_statements
|
||||
.iter()
|
||||
.map(|&x| {
|
||||
let proc_id = AlwaysStatement::codegen(x, context).unwrap();
|
||||
let proc = context.module.unit(proc_id);
|
||||
let ext_proc = entity_builder.add_extern(proc.name().clone(), proc.sig().clone());
|
||||
let ext_proc = builder.add_extern(proc.name().clone(), proc.sig().clone());
|
||||
(ext_proc, proc_id)
|
||||
})
|
||||
.collect();
|
||||
|
||||
builder.append_to(builder.unit().entry());
|
||||
|
||||
// instantiate processes
|
||||
for (ext_proc, proc_id) in ext_to_proc {
|
||||
let proc = &context.module.unit(proc_id);
|
||||
|
@ -141,7 +187,7 @@ impl ModuleDeclaration {
|
|||
.into_iter()
|
||||
.map(|x| {
|
||||
let name = &proc.get_name(x).unwrap().to_string();
|
||||
entity_ctx.raw_name_to_value[name]
|
||||
raw_name_to_value[name]
|
||||
})
|
||||
.collect();
|
||||
let outputs: Vec<Value> = proc
|
||||
|
@ -149,10 +195,10 @@ impl ModuleDeclaration {
|
|||
.into_iter()
|
||||
.map(|x| {
|
||||
let name = &proc.get_name(x).unwrap().to_string();
|
||||
entity_ctx.raw_name_to_value[name]
|
||||
raw_name_to_value[name]
|
||||
})
|
||||
.collect();
|
||||
entity_builder.ins().inst(ext_proc, inputs, outputs);
|
||||
builder.ins().inst(ext_proc, inputs, outputs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use crate::cst::{Expression, ModuleContext, Tag, Tools, UnitContext};
|
||||
use json::JsonValue;
|
||||
use llhd::{ir::Block, value::TimeValue};
|
||||
use llhd::{
|
||||
ir::{Block, UnitKind},
|
||||
value::TimeValue,
|
||||
};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
@ -13,9 +16,12 @@ impl NetVariableAssignment {
|
|||
assert_eq!(json["tag"], Tag::NET_VARIABLE_ASSIGNMENT);
|
||||
|
||||
let json_children = &json["children"];
|
||||
assert_eq!(json_children.len(), 4);
|
||||
assert!(json_children.len() >= 3);
|
||||
assert_eq!(json_children[1]["tag"], "=");
|
||||
if json_children.len() > 3 {
|
||||
assert_eq!(json_children.len(), 4);
|
||||
assert_eq!(json_children[3]["tag"], ";");
|
||||
}
|
||||
|
||||
let json_symbol_identifier = Tools::match_tags(
|
||||
vec![&json_children[0]],
|
||||
|
@ -35,14 +41,26 @@ impl NetVariableAssignment {
|
|||
|
||||
let lvalue_name = &json_lpvalue["text"].to_string();
|
||||
context.unit_ctx.lvalues.insert(lvalue_name.clone());
|
||||
if context.unit_ctx.raw_name_to_value.contains_key(lvalue_name) {
|
||||
assert!(context.unit_ctx.raw_name_to_arg.contains_key(lvalue_name));
|
||||
let lvalue = context.unit_ctx.raw_name_to_value.get(lvalue_name);
|
||||
if lvalue.is_some() {
|
||||
assert!(context.unit_ctx.data.is_some());
|
||||
let arg = context.unit_ctx.raw_name_to_arg[lvalue_name];
|
||||
let builder = &UnitContext::builder(&mut context.unit_ctx.data);
|
||||
match builder.unit().kind() {
|
||||
UnitKind::Process => {
|
||||
assert!(context.unit_ctx.raw_name_to_arg.contains_key(lvalue_name));
|
||||
let arg = context.unit_ctx.raw_name_to_arg[lvalue_name];
|
||||
// set active Type
|
||||
context.unit_ctx.ty_active = Some(builder.unit().sig().arg_type(arg));
|
||||
}
|
||||
UnitKind::Entity => {
|
||||
// set active Type
|
||||
context.unit_ctx.ty_active = Some(builder.unit().value_type(*lvalue.unwrap()));
|
||||
}
|
||||
_ => {
|
||||
panic!("unknown error at CST node '{}'", json_lpvalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let opt_expr = Expression::codegen(json_expression, context);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::cst::{ModuleContext, Number, SymbolInfo, SymbolKind, Tag, Tools};
|
||||
use json::JsonValue;
|
||||
use llhd::{ir::UnitName, value::IntValue};
|
||||
use llhd::value::IntValue;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
@ -8,24 +8,7 @@ use log::{debug, error, info, trace, warn};
|
|||
pub struct SymbolDeclaration {}
|
||||
|
||||
impl SymbolDeclaration {
|
||||
pub fn gen_entity_name(json: &JsonValue, context: &mut ModuleContext) -> UnitName {
|
||||
context.name = {
|
||||
let json_symbol_identifier = Tools::match_tags(
|
||||
vec![json],
|
||||
vec![
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_HEADER,
|
||||
Tag::SYMBOL_IDENTIFIER,
|
||||
],
|
||||
);
|
||||
assert_eq!(json_symbol_identifier.len(), 1);
|
||||
json_symbol_identifier[0]["text"].to_string()
|
||||
};
|
||||
|
||||
UnitName::global(context.name.to_string())
|
||||
}
|
||||
|
||||
pub fn gen_port_info(json: &JsonValue, context: &mut ModuleContext) {
|
||||
pub fn declare_port(json: &JsonValue, context: &mut ModuleContext) {
|
||||
let base_path_2001 = [
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_ITEM_LIST,
|
||||
|
@ -174,7 +157,7 @@ impl SymbolDeclaration {
|
|||
gen_port_info(json_output_ports, SymbolKind::Output);
|
||||
}
|
||||
|
||||
pub fn gen_reg_info(json: &JsonValue, context: &mut ModuleContext) {
|
||||
pub fn declare_reg(json: &JsonValue, context: &mut ModuleContext) {
|
||||
let base_path = [
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_ITEM_LIST,
|
||||
|
@ -224,7 +207,7 @@ impl SymbolDeclaration {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn gen_wire_info(json: &JsonValue, context: &mut ModuleContext) {
|
||||
pub fn declare_wire(json: &JsonValue, context: &mut ModuleContext) {
|
||||
let base_path = [
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_ITEM_LIST,
|
||||
|
@ -304,7 +287,7 @@ impl SymbolDeclaration {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn gen_param_info(json: &JsonValue, context: &mut ModuleContext) {
|
||||
pub fn declare_param(json: &JsonValue, context: &mut ModuleContext) {
|
||||
let base_path = [
|
||||
Tag::MODULE_DECLARATION,
|
||||
Tag::MODULE_ITEM_LIST,
|
||||
|
@ -341,7 +324,7 @@ impl SymbolDeclaration {
|
|||
|
||||
let name = json_names[0]["text"].to_string();
|
||||
let symbol = SymbolInfo::new(SymbolKind::Param, v);
|
||||
debug!("found {} {}", SymbolKind::Param, name);
|
||||
trace!("found {} {}", SymbolKind::Param, name);
|
||||
|
||||
context.symbol.insert(name, symbol);
|
||||
}
|
||||
|
|
|
@ -80,9 +80,12 @@ impl Tag {
|
|||
pub const SEQ_BLOCK: &'static str = "kSeqBlock";
|
||||
pub const BLOCK_ITEM_STATEMENT_LIST: &'static str = "kBlockItemStatementList";
|
||||
|
||||
pub const NONBLOCKING_ASSIGNMENT_STATEMENT: &'static str = "kNonblockingAssignmentStatement";
|
||||
pub const CONTINUOUS_ASSIGNMENT_STATEMENT: &'static str = "kContinuousAssignmentStatement";
|
||||
pub const ASSIGNMENT_LIST: &'static str = "kAssignmentList";
|
||||
pub const NET_VARIABLE_ASSIGNMENT: &'static str = "kNetVariableAssignment";
|
||||
|
||||
pub const NONBLOCKING_ASSIGNMENT_STATEMENT: &'static str = "kNonblockingAssignmentStatement";
|
||||
|
||||
pub const CONDITIONAL_STATEMENT: &'static str = "kConditionalStatement";
|
||||
pub const IF_CLAUSE: &'static str = "kIfClause";
|
||||
pub const IF_HEADER: &'static str = "kIfHeader";
|
||||
|
@ -95,10 +98,6 @@ impl Tag {
|
|||
pub const CASE_ITEM: &'static str = "kCaseItem";
|
||||
pub const DEFAULT_ITEM: &'static str = "kDefaultItem";
|
||||
|
||||
/*
|
||||
pub const CONTINUOUS_ASSIGNMENT_STATEMENT: &'static str = "kContinuousAssignmentStatement";
|
||||
*/
|
||||
|
||||
pub const INPUT: &'static str = "input";
|
||||
pub const OUTPUT: &'static str = "output";
|
||||
pub const REG: &'static str = "reg";
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::cst::UnitContext;
|
||||
use json::JsonValue;
|
||||
use llhd::ir::{Block, Inst, Opcode};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::File,
|
||||
io::{BufRead, BufReader},
|
||||
};
|
||||
|
@ -18,6 +21,88 @@ impl Tools {
|
|||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn beautify(unit_ctx: &mut UnitContext) {
|
||||
let mut builder = UnitContext::builder(&mut unit_ctx.data);
|
||||
|
||||
let bb_first = builder.unit().first_block().unwrap();
|
||||
let bb_last = builder.unit().last_block().unwrap();
|
||||
builder.set_block_name(bb_last, String::from("end"));
|
||||
builder.append_to(bb_last);
|
||||
builder.ins().br(bb_first);
|
||||
|
||||
// remove blocks with a single jump
|
||||
{
|
||||
let single_inst_blocks: Vec<Block> = builder
|
||||
.unit()
|
||||
.blocks()
|
||||
.filter(|&x| builder.unit().insts(x).count() == 1)
|
||||
.collect();
|
||||
for block in single_inst_blocks {
|
||||
let inst = builder.unit().insts(block).last().unwrap();
|
||||
let inst_data = &builder[inst];
|
||||
if inst_data.opcode() == Opcode::Br {
|
||||
assert!(inst_data.args().len() == 0 && inst_data.blocks().len() == 1);
|
||||
let to_block = inst_data.blocks()[0];
|
||||
builder.replace_block_use(block, to_block);
|
||||
builder.delete_block(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove empty blocks
|
||||
{
|
||||
let empty_blocks: Vec<Block> = builder
|
||||
.unit()
|
||||
.blocks()
|
||||
.filter(|&x| builder.unit().insts(x).count() == 0)
|
||||
.collect();
|
||||
for block in empty_blocks {
|
||||
let next_block = builder.unit().next_block(block);
|
||||
assert!(next_block.is_some());
|
||||
builder.replace_block_use(block, next_block.unwrap());
|
||||
builder.delete_block(block);
|
||||
}
|
||||
}
|
||||
|
||||
// name values for 'prb' and 'ld' instructions
|
||||
{
|
||||
let mut prb_count = HashMap::<String, usize>::new();
|
||||
let mut ld_count = HashMap::<String, usize>::new();
|
||||
let get_name = |base_name: &String, count: &mut HashMap<String, usize>| -> String {
|
||||
if count.contains_key(base_name) {
|
||||
count.insert(base_name.clone(), count[base_name] + 1);
|
||||
format!("{}{}", base_name, count[base_name])
|
||||
} else {
|
||||
count.insert(base_name.clone(), 0);
|
||||
base_name.clone()
|
||||
}
|
||||
};
|
||||
let insts: Vec<Inst> = builder.unit().all_insts().collect();
|
||||
for inst in insts {
|
||||
let inst_data = &builder[inst];
|
||||
let output = builder.get_inst_result(inst);
|
||||
match inst_data.opcode() {
|
||||
Opcode::Prb => {
|
||||
let input = inst_data.args()[0];
|
||||
let input_name = builder.unit().get_name(input).unwrap();
|
||||
let skip = unit_ctx.raw_name_to_shadow.contains_key(input_name);
|
||||
if !skip {
|
||||
// skip shadows
|
||||
let base_name = &format!("{}.prb", input_name);
|
||||
builder.set_name(output.unwrap(), get_name(base_name, &mut prb_count));
|
||||
}
|
||||
}
|
||||
Opcode::Ld => {
|
||||
let input = inst_data.args()[0];
|
||||
let base_name = &format!("{}.ld", builder.unit().get_name(input).unwrap());
|
||||
builder.set_name(output.unwrap(), get_name(base_name, &mut ld_count));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CodeReporter {
|
||||
|
|
Loading…
Reference in New Issue