Fix a bug in case statement
This commit is contained in:
parent
929abdaf85
commit
7ab655df9b
|
@ -1,10 +1,10 @@
|
|||
use crate::cst::{Expression, ModuleContext, Statement, SymbolKind, Tag, Tools, UnitContext};
|
||||
use json::JsonValue;
|
||||
use linked_hash_map::LinkedHashMap as HashMap;
|
||||
use llhd::{
|
||||
ir::{Block, Inst, Opcode, Signature, UnitId, UnitKind, UnitName, Value},
|
||||
ty::{int_ty, signal_ty},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::cst::{Expression, ModuleContext, Statement, Tag, Tools, UnitContext};
|
||||
use json::JsonValue;
|
||||
use llhd::ir::Block;
|
||||
use llhd::ir::{Block, Unit};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
@ -34,10 +34,21 @@ impl CaseStatement {
|
|||
e.unwrap()
|
||||
};
|
||||
|
||||
let mut bb_next = {
|
||||
let unit_ctx = &mut context.unit_ctx;
|
||||
let mut builder = UnitContext::builder(&mut unit_ctx.data);
|
||||
builder.block()
|
||||
let case_body_name = |unit: Unit| -> String {
|
||||
let prefix = "case_body";
|
||||
let count = unit
|
||||
.blocks()
|
||||
.filter(|x| {
|
||||
let bb_name = unit.get_block_name(*x);
|
||||
bb_name.is_some() && bb_name.unwrap().to_string().starts_with(prefix)
|
||||
})
|
||||
.count();
|
||||
|
||||
if count > 0 {
|
||||
format!("{}{}", prefix, count)
|
||||
} else {
|
||||
String::from(prefix)
|
||||
}
|
||||
};
|
||||
|
||||
let case_tails: Vec<_> = json_case_items
|
||||
|
@ -52,8 +63,15 @@ impl CaseStatement {
|
|||
let unit_ctx = &mut context.unit_ctx;
|
||||
let mut builder = UnitContext::builder(&mut unit_ctx.data);
|
||||
|
||||
let bb_curr = bb_next;
|
||||
bb_next = builder.block();
|
||||
let bb_curr = builder.named_block(case_body_name(builder.unit()));
|
||||
let bb_next = builder.block();
|
||||
|
||||
debug!(
|
||||
"case br_cond (true {}; false {}) in block {}",
|
||||
bb_curr.dump(&builder.unit()),
|
||||
bb_next.dump(&builder.unit()),
|
||||
unit_ctx.bb_head.last().unwrap().dump(&builder.unit())
|
||||
);
|
||||
|
||||
builder.append_to(unit_ctx.bb_head.pop().unwrap());
|
||||
unit_ctx.bb_head.push(bb_next); // basic block for the next case
|
||||
|
@ -76,13 +94,16 @@ impl CaseStatement {
|
|||
})
|
||||
.collect();
|
||||
|
||||
if json_default_statement.is_some() {
|
||||
let bb_last = if json_default_statement.is_some() {
|
||||
let stmt = Self::visit_case_body(json_default_statement.unwrap(), context);
|
||||
let unit_ctx = &mut context.unit_ctx;
|
||||
unit_ctx.bb_head.pop();
|
||||
unit_ctx.bb_head.push(stmt.unwrap()); // basic block for the future statement
|
||||
bb_next = stmt.unwrap();
|
||||
}
|
||||
stmt.unwrap()
|
||||
} else {
|
||||
let unit_ctx = &mut context.unit_ctx;
|
||||
*unit_ctx.bb_head.last().unwrap() // WARN: double check
|
||||
};
|
||||
|
||||
let unit_ctx = &mut context.unit_ctx;
|
||||
if unit_ctx.data.is_some() {
|
||||
|
@ -90,12 +111,12 @@ impl CaseStatement {
|
|||
|
||||
// merge dangling basic blocks at the end of each case
|
||||
for case_tail in case_tails {
|
||||
builder.replace_block_use(case_tail, bb_next);
|
||||
builder.replace_block_use(case_tail, bb_last);
|
||||
builder.delete_block(case_tail);
|
||||
}
|
||||
}
|
||||
|
||||
Some(bb_next)
|
||||
Some(bb_last)
|
||||
}
|
||||
|
||||
fn visit_case_body(json: &JsonValue, context: &mut ModuleContext) -> Option<Block> {
|
||||
|
|
|
@ -24,16 +24,16 @@ impl ConditionalStatement {
|
|||
let unit_ctx = &mut context.unit_ctx;
|
||||
let mut builder = UnitContext::builder(&mut unit_ctx.data);
|
||||
|
||||
let unit = &builder.unit();
|
||||
let count = unit
|
||||
.blocks()
|
||||
.filter(|x| {
|
||||
let bb_name = unit.get_block_name(*x);
|
||||
bb_name.is_some() && bb_name.unwrap().to_string().starts_with("if_true")
|
||||
})
|
||||
.count();
|
||||
|
||||
let (if_true_name, if_false_name) = {
|
||||
let unit = &builder.unit();
|
||||
let count = unit
|
||||
.blocks()
|
||||
.filter(|x| {
|
||||
let bb_name = unit.get_block_name(*x);
|
||||
bb_name.is_some() && bb_name.unwrap().to_string().starts_with("if_true")
|
||||
})
|
||||
.count();
|
||||
|
||||
if count > 0 {
|
||||
(format!("if_true{}", count), format!("if_false{}", count))
|
||||
} else {
|
||||
|
|
|
@ -163,6 +163,10 @@ impl ModuleDeclaration {
|
|||
}
|
||||
|
||||
context.module.add_unit(entity_data);
|
||||
debug!(
|
||||
"module codegen >>>>>>>>>\n{}<<<<<<<<<",
|
||||
context.module.dump()
|
||||
);
|
||||
|
||||
context.module
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue