Skip to content

Commit

Permalink
record: Precise tail-call loop ending checking
Browse files Browse the repository at this point in the history
  • Loading branch information
djwatson committed Oct 3, 2023
1 parent 332a4d8 commit f6fee47
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 27 deletions.
44 changes: 22 additions & 22 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -167,56 +167,56 @@ <h2>Benchmarks</h2>
makechart('puzzle', [1.6299999999996544, 1.5299999713897705, 2.193014, 1.68]);
//makechart('fft', [0.0, 0.9300000071525574, 0.869155, 2.21]);
makechart('dynamic', [1.3899999999998727, 2.3949999809265137, 3.172476, 1.77]);
makechart('ctak', [0.41000000000030923, 16.945999145507812, 1.854662, 3.38]);
makechart('ctak', [0.41000000000030923, 16.945999145507812, 1.854662, 3.29]);
makechart('sum1', [0.7400000000002365, 2.99, 0.762798, 1.79]);
makechart('parsing', [2.0299999999997453, 1.8980000019073486, 1.837709, 2.39]);
makechart('parsing', [2.0299999999997453, 1.8980000019073486, 1.837709, 1.9]);
//makechart('nucleic', [1.6100000000001273, 0.0, 1.365529, 4.33]);
makechart('bv2string', [0.650000000000091, 0.9869999885559082, 1.089267, 0.45]);
makechart('nqueens', [3.519999999999982, 4.40500020980835, 4.38331, 3.4]);
makechart('nqueens', [3.519999999999982, 4.40500020980835, 4.38331, 3.17]);
//makechart('chudnovsky', [0.13000000000010914, 18.4689998626709, 0.268382, 0.0]);
//makechart('mbrot', [4.6899999999996, 4.1479997634887695, 2.052373, 9.19]);
makechart('primes', [0.650000000000091, 0.75, 0.577724, 0.55]);
makechart('cat', [1.3100000000004002, 2.421999931335449, 10.767127, 1.85]);
makechart('cat', [1.3100000000004002, 2.421999931335449, 10.767127, 1.65]);
makechart('tak', [1.1199999999998909, 1.1089999675750732, 1.620081, 1.24]);
//makechart('sumfp', [3.7399999999997817, 0.0, 1.549888, 3.748]);
makechart('triangl', [1.199999999999818, 0.9570000171661377, 1.264036, 0.91]);
makechart('matrix', [1.32, 1.2879999876022339, 1.603249, 1.4]);
makechart('lattice', [2.6600000000003092, 2.4709999561309814, 4.184831, 3.1]);
makechart('triangl', [1.199999999999818, 0.9570000171661377, 1.264036, 0.87]);
makechart('matrix', [1.32, 1.2879999876022339, 1.603249, 1.32]);
makechart('lattice', [2.6600000000003092, 2.4709999561309814, 4.184831, 2.82]);
makechart('browse', [0.9500000000002728, 1.1690000295639038, 1.476638, 0.82]);
makechart('sum', [1.6199999999998909, 1.6970000267028809, 1.363083, 0.86]);
makechart('nboyer', [1.3900000000003274, 1.2589999437332153, 2.450626, 1.56]);
makechart('nboyer', [1.3900000000003274, 1.2589999437332153, 2.450626, 1.82]);
//makechart('quicksort', [0.0, 2.2100000381469727, 3.023306, 12.73]);
makechart('tail', [0.0, 3.299999952316284, 2.195105, 0.24]);
makechart('gcbench', [0.5399999999999636, 0.5889999866485596, 1.04997, 0.65]);
makechart('fib', [2.980000000000018, 2.680999994277954, 2.147171, 2.45]);
makechart('fib', [2.980000000000018, 2.680999994277954, 2.147171, 2.13]);
//makechart('mbrotZ', [3.869999999999891, 13.081999778747559, 7.885695, 0.0]);
makechart('cpstak', [2.130000000000109, 3.247999906539917, 2.585882, 2.35]);
makechart('cpstak', [2.130000000000109, 3.247999906539917, 2.585882, 2.22]);
makechart('maze', [.437, 1.062000036239624, 0.448774, 0.42]);
//makechart('pi', [0.2600000000002183, 0.0, 0.503891, .322]);
makechart('takl', [2.7899999999999636, 1.5609999895095825, 1.751044, 1.88]);
makechart('fibc', [0.30999999999994543, 9.291000366210938, 1.176995, 1.5]);
makechart('takl', [2.7899999999999636, 1.5609999895095825, 1.751044, 1.66]);
makechart('fibc', [0.30999999999994543, 9.291000366210938, 1.176995, 1.71]);
//makechart('ray', [1.7999999999997272, 1.7899999618530273, 1.064618, 5.27]);
makechart('deriv', [0.8800000000001091, 1.7610000371932983, 0.939768, 0.83]);
makechart('ntakl', [2.6599999999998545, 1.5379999876022339, 1.935883, 1.99]);
makechart('deriv', [0.8800000000001091, 1.7610000371932983, 0.939768, 0.78]);
makechart('ntakl', [2.6599999999998545, 1.5379999876022339, 1.935883, 1.53]);
makechart('read1', [0.5199999999999818, 1.9600000381469727, 1.245462, 0.95]);
makechart('slatex', [1.849999999999909, 1.840999960899353, 3.885483, 1.85]);
//makechart('simplex', [1.6700000000000728, 1.3509999513626099, 1.532647, 9.44]);
makechart('string', [2.9100000000003092, 2.611999988555908, 1.703866, 5.04]);
makechart('compiler', [2.2, 1.059000015258789, 0.0, 2.39]);
makechart('sboyer', [0.7400000000002365, 0.6370000243186951, 1.000899, 1.1]);
makechart('scheme', [1.9800000000000182, 1.878999948501587, 4.262164, 1.52]);
makechart('earley', [2.9200000000000728, 0.0, 3.036918, 2.13]);
makechart('string', [2.9100000000003092, 2.611999988555908, 1.703866, 5.41]);
makechart('compiler', [2.2, 1.059000015258789, 0.0, 2.21]);
makechart('sboyer', [0.7400000000002365, 0.6370000243186951, 1.000899, 1.25]);
makechart('scheme', [1.9800000000000182, 1.878999948501587, 4.262164, 1.6]);
makechart('earley', [2.9200000000000728, 0.0, 3.036918, 2.24]);
makechart('peval', [1.400000000000091, 1.8600000143051147, 1.82575, 1.62]);
makechart('ack', [1.9100000000003092, 2.5290000438690186, 2.534312, 1.9]);
makechart('paraffins', [3.363, 1.2400000095367432, 2.397688, 3.37]);
makechart('diviter', [0.9800000000000182, 1.1749999523162842, 1.108788, 1.00]);
makechart('equal', [0.3900000000003274, 1.5759999752044678, 0.234992, 0.2]);
makechart('divrec', [1.6200000000, 1.9700000286102295, 1.559836, 1.59]);
makechart('graphs', [1.3099999999999454, 1.7000000476837158, 5.411687, 1.95]);
makechart('graphs', [1.3099999999999454, 1.7000000476837158, 5.411687, 1.89]);
makechart('mperm', [6.8400000000001455, 4.39300012588501, 4.34869, 5.1]);
makechart('mazefun', [1.5799999999999272, 1.6059999465942383, 2.093023, 1.76]);
makechart('array1', [4.5900000000001455, 1.4989999532699585, 2.981551, 1.96]);
makechart('wc', [0.9400000000000546, 1.5779999494552612, 5.82148, 1.22]);
makechart('array1', [4.5900000000001455, 1.4989999532699585, 2.981551, 2.12]);
makechart('wc', [0.9400000000000546, 1.5779999494552612, 5.82148, 1.10]);
</script>
<script>hljs.highlightAll();</script>
</body>
Expand Down
22 changes: 17 additions & 5 deletions src/record.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ int *regs = &regs_list[1];
snap_s *side_exit = nullptr;
static trace_s *parent = nullptr;
static uint8_t unroll = 0;
static uint8_t tailcalled = 0;
typedef struct {
uint32_t* key;
uint32_t value;
} tailcall_counter;
static tailcall_counter* tailcalled = nullptr;
static uint32_t stack_top;

unsigned int **downrec = NULL;
Expand Down Expand Up @@ -221,6 +225,7 @@ void record_side(trace_s *p, snap_s *side) {

void record_abort();
void record_start(unsigned int *pc, long *frame, long argcnt) {
hmdefault(tailcalled, 0);
trace = malloc(sizeof(trace_s));
trace->syms = NULL;
trace->next = NULL;
Expand All @@ -236,7 +241,6 @@ void record_start(unsigned int *pc, long *frame, long argcnt) {
trace->parent = parent;
trace_state = START;
unroll = 0;
tailcalled = 0;
if (verbose) {
func = (long)find_func_for_frame(pc);
assert(func);
Expand Down Expand Up @@ -317,6 +321,7 @@ void record_stop(unsigned int *pc, long *frame, int link) {
// }

pendpatch();
hmfree(tailcalled);

if (side_exit != nullptr) {
if (verbose)
Expand Down Expand Up @@ -377,6 +382,7 @@ void record_abort() {
arrfree(trace->relocs);
arrfree(trace->ops);
arrfree(trace->snaps);
hmfree(tailcalled);

pendpatch();
free(trace);
Expand Down Expand Up @@ -755,15 +761,15 @@ int record_instr(unsigned int *pc, long *frame, long argcnt) {
// A pile of heuristics, to try and catch traces that are loops, but don't use
// the loop construct.
if (pc == pc_start && parent == NULL) {
if ((cnt + tailcalled) >= UNROLL_LIMIT && depth == 0) {
if ((hmget(tailcalled, pc)) > UNROLL_LIMIT && depth == 0) {
auto link_trace = check_argument_match(frame, trace);
if (link_trace) {
if (verbose)
printf("Record stop loop\n");
record_stop(pc, frame, link_trace->num);
return 1;
}
} else if (cnt >= UNROLL_LIMIT && depth != 0) {
} else if (cnt > UNROLL_LIMIT && depth != 0) {
// Don't test on 'tailcalled' here, since up-recursion
// can't be a tailcall.
auto link_trace = check_argument_match(frame, trace);
Expand Down Expand Up @@ -1004,7 +1010,13 @@ int record_instr(unsigned int *pc, long *frame, long argcnt) {
break;
}
case CALLT: {
tailcalled++;
// Record the tailcall for checking for loop endings.
{
auto clo = (closure_s*)(frame[INS_A(i) + 1] - CLOSURE_TAG);
auto call_pc = &((bcfunc*)clo->v[0])->code[0];
auto v = hmget(tailcalled, call_pc);
hmput(tailcalled, call_pc, v + 1);
}
// Check call type
{
auto clo = record_stack_load(INS_A(i) + 1, frame);
Expand Down

0 comments on commit f6fee47

Please sign in to comment.