Skip to content

Commit

Permalink
[Cider] Barebones integration of the SourceInfoTable (#2398)
Browse files Browse the repository at this point in the history
A quick and dirty integration of the newer sourceinfo into Cider such
that requesting the program counter will display the source filename &
line when available, similar to how it used to work with the embedded
metadata lines.
  • Loading branch information
EclecticGriffin authored Jan 28, 2025
1 parent 3160307 commit b5ea2c0
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 127 deletions.
6 changes: 6 additions & 0 deletions calyx-frontend/src/source_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ impl SourceInfoTable {
&self.position_map[&pos]
}

/// Looks up the source location of the position with the given id. If no
/// such position exists, returns `None`
pub fn get_position(&self, pos: PositionId) -> Option<&SourceLocation> {
self.position_map.get(&pos)
}

/// Iterate over the stored file map, returning a tuple of references to the
/// file id and the path
pub fn iter_file_map(&self) -> impl Iterator<Item = (&FileId, &PathBuf)> {
Expand Down
35 changes: 34 additions & 1 deletion cider/src/debugger/debugger_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,40 @@ impl<C: AsRef<Context> + Clone> Debugger<C> {
.print_watchpoints(self.interpreter.env()),

Command::PrintPC(print_mode) => match print_mode {
PrintCommand::Normal | PrintCommand::PrintCalyx => {
PrintCommand::Normal => {
if let Some(source_info) = &self
.program_context
.as_ref()
.secondary
.source_info_table
{
let mut printed_position = false;
for position in
self.interpreter.env().iter_positions()
{
if let Some(location) =
source_info.get_position(position)
{
println!(
"{}:{}",
source_info
.lookup_file_path(location.file)
.display(),
location.line
);
printed_position = true;
}
}

if !printed_position {
println!("Source info unavailable, falling back to Calyx");
self.interpreter.print_pc();
}
} else {
self.interpreter.print_pc();
}
}
PrintCommand::PrintCalyx => {
self.interpreter.print_pc();
}
PrintCommand::PrintNodes => {
Expand Down
18 changes: 9 additions & 9 deletions cider/src/flatten/flat_ir/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,26 +218,26 @@ impl ComponentCore {
} else if let Some(root) = self.control {
let mut search_stack = vec![root];
while let Some(node) = search_stack.pop() {
match &ctx.primary[node] {
ControlNode::Empty(_) => {}
ControlNode::Enable(e) => {
match &ctx.primary[node].control {
Control::Empty(_) => {}
Control::Enable(e) => {
if ctx.primary[e.group()].assignments.contains(assign) {
return Some(AssignmentDefinitionLocation::Group(
e.group(),
));
}
}
ControlNode::Seq(s) => {
Control::Seq(s) => {
for stmt in s.stms() {
search_stack.push(*stmt);
}
}
ControlNode::Par(p) => {
Control::Par(p) => {
for stmt in p.stms() {
search_stack.push(*stmt);
}
}
ControlNode::If(i) => {
Control::If(i) => {
if let Some(comb) = i.cond_group() {
if ctx.primary[comb].assignments.contains(assign) {
return Some(
Expand All @@ -251,7 +251,7 @@ impl ComponentCore {
search_stack.push(i.tbranch());
search_stack.push(i.fbranch());
}
ControlNode::While(wh) => {
Control::While(wh) => {
if let Some(comb) = wh.cond_group() {
if ctx.primary[comb].assignments.contains(assign) {
return Some(
Expand All @@ -263,10 +263,10 @@ impl ComponentCore {
}
search_stack.push(wh.body());
}
ControlNode::Repeat(r) => {
Control::Repeat(r) => {
search_stack.push(r.body);
}
ControlNode::Invoke(i) => {
Control::Invoke(i) => {
if let Some(comb) = i.comb_group {
if ctx.primary[comb].assignments.contains(assign) {
return Some(
Expand Down
45 changes: 35 additions & 10 deletions cider/src/flatten/flat_ir/control/structures.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use calyx_frontend::source_info::PositionId;
use cider_idx::{impl_index, iter::IndexRange, maps::IndexedMap};
use smallvec::SmallVec;

Expand Down Expand Up @@ -278,7 +279,7 @@ impl Repeat {

/// An enum representing the different types of control nodes. Analogue of [calyx_ir::Control]
#[derive(Debug)]
pub enum ControlNode {
pub enum Control {
/// An empty control node
Empty(Empty),
/// A group enable node
Expand All @@ -297,23 +298,47 @@ pub enum ControlNode {
Invoke(Invoke),
}

impl ControlNode {
impl Control {
/// Returns true if the control node is a leaf node (i.e. invoke, enable, or
/// empty)
pub fn is_leaf(&self) -> bool {
match self {
ControlNode::While(_)
| ControlNode::Repeat(_)
| ControlNode::Seq(_)
| ControlNode::Par(_)
| ControlNode::If(_) => false,
ControlNode::Enable(_)
| ControlNode::Invoke(_)
| ControlNode::Empty(_) => true,
Control::While(_)
| Control::Repeat(_)
| Control::Seq(_)
| Control::Par(_)
| Control::If(_) => false,
Control::Enable(_) | Control::Invoke(_) | Control::Empty(_) => true,
}
}
}

#[derive(Debug)]
pub struct ControlNode {
pub control: Control,
pub pos: Option<Box<[PositionId]>>,
}

impl AsRef<Control> for ControlNode {
fn as_ref(&self) -> &Control {
&self.control
}
}

impl ControlNode {
pub fn positions(&self) -> impl Iterator<Item = PositionId> + '_ {
self.pos.iter().flatten().copied()
}
}

impl std::ops::Deref for ControlNode {
type Target = Control;

fn deref(&self) -> &Self::Target {
&self.control
}
}

// ---------------------

/// An enum indicating whether an entity is entirely local to the given context
Expand Down
32 changes: 21 additions & 11 deletions cider/src/flatten/flat_ir/control/translator.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::collections::HashSet;

use ahash::{HashMap, HashMapExt};
use calyx_frontend::{source_info::PositionId, SetAttr};
use calyx_ir::GetAttributes;
use calyx_ir::{self as cir, NumAttr, RRC};
use cider_idx::iter::IndexRange;
use itertools::Itertools;
Expand Down Expand Up @@ -41,7 +43,7 @@ pub struct GroupMapper {
}

pub fn translate(orig_ctx: &cir::Context) -> Context {
let mut ctx = Context::new();
let mut ctx = Context::new(orig_ctx.source_info_table.clone());

let mut component_id_map = ComponentMapper::new();

Expand Down Expand Up @@ -265,7 +267,7 @@ fn translate_component(
*ctx = taken_ctx;

for node in IndexRange::new(ctrl_idx_start, ctrl_idx_end).iter() {
if let ControlNode::Invoke(i) = &mut ctx.primary.control[node] {
if let Control::Invoke(i) = &mut ctx.primary.control[node].control {
let assign_start_index = ctx.primary.assignments.peek_next_idx();

for (dst, src) in i.signature.iter() {
Expand Down Expand Up @@ -618,20 +620,20 @@ impl FlattenTree for cir::Control {
aux: &Self::AuxiliaryData,
) -> Self::Output {
let (group_map, layout, ctx, comp_info) = aux;
match self {
cir::Control::Seq(s) => ControlNode::Seq(Seq::new(
let ctrl = match self {
cir::Control::Seq(s) => Control::Seq(Seq::new(
s.stmts.iter().map(|s| handle.enqueue(s)),
)),
cir::Control::Par(p) => ControlNode::Par(Par::new(
cir::Control::Par(p) => Control::Par(Par::new(
p.stmts.iter().map(|s| handle.enqueue(s)),
)),
cir::Control::If(i) => ControlNode::If(If::new(
cir::Control::If(i) => Control::If(If::new(
layout.port_map[&i.port.as_raw()],
i.cond.as_ref().map(|c| group_map.comb_groups[&c.as_raw()]),
handle.enqueue(&i.tbranch),
handle.enqueue(&i.fbranch),
)),
cir::Control::While(w) => ControlNode::While(While::new(
cir::Control::While(w) => Control::While(While::new(
layout.port_map[&w.port.as_raw()],
w.cond.as_ref().map(|c| group_map.comb_groups[&c.as_raw()]),
handle.enqueue(&w.body),
Expand Down Expand Up @@ -734,7 +736,7 @@ impl FlattenTree for cir::Control {
);
let comp_done = layout.port_map[&done[0].as_raw()];

ControlNode::Invoke(Invoke::new(
Control::Invoke(Invoke::new(
invoked_cell,
inv.comb_group
.as_ref()
Expand All @@ -746,17 +748,25 @@ impl FlattenTree for cir::Control {
comp_done,
))
}
cir::Control::Enable(e) => ControlNode::Enable(Enable::new(
cir::Control::Enable(e) => Control::Enable(Enable::new(
group_map.groups[&e.group.as_raw()],
)),
cir::Control::Empty(_) => ControlNode::Empty(Empty),
cir::Control::Empty(_) => Control::Empty(Empty),
cir::Control::Static(_) => {
todo!("The interpreter does not support static control yet")
}
cir::Control::Repeat(repeat) => {
let body = handle.enqueue(&repeat.body);
ControlNode::Repeat(Repeat::new(body, repeat.num_repeats))
Control::Repeat(Repeat::new(body, repeat.num_repeats))
}
};

ControlNode {
control: ctrl,
pos: self
.get_attributes()
.get_set(SetAttr::Pos)
.map(|x| x.iter().map(|p| PositionId::new(*p)).collect()),
}
}
}
39 changes: 23 additions & 16 deletions cider/src/flatten/structures/context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::ops::Index;

use calyx_frontend::source_info::SourceInfoTable;
use calyx_ir::Direction;
use cider_idx::{
iter::IndexRange,
Expand Down Expand Up @@ -129,6 +130,8 @@ pub struct SecondaryContext {
pub ref_cell_defs: IndexedMap<RefCellDefinitionIdx, RefCellInfo>,
/// auxiliary information for components
pub comp_aux_info: SecondaryMap<ComponentIdx, AuxiliaryComponentInfo>,
/// Source Info Table
pub source_info_table: Option<SourceInfoTable>,
}

impl Index<Identifier> for SecondaryContext {
Expand Down Expand Up @@ -180,6 +183,18 @@ impl Index<ComponentIdx> for SecondaryContext {
}

impl SecondaryContext {
pub fn new(source_info_table: Option<SourceInfoTable>) -> Self {
Self {
string_table: IdMap::new(),
local_port_defs: Default::default(),
ref_port_defs: Default::default(),
local_cell_defs: Default::default(),
ref_cell_defs: Default::default(),
comp_aux_info: Default::default(),
source_info_table,
}
}

/// Insert a new local port definition into the context and return its index
pub fn push_local_port(
&mut self,
Expand Down Expand Up @@ -228,19 +243,6 @@ impl SecondaryContext {
}
}

impl Default for SecondaryContext {
fn default() -> Self {
Self {
string_table: IdMap::new(),
local_port_defs: Default::default(),
ref_port_defs: Default::default(),
local_cell_defs: Default::default(),
ref_cell_defs: Default::default(),
comp_aux_info: Default::default(),
}
}
}

/// The full immutable program context for the interpreter.
#[derive(Debug)]
pub struct Context {
Expand All @@ -258,7 +260,7 @@ impl Default for Context {
fn default() -> Self {
Self {
primary: Default::default(),
secondary: Default::default(),
secondary: SecondaryContext::new(None),
entry_point: ComponentIdx::new(0),
}
}
Expand All @@ -278,8 +280,13 @@ impl From<(InterpretationContext, SecondaryContext)> for Context {

impl Context {
/// Create a new empty context
pub fn new() -> Self {
Default::default()
pub fn new(source_info_table: Option<SourceInfoTable>) -> Self {
Self {
primary: Default::default(),
secondary: SecondaryContext::new(source_info_table),

entry_point: ComponentIdx::new(0),
}
}

/// Resolve the string associated with the given identifier
Expand Down
Loading

0 comments on commit b5ea2c0

Please sign in to comment.