fix flame graph

This commit is contained in:
sfja 2024-12-15 04:24:07 +01:00
parent 28225fde52
commit cee24abfc7
9 changed files with 151 additions and 34 deletions

View File

@ -119,8 +119,10 @@ export class Checker {
throw new Error();
}
const isBuiltin = stmt.kind.anno && stmt.kind.anno.ident === "builtin";
if (isBuiltin) {
if (
stmt.kind.anno?.ident === "remainder" ||
stmt.kind.anno?.ident === "builtin"
) {
return;
}

View File

@ -221,7 +221,7 @@ export class SpecialLoopDesugarer implements AstVisitor {
],
}),
}),
}),
}, cond.pos),
),
Stmt({
type: "expr",

View File

@ -12,6 +12,7 @@ export class Lowerer {
private locals: Locals = new LocalsFnRoot();
private fnStmtIdLabelMap: { [stmtId: number]: string } = {};
private fnLabelNameMap: { [name: string]: string } = {};
private returnStack: Label[] = [];
private breakStack: Label[] = [];
public constructor(private lastPos: Pos) {}
@ -83,7 +84,7 @@ export class Lowerer {
case "break":
return this.lowerBreakStmt(stmt);
case "return":
break;
return this.lowerReturnStmt(stmt);
case "fn":
return this.lowerFnStmt(stmt);
case "let":
@ -128,6 +129,18 @@ export class Lowerer {
}
}
private lowerReturnStmt(stmt: Stmt) {
if (stmt.kind.type !== "return") {
throw new Error();
}
if (stmt.kind.expr) {
this.lowerExpr(stmt.kind.expr);
}
this.addClearingSourceMap();
this.program.add(Ops.PushPtr, this.returnStack.at(-1)!);
this.program.add(Ops.Jump);
}
private lowerBreakStmt(stmt: Stmt) {
if (stmt.kind.type !== "break") {
throw new Error();
@ -155,6 +168,9 @@ export class Lowerer {
const fnRoot = new LocalsFnRoot(outerLocals);
const outerProgram = this.program;
const returnLabel = this.program.makeLabel();
this.returnStack.push(returnLabel);
this.program = new Assembler();
this.locals = fnRoot;
for (const { ident } of stmt.kind.params) {
@ -162,11 +178,16 @@ export class Lowerer {
}
if (stmt.kind.anno?.ident === "builtin") {
this.lowerFnBuiltinBody(stmt.kind.anno.values);
} else if (stmt.kind.anno?.ident === "remainder") {
this.program.add(Ops.Remainder);
} else {
this.lowerExpr(stmt.kind.body);
}
this.locals = outerLocals;
this.returnStack.pop();
this.program.setLabel(returnLabel);
const localAmount = fnRoot.stackReserved() -
stmt.kind.params.length;
for (let i = 0; i < localAmount; ++i) {
@ -224,7 +245,7 @@ export class Lowerer {
case "int":
return this.lowerIntExpr(expr);
case "bool":
break;
return this.lowerBoolExpr(expr);
case "string":
return this.lowerStringExpr(expr);
case "ident":
@ -300,6 +321,13 @@ export class Lowerer {
this.program.add(Ops.PushInt, expr.kind.value);
}
private lowerBoolExpr(expr: Expr) {
if (expr.kind.type !== "bool") {
throw new Error();
}
this.program.add(Ops.PushBool, expr.kind.value);
}
private lowerStringExpr(expr: Expr) {
if (expr.kind.type !== "string") {
throw new Error();
@ -375,6 +403,12 @@ export class Lowerer {
return;
}
}
if (vtype.type === "bool") {
if (expr.kind.binaryType === "or") {
this.program.add(Ops.Or);
return;
}
}
throw new Error(
`unhandled binaryType` +
` '${vtypeToString(expr.vtype!)}' aka. ` +

View File

@ -0,0 +1,24 @@
fn ten_times() {
for (let i = 0; i < 10; i += 1) {
}
}
fn twenty_times() {
let i = 0;
loop {
if not (i < 20) {
break;
}
i += 1;
}
}
fn main() {
loop {
ten_times();
twenty_times();
}
}

80
examples/primes_10000.slg Normal file
View File

@ -0,0 +1,80 @@
fn remainder(left: int, right: int) -> int #[remainder()] {}
fn int_to_string(v: int) -> string #[builtin(IntToString)] {}
fn string_push_char(str: string, value: int) -> string #[builtin(StringPushChar)] {}
fn string_char_at(str: string, index: int) -> int #[builtin(StringCharAt)] {}
fn string_length(str: string) -> int #[builtin(StringLength)] {}
fn string_to_int(v: string) -> int #[builtin(StringToInt)] {}
fn string_array_new() -> [string] #[builtin(ArrayNew)] {}
fn string_array_push(array: [string], value: string) #[builtin(ArrayPush)] {}
fn string_array_length(array: [string]) -> int #[builtin(ArrayLength)] {}
fn string_array_at(array: [string], index: int) -> string #[builtin(ArrayAt)] {}
fn int_array_new() -> [int] #[builtin(ArrayNew)] {}
fn int_array_push(array: [int], value: int) #[builtin(ArrayPush)] {}
fn int_array_length(array: [int]) -> int #[builtin(ArrayLength)] {}
fn int_array_at(array: [int], index: int) -> int #[builtin(ArrayAt)] {}
fn file_open(filename: string, mode: string) -> int #[builtin(FileOpen)] {}
fn file_close(file: int) #[builtin(FileClose)] {}
fn file_write_string(file: int, content: string) -> int #[builtin(FileWriteString)] {}
fn file_read_char(file: int) -> int #[builtin(FileReadChar)] {}
fn file_read_to_string(file: int) -> string #[builtin(FileReadToString)] {}
fn file_flush(file: int) #[builtin(FileFlush)] {}
fn file_eof(file: int) -> bool #[builtin(FileEof)] {}
fn stdin() -> int { 0 }
fn stdout() -> int { 1 }
fn stderr() -> int { 2 }
fn file_read_line(file: int) -> string {
let line = "";
loop {
if file_eof(file) {
break;
}
let ch = file_read_char(file);
if ch == "\n"[0] {
break;
}
line = string_push_char(line, ch);
}
line
}
fn print(msg: string) #[builtin(Print)] {}
fn println(msg: string) { print(msg + "\n") }
fn input(prompt: string) -> string {
print("> ");
file_flush(stdout());
file_read_line(stdin())
}
//
fn is_prime(n: int) -> bool {
if n == 1 or n == 0{
return false;
}
for (let i = 2; i < n; i += 1) {
if remainder(n, i) == 0 {
return false;
}
}
true
}
fn main() {
for (let i = 1; i < 10000; i += 1) {
if is_prime(i) {
print(int_to_string(i) + " ");
}
}
println("");
}

View File

@ -9,7 +9,7 @@ ifeq ($(RELEASE),1)
CXX_FLAGS = \
-std=c++23 \
-O2 \
-O3 \
-pedantic -pedantic-errors \
-Wall -Wextra -Wpedantic -Wconversion -Werror\

View File

@ -7,8 +7,6 @@
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <format>
#include <iostream>
#include <string>
#include <vector>
@ -89,13 +87,12 @@ private:
inline void calculate_node_midway_result(int64_t ic, size_t node_index)
{
int64_t diff = ic - this->nodes[this->current].ic_start;
this->nodes[this->current].acc += diff;
this->nodes[this->current].ic_start = ic;
// TODO this was a hack, idk if correct
if (node_index == this->nodes[this->current].parent)
int64_t diff = ic - this->nodes[node_index].ic_start;
this->nodes[node_index].acc += diff;
this->nodes[node_index].ic_start = ic;
if (node_index == 0)
return;
calculate_node_midway_result(ic, this->nodes[this->current].parent);
calculate_node_midway_result(ic, this->nodes[node_index].parent);
}
void fg_node_to_json(json::Writer& writer, size_t node_index) const;

View File

@ -1,14 +0,0 @@
fn add(a, b) {
+ a b
}
let result = 0;
let i = 0;
loop {
if >= i 10 {
break;
}
result = add(result, 5);
i = + i 1;
}

View File

@ -346,9 +346,6 @@ async function main() {
view.replaceChildren(outerContainer);
},
"code-coverage": async () => {
if (await data.status().then((r) => r.running)) {
return;
}
const codeCoverageData = await data.codeCoverageData();
const outerContainer = document.createElement("div");
@ -375,9 +372,6 @@ async function main() {
view.replaceChildren(outerContainer, tooltip);
},
"flame-graph": async () => {
if (await data.status().then((r) => r.running)) {
return;
}
const flameGraphData = await data.flameGraphData();
const flameGraphFnNames = await data.flameGraphFnNames();