diff --git a/Cargo.lock b/Cargo.lock
index 7a380e2ad8..0e48061e34 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,12 +2,40 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
+[[package]]
+name = "cpufeatures"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
 [[package]]
 name = "datafrog"
 version = "2.0.1"
@@ -20,12 +48,38 @@ version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
 
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
 [[package]]
 name = "fixedbitset"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
 
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.149"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
+
 [[package]]
 name = "log"
 version = "0.4.14"
@@ -35,12 +89,69 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "memchr"
+version = "2.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
+
+[[package]]
+name = "once_cell"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+
 [[package]]
 name = "ordermap"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
 
+[[package]]
+name = "pest"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4"
+dependencies = [
+ "memchr",
+ "thiserror",
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d"
+dependencies = [
+ "once_cell",
+ "pest",
+ "sha2",
+]
+
 [[package]]
 name = "petgraph"
 version = "0.4.13"
@@ -63,6 +174,8 @@ version = "0.7.0"
 dependencies = [
  "diff",
  "log",
+ "pest",
+ "pest_derive",
  "petgraph",
  "pico-args",
  "polonius-engine",
@@ -83,8 +196,92 @@ dependencies = [
 name = "polonius-parser"
 version = "0.5.0"
 
+[[package]]
+name = "proc-macro2"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
+dependencies = [
+ "proc-macro2",
+]
+
 [[package]]
 name = "rustc-hash"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "sha2"
+version = "0.10.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.49"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.49"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+[[package]]
+name = "ucd-trie"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
diff --git a/Cargo.toml b/Cargo.toml
index a5123f12c9..74e6679702 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,5 +19,7 @@ polonius-engine = { path = "./polonius-engine" }
 log             = "0.4"
 petgraph        = "0.4.13"
 pico-args       = "0.2"
+pest = "2.7.4"
+pest_derive = "2.7.4"
 
 [workspace]
diff --git a/src/cli.rs b/src/cli.rs
index 2d1e23ce94..c400219f23 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -13,6 +13,7 @@ use crate::dump;
 use crate::dump::Output;
 use crate::facts::AllFacts;
 use crate::intern;
+use crate::mir_parser;
 use crate::tab_delim;
 
 const PKG_NAME: &str = env!("CARGO_PKG_NAME");
@@ -29,6 +30,7 @@ pub struct Options {
     output_directory: Option<String>,
     fact_dirs: Vec<String>,
     liveness_graph_file: Option<String>,
+    mir_file: Option<String>,
 }
 
 #[derive(Debug)]
@@ -86,7 +88,11 @@ pub fn main(opt: Options) -> Result<(), Error> {
                         .expect("Failed to write output");
                 }
                 if let Some(ref graphviz_file) = graphviz_file {
-                    dump::graphviz(&output, &all_facts, graphviz_file, tables)
+                    let mir = opt
+                        .mir_file
+                        .as_ref()
+                        .map(|x| mir_parser::parse(Path::new(&x)));
+                    dump::graphviz(&output, &all_facts, graphviz_file, tables, &mir)
                         .expect("Failed to write GraphViz");
                 }
                 if let Some(ref liveness_graph_file) = liveness_graph_file {
@@ -169,6 +175,7 @@ ARGS:
         graphviz_file: arg_from_str(&mut args, "--graphviz-file")?,
         output_directory: arg_from_str(&mut args, "-o")?.or(arg_from_str(&mut args, "--output")?),
         liveness_graph_file: arg_from_str(&mut args, "--dump-liveness-graph")?,
+        mir_file: arg_from_str(&mut args, "--mir-file")?,
         fact_dirs: args.free().map_err(readable_pico_error)?,
     };
 
diff --git a/src/dump.rs b/src/dump.rs
index cf7120b917..a5c1bb0b1b 100644
--- a/src/dump.rs
+++ b/src/dump.rs
@@ -504,6 +504,7 @@ pub(crate) fn graphviz(
     all_facts: &AllFacts,
     output_file: &PathBuf,
     intern: &InternerTables,
+    mir: &Option<HashMap<String, Vec<String>>>,
 ) -> io::Result<()> {
     let mut file = File::create(output_file)?;
     let mut output_fragments: Vec<String> = Vec::new();
@@ -522,6 +523,7 @@ pub(crate) fn graphviz(
             &inputs_by_point,
             &outputs_by_point,
             intern,
+            mir,
         )
         .into_iter();
         output_fragments.extend(graphviz_code);
@@ -540,6 +542,7 @@ fn graphviz_for_edge(
     inputs_by_point: &[HashMap<Point, String>],
     outputs_by_point: &[HashMap<Point, String>],
     intern: &InternerTables,
+    mir: &Option<HashMap<String, Vec<String>>>,
 ) -> Vec<String> {
     let mut ret = Vec::new();
     maybe_render_point(
@@ -549,6 +552,7 @@ fn graphviz_for_edge(
         outputs_by_point,
         &mut ret,
         intern,
+        mir,
     );
     maybe_render_point(
         point2,
@@ -557,6 +561,7 @@ fn graphviz_for_edge(
         outputs_by_point,
         &mut ret,
         intern,
+        mir,
     );
     ret.push(format!(
         "\"node{0}\" -> \"node{1}\":f0 [\n  id = {2}\n];\n",
@@ -574,6 +579,7 @@ fn maybe_render_point(
     outputs_by_point: &[HashMap<Point, String>],
     render_vec: &mut Vec<String>,
     intern: &InternerTables,
+    mir: &Option<HashMap<String, Vec<String>>>,
 ) {
     if seen_points.contains(&point.index()) {
         return;
@@ -592,11 +598,24 @@ fn maybe_render_point(
         .collect::<Vec<_>>()
         .join(" | ");
 
-    render_vec.push(format!("\"node{0}\" [\n  label = \"{{ <f0> {1} | INPUTS | {2} | OUTPUTS | {3} }}\"\n  shape = \"record\"\n];\n",
+    let point_str = escape_for_graphviz(Point::table(intern).untern(point));
+    let (bb_name, offset) = extract(&point_str);
+    let instr: String = mir
+        .as_ref()
+        .and_then(|hm| Some(format!("| {}", escape_for_graphviz(&hm[bb_name][offset]))))
+        .unwrap_or_default();
+    render_vec.push(format!("\"node{0}\" [\n  label = \"{{ <f0> {point_str} {instr} | INPUTS | {input_tuples} | OUTPUTS | {output_tuples} }}\"\n  shape = \"record\"\n];\n",
                      point.index(),
-                     escape_for_graphviz(Point::table(intern).untern(point)),
-                     &input_tuples,
-                     &output_tuples));
+                    ));
+}
+
+fn extract(x: &str) -> (&str, usize) {
+    let a = x.find('(').unwrap();
+    let b = x.find('[').unwrap();
+    let c = x.find(']').unwrap();
+    let bb_name = &x[a + 1..b];
+    let offset = &x[b + 1..c];
+    (bb_name, offset.parse().unwrap())
 }
 
 fn escape_for_graphviz(s: &str) -> String {
diff --git a/src/lib.rs b/src/lib.rs
index 3ca862b083..f606b3fc50 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,7 @@
 mod dump;
 mod facts;
 mod intern;
+mod mir_parser;
 mod program;
 mod tab_delim;
 mod test;
diff --git a/src/mir.pest b/src/mir.pest
new file mode 100644
index 0000000000..3faca012b0
--- /dev/null
+++ b/src/mir.pest
@@ -0,0 +1,19 @@
+// no \n . =
+char2 = _{ 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" | "-" | "(" | ")" | "[" | "]" | ":" | " " | "<" | ">" | "&" | "'" | "?" | "," }
+
+block_name = { (!"{" ~ ANY)+ }
+
+// not started with }
+instruction = { (!(NEWLINE | "}") ~ ANY) ~ (! NEWLINE ~ ANY)+ ~ NEWLINE }
+
+header = _{ (scope | instruction) * }
+
+scope = _{ "scope" ~ ASCII_ALPHANUMERIC+ ~ "{" ~ NEWLINE ~ header ~ "}" ~ NEWLINE }
+
+block = { block_name ~ "{" ~ NEWLINE ~ instruction+ ~ "}" ~ NEWLINE* }
+
+func = { SOI ~ "fn" ~ char2+ ~ "{" ~ NEWLINE ~ header ~ NEWLINE* ~ block+ ~ "}" ~ NEWLINE* ~ EOI }
+
+COMMENT = _{ ("//" | "|") ~ (!NEWLINE ~ ANY)* ~ NEWLINE* }
+WHITESPACE = _{ " " | "\t" }
+
diff --git a/src/mir_parser.rs b/src/mir_parser.rs
new file mode 100644
index 0000000000..78203ff4be
--- /dev/null
+++ b/src/mir_parser.rs
@@ -0,0 +1,64 @@
+use pest::Parser;
+use pest_derive::Parser;
+use std::collections::HashMap;
+use std::io::Read;
+use std::path::Path;
+
+#[derive(Parser)]
+#[grammar = "mir.pest"]
+struct MirParser;
+
+pub fn parse(path: &Path) -> HashMap<String, Vec<String>> {
+    let mut file = std::fs::File::open(&path).unwrap();
+    let mut contents = String::new();
+    file.read_to_string(&mut contents).unwrap();
+
+    let mut pairs = MirParser::parse(Rule::func, &contents).unwrap_or_else(|e| panic!("{}", e));
+    let func_pair = pairs.next().unwrap();
+
+    let mut hm = HashMap::new();
+    for pair in func_pair.into_inner() {
+        match pair.as_rule() {
+            Rule::block => {
+                let mut iter = pair.into_inner();
+                let bb = iter.next().unwrap();
+                assert_eq!(bb.as_rule(), Rule::block_name);
+                let bb_name = bb.as_str().replace("(cleanup):", "").replace(':', "");
+                let bb_name = bb_name.trim();
+                let mut v: Vec<String> = Vec::new();
+                for instr in iter {
+                    assert_eq!(instr.as_rule(), Rule::instruction);
+                    v.push(instr.as_str().trim().to_owned());
+                }
+                let None = hm.insert(bb_name.to_owned(), v) else {
+                    unreachable!()
+                };
+            }
+            _ => {}
+        }
+    }
+    hm
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn it_works() {
+        let path = Path::new(env!("HOME"))
+            .join("rust")
+            .join("tests")
+            .join("mir-opt")
+            .join("nll")
+            .join("named_lifetimes_basic.use_x.nll.0.mir");
+        let _ = parse(&path);
+
+        let path = Path::new(env!("HOME"))
+            .join("rust")
+            .join("tests")
+            .join("mir-opt")
+            .join("storage_ranges.main.nll.0.mir");
+        let _ = parse(&path);
+    }
+}