diff --git a/benchmarks/core/totient.bril b/benchmarks/core/totient.bril new file mode 100644 index 000000000..02ac090e2 --- /dev/null +++ b/benchmarks/core/totient.bril @@ -0,0 +1,66 @@ +# ARGS: 2023 +@main (n: int) { + print n; + tot: int = call @totient n; + print tot; +} + +@totient (n: int): int { + result: int = id n; + p: int = const 2; + one: int = const 1; + zero: int = const 0; + +.for.set.cond: + pp: int = mul p p; + cond: bool = le pp n; + br cond .for.set.body .for.set.end; + +.for.set.body: + + npmod: int = call @mod n p; + if_cond: bool = eq npmod zero; + br if_cond .if_lbl .else_lbl; +.if_lbl: + +.while.set.cond: + + npmod: int = call @mod n p; + while_cond: bool = eq npmod zero; + br while_cond .while.body .while.end; + +.while.body: + npdiv: int = div n p; + n: int = id npdiv; + jmp .while.set.cond; + +.while.end: + + resdiv: int = div result p; + result: int = sub result resdiv; + +.else_lbl: + + p: int = add p one; + jmp .for.set.cond; + +.for.set.end: + + final_if_cond: bool = gt n one; + br final_if_cond .final_if_label .final_else_label; + +.final_if_label: + resdiv: int = div result n; + result: int = sub result resdiv; + +.final_else_label: + + ret result; +} + +@mod (a: int, b: int): int { + ad: int = div a b; + mad: int = mul b ad; + ans: int = sub a mad; + ret ans; +} diff --git a/benchmarks/core/totient.out b/benchmarks/core/totient.out new file mode 100644 index 000000000..0dd06b31d --- /dev/null +++ b/benchmarks/core/totient.out @@ -0,0 +1,2 @@ +2023 +1632 diff --git a/benchmarks/core/totient.prof b/benchmarks/core/totient.prof new file mode 100644 index 000000000..d8c8e70f1 --- /dev/null +++ b/benchmarks/core/totient.prof @@ -0,0 +1 @@ +total_dyn_inst: 253 diff --git a/docs/tools/bench.md b/docs/tools/bench.md index db5b959f9..85086a336 100644 --- a/docs/tools/bench.md +++ b/docs/tools/bench.md @@ -55,6 +55,7 @@ The current benchmarks are: * `sum-bit`: Print the number of 1-bits in the binary representation of the input integer. * `sum-divisors`: Prints the positive integer divisors of the input integer, followed by the sum of the divisors. * `sum-sq-diff`: Output the difference between the sum of the squares of the first *n* natural numbers and the square of their sum. +* `totient`: Computes [Euler's totient function][totient] on an input integer *n*. * `up-arrow`: Computes [Knuth's up arrow][uparrow] notation, with the first argument being the number, the second argument being the number of Knuth's up arrows, and the third argument being the number of repeats. * `vsmul`: Multiplies a constant scalar to each element of a large array. Tests the performance of vectorization optimizations. * `reverse`: Compute number with reversed digits (e.g. 123 -> 321). @@ -87,3 +88,4 @@ Credit for several of these benchmarks goes to Alexa VanHattum and Gregory Yaune [palindrome]: https://en.wikipedia.org/wiki/Palindrome [hanoi]: https://en.wikipedia.org/wiki/Tower_of_Hanoi [euler]: https://en.wikipedia.org/wiki/E_(mathematical_constant) +[totient]: https://en.wikipedia.org/wiki/Euler's_totient_function \ No newline at end of file