diff --git a/src/StmtToHTML.cpp b/src/StmtToHTML.cpp index cd72ecabfdf1..030c56618e92 100644 --- a/src/StmtToHTML.cpp +++ b/src/StmtToHTML.cpp @@ -1066,7 +1066,12 @@ class HTMLCodePrinter : public IRVisitor { } void print(const Expr &ir) { + static int depth = 0; + depth++; + print_opening_tag("span", "expr-depth-" + std::to_string(depth)); ir.accept(this); + print_closing_tag("span"); + depth--; } void print(const Stmt &ir) { @@ -1103,7 +1108,7 @@ class HTMLCodePrinter : public IRVisitor { // Prints the closing tag for the specified html element. void print_closing_tag(const std::string &tag) { internal_assert(!context_stack.empty() && tag == context_stack_tags.back()) - << tag << " " << context_stack.empty() << " " << context_stack_tags.back(); + << "closing tag: " << tag << ", stack size: " << context_stack.size() << ", last element: " << (context_stack_tags.empty() ? "null" : context_stack_tags.back()); context_stack.pop_back(); context_stack_tags.pop_back(); stream << ""; @@ -1243,10 +1248,7 @@ class HTMLCodePrinter : public IRVisitor { } void print_function_call(const std::string &fn_name, const std::vector &args, const std::string &tooltip) { - print_opening_tag("span", "matched"); - print_html_element("span", "Symbol matched", fn_name, tooltip); - print_text("("); - print_closing_tag("span"); + print_html_element("span", "Symbol matched", fn_name + "(", tooltip); bool print_delim = false; for (const auto &arg : args) { if (print_delim) { @@ -1478,15 +1480,11 @@ class HTMLCodePrinter : public IRVisitor { } void visit(const Min *op) override { - print_opening_tag("span", "Min"); print_function_call("min", {op->a, op->b}, type_to_string(op->type)); - print_closing_tag("span"); } void visit(const Max *op) override { - print_opening_tag("span", "Max"); print_function_call("max", {op->a, op->b}, type_to_string(op->type)); - print_closing_tag("span"); } void visit(const EQ *op) override { @@ -1539,10 +1537,21 @@ class HTMLCodePrinter : public IRVisitor { int id = gen_node_id(op); print_opening_tag("span", "Load", "load-" + std::to_string(id)); print_opening_tag("span", "matched", type_str); + if (op->is_streaming) { + print_html_element("span", "keyword", "streaming "); + } stream << variable(op->name, type_to_string(op->type) + "*"); print_text("["); print_closing_tag("span"); print(op->index); + if (op->alignment.modulus != 1) { + print_opening_tag("span", "Alignment"); + stream << " aligned(" + << op->alignment.modulus + << ", " + << op->alignment.remainder << ")"; + print_closing_tag("span"); + } print_html_element("span", "matched", "]", type_str); if (!is_const_one(op->predicate)) { print_html_element("span", "keyword", " if "); @@ -1575,18 +1584,20 @@ class HTMLCodePrinter : public IRVisitor { void visit(const Let *op) override { scope.push(op->name, gen_unique_id()); - print_opening_tag("span", "Let"); + print_opening_tag("div", "Let"); print_opening_tag("span", "matched"); - print_text("("); print_html_element("span", "keyword", "let "); print_variable(op->name, op->type); print_html_element("span", "Operator Assign", " = "); print_closing_tag("span"); print(op->value); print_html_element("span", "matched keyword", " in "); - print(op->body); - print_html_element("span", "matched", ")"); - print_closing_tag("span"); + print_closing_tag("div"); + if (const Let *let = op->body.as()) { + visit(let); // flatten the let chain + } else { + print(op->body); + } scope.pop(op->name); } @@ -1770,7 +1781,7 @@ class HTMLCodePrinter : public IRVisitor { } void visit(const Store *op) override { - // Start a dive to hold code for this acquire + // Start a dive to hold code for this store print_opening_tag("div", "Store WrapLine"); // Print cost buttons @@ -1779,22 +1790,40 @@ class HTMLCodePrinter : public IRVisitor { std::string type_str = type_to_string(op->value.type()); // Print store target + if (!is_const_one(op->predicate)) { + print_html_element("span", "keyword matched", "predicate "); + print(op->predicate); + print_opening_tag("div", "indent"); // Indent + } print_opening_tag("span", "matched", type_str); + if (op->is_streaming) { + print_html_element("span", "keyword", "streaming "); + } stream << variable(op->name, type_str + "*"); print_text("["); print_closing_tag("span"); print(op->index); + if (op->alignment.modulus != 1) { + print_opening_tag("span", "Alignment"); + stream << " aligned(" + << op->alignment.modulus + << ", " + << op->alignment.remainder << ")"; + print_closing_tag("span"); + } print_html_element("span", "matched", "]", type_str); print_html_element("span", "Operator Assign Matched", " = ", type_str); // Print store value print_opening_tag("span", "StoreValue"); print(op->value); + print_closing_tag("span"); if (!is_const_one(op->predicate)) { - print_html_element("span", "keyword", " if "); - print(op->predicate); + print_closing_tag("div"); // Unindent + } + if (op->value.as()) { + print_html_element("div", "EmtpyLine", " "); } - print_closing_tag("span"); // Close div holding this store print_closing_tag("div"); @@ -2505,8 +2534,9 @@ class PipelineHTMLInspector { // IR settings stream << "
IR:\n"; stream << " \n"; - stream << " \n"; - stream << " \n"; + stream << " \n"; + stream << " \n"; + stream << " \n"; stream << "
\n"; // Which panes to show @@ -2522,6 +2552,7 @@ class PipelineHTMLInspector { // Color theme stream << "
Theme:\n"; stream << " \n"; + stream << " \n"; stream << " \n"; stream << " \n"; stream << "\n"; diff --git a/src/irvisualizer/html_template_StmtToHTML.css b/src/irvisualizer/html_template_StmtToHTML.css index c33b308f5ecc..eec04e5cc135 100644 --- a/src/irvisualizer/html_template_StmtToHTML.css +++ b/src/irvisualizer/html_template_StmtToHTML.css @@ -1,14 +1,12 @@ /* General CSS Rules*/ * { - --font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; - font-size: 12px; - font-family: Consolas, 'Fira Code',Courier New,Monaco,Andale Mono,Ubuntu Mono,monospace; + font-size: 13px; + font-family: monospace; } body { padding: 0; margin: 0; - line-height: 14px; } [data-theme="classic-light"] { @@ -26,7 +24,7 @@ body { --fg1: #333; --red: #c00; --orange: #a50; - --yellow: #bb0; + --yellow: #880; --green: #080; --aqua: #099; --blue: #01a; @@ -53,6 +51,49 @@ body { --cost-Lf: 1.0; } + +[data-theme="classic-dark"] { + --bg-color: #000; + --fg-color: #fff; + + --bg0: #111; + --bg1: #222; + --bg2: #333; + --bg3: #444; + --bg4: #555; + --bg5: #111; + + --fg0: #fff; + --fg1: #eee; + --red: #f00; + --orange: #f80; + --yellow: #ff0; + --green: #080; + --aqua: #0ff; + --blue: #35f; + --purple: #d4b; + + + --bg_diff_green: #e4edc8; + --bg_visual_green: #dde5c2; + --bg_diff_red: #f8e4c9; + --bg_visual_red: #f0ddc3; + --bg_diff_blue: #e0e9d3; + --bg_visual_blue: #d9e1cc; + --bg_visual_yellow: #f9eabf; + --bg_current_word: #f3eac7; + + --bg_red: #a55; + --bg_green: #4b4; + --bg_yellow: #ca0; + + --grey0: #888; + --grey1: #aaa; + --grey2: #ccc; + + --cost-Lf: 1.0; +} + [data-theme="gruvbox-light"] { --bg-color: #f9f5d7; --fg-color: #654735; @@ -152,6 +193,7 @@ body { --cs-line-num: var(--grey0); --cs-register: var(--orange); --cs-variable: var(--grey2); + --cs-alignment: var(--yellow); } @@ -162,13 +204,17 @@ span.UIntImm { color: var(--cs-uint); } span.FloatImm { color: var(--cs-float); } span.StringImm { color: var(--cs-str); } span.Type { color: var(--cs-type); font-weight: bold; } -span.Symbol { color: var(--cs-symbol); } span.Assign { color: var(--cs-operator); } span.Comment { color: var(--cs-comment); font-style: italic; } -span.Operator { color: var(--cs-operator); } +span.Alignment { color: var(--cs-alignment); opacity: 0.75; } #ir-code-pane b.variable { color: var(--cs-variable); } #device-code-pane b.variable { color: var(--cs-register); } +[data-rainbow-parens="false"] { + span.Operator { color: var(--cs-operator); } + span.Symbol { color: var(--cs-symbol); } +} + b.Highlight, b.Highlight * { font-weight: bold; background-color: var(--bg_yellow) !important; @@ -255,6 +301,20 @@ span.Label b { background-color: var(--bg_visual_red); font-weight: bold !import } +[data-rainbow-parens="true"] { + #ir-code-pane { + color: var(--aqua); + span.expr-depth-1 { color: var(--red); } + span.expr-depth-2 { color: var(--blue); } + span.expr-depth-3 { color: var(--green); } + span.expr-depth-4 { color: var(--yellow); } + span.expr-depth-5 { color: var(--purple); } + span.expr-depth-6 { color: var(--aqua); } + span.expr-depth-7 { color: var(--orange); } + span.expr-depth-8 { color: var(--green); } + } +} + a, a:hover, a:visited, @@ -510,7 +570,7 @@ div.For { border-radius: 8px; } div.For.for-type-parallel, div.For.for-type-gpu_block { min-width: fit-content; - background-color: rgba(240, 200, 0, 0.03); + background-color: rgba(240, 200, 0, 0.04); border: 3px solid rgba(240, 200, 0, 0.10); margin: 0.2em 0.0em; padding: 0.1em; @@ -525,7 +585,7 @@ div.For.for-type-gpu_block div.For.for-type-gpu_block { padding: 0; } div.For.for-type-gpu_thread { - background-color: rgba(240, 100, 50, 0.03); + background-color: rgba(240, 100, 50, 0.04); border: 3px solid rgba(240, 100, 50, 0.10); margin: 0.2em 0.0em; padding: 0.1em; @@ -644,16 +704,17 @@ div.icon-btn { margin-right: 0px; width: 24px; height: 12px; - line-height: 16px; vertical-align: middle; + position: relative; background: transparent; - font-size: 22px; + font-size: 20px; outline: 1px solid black; top: -1px; border-radius: 4px; display: inline-block; text-align: center; box-sizing: border-box; + line-height: 10px; } div.icon-btn:before { margin: 0; @@ -746,8 +807,16 @@ div.Evaluate:before { } } +div.EmptyLine { + visibility: hidden; +} +div.Let { + display: block; + padding-left: 15px; +} + .tooltip-parent { - position: relative; + position: absolute; overflow: visible; } @@ -756,10 +825,10 @@ span.tooltip { color: black; font-weight: normal; visibility: hidden; + position: absolute; left: 50px; top: -10px; width: max-content; - position: relative; display: block; padding: 8px; background: #fff7e0; diff --git a/src/irvisualizer/html_template_StmtToHTML.js b/src/irvisualizer/html_template_StmtToHTML.js index fe803673a087..f5792517e5c1 100644 --- a/src/irvisualizer/html_template_StmtToHTML.js +++ b/src/irvisualizer/html_template_StmtToHTML.js @@ -228,6 +228,7 @@ function initToolbar() { make_toggler(document.getElementsByName("checkbox-show-ir-line-nums")[0], "data-show-line-nums", false); make_toggler(document.getElementsByName("checkbox-show-ir-costs")[0], "data-hide-cost", true); make_toggler(document.getElementsByName("checkbox-show-ir-wrap")[0], "data-wrap", false); + make_toggler(document.getElementsByName("checkbox-rainbow-parens")[0], "data-rainbow-parens", false); /* Hiding panes */ make_toggler(document.getElementsByName("checkbox-show-ir")[0], "data-show-ir", false);