mirror of
https://github.com/alex-s168/website.git
synced 2025-09-10 09:05:08 +02:00
more content
This commit is contained in:
36
common.typ
36
common.typ
@@ -212,6 +212,22 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#let spoiler(content) = {
|
||||||
|
[#context if is-html() {
|
||||||
|
html-style(class:"hide", "", content)
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
#let inline-block(content) = {
|
||||||
|
[#context if is-html() {
|
||||||
|
html-style("white-space:nowrap;", content)
|
||||||
|
} else {
|
||||||
|
block(breakable:false, content)
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
#let table-of-contents() = {
|
#let table-of-contents() = {
|
||||||
html-style(class:"table-of-contents", "", box(
|
html-style(class:"table-of-contents", "", box(
|
||||||
stroke: black,
|
stroke: black,
|
||||||
@@ -235,14 +251,18 @@
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
])) + html-style(class:"table-of-contents", "", html-script-dom-onload("
|
])) + html-style(class:"table-of-contents", "", html-script-dom-onload("
|
||||||
let tags = ['h2','h3','h4'].flatMap(x => Array.from(document.getElementsByTagName(x)));
|
let tags = ['h2', 'h3', 'h4'].flatMap(x => Array.from(document.getElementsByTagName(x))).sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top);
|
||||||
document.getElementById('headingr-0').classList.add('current')
|
let pageHeight = document.documentElement.scrollHeight-window.innerHeight;
|
||||||
document.addEventListener('scroll', (event) => {
|
document.addEventListener('scroll', (event) => {
|
||||||
let curr = tags.map(x => [x, (x.getBoundingClientRect().top + x.getBoundingClientRect().bottom) / 2]).filter(x => x[1] >= 0).sort((a,b) => a[1] > b[1])[0][0];
|
let progress = -(document.documentElement.getBoundingClientRect().y / pageHeight);
|
||||||
let idx = tags.sort((a,b) => a.getBoundingClientRect().top > b.getBoundingClientRect().top).map((x, idx) => [idx, x]).filter(x => x[1] == curr)[0][0];
|
let delta = progress * window.innerHeight;
|
||||||
Array.from(document.getElementsByClassName('headingr')).map(x => x.classList.remove('current'))
|
let idx = tags.map(x => 0 > x.getBoundingClientRect().top - delta).lastIndexOf(true);
|
||||||
document.getElementById('headingr-'+idx).classList.add('current')
|
Array.from(document.getElementsByClassName('headingr')).map(x => x.classList.remove('current'));
|
||||||
});
|
if (idx != -1) {
|
||||||
|
document.getElementById('headingr-' + idx).classList.add('current');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
") + [
|
") + [
|
||||||
#context if is-html() {
|
#context if is-html() {
|
||||||
html.elem("style", "
|
html.elem("style", "
|
||||||
|
@@ -59,7 +59,7 @@
|
|||||||
Doing pattern matching this way has many disadvantages.
|
Doing pattern matching this way has many disadvantages.
|
||||||
|
|
||||||
\
|
\
|
||||||
Some (but not all) disadvantages:
|
Some (but not all):
|
||||||
- debugging pattern match rules can be hard
|
- debugging pattern match rules can be hard
|
||||||
- IR rewrites need to be tracked manually (for debugging)
|
- IR rewrites need to be tracked manually (for debugging)
|
||||||
- source locations and debug information also need to be tracked manually, which often isn't implemented very well.
|
- source locations and debug information also need to be tracked manually, which often isn't implemented very well.
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
- the compiler could AOT compile patterns
|
- the compiler could AOT compile patterns
|
||||||
- the compiler could optimize, analyze, and combine patterns to reduce compile time.
|
- the compiler could optimize, analyze, and combine patterns to reduce compile time.
|
||||||
- IR (de-)serialization infrastructure in the compiler can also be used to exchange peephole optimizations.
|
- IR (de-)serialization infrastructure in the compiler can also be used to exchange peephole optimizations.
|
||||||
- bragging rights: your compiler represents it's own patterns in it's own IR
|
- bragging rights: your compiler represents its patterns in it's own IR
|
||||||
]
|
]
|
||||||
|
|
||||||
#section[
|
#section[
|
||||||
@@ -177,6 +177,29 @@
|
|||||||
The advantage of this over just having a rewrite dialect is that it makes patterns even more readable (and maintainable!)
|
The advantage of this over just having a rewrite dialect is that it makes patterns even more readable (and maintainable!)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#section[
|
||||||
|
== egg
|
||||||
|
Some people might say: "bUt Im JuSt GoInG tO uSe EgG, i DoNt NeEd A pAtTeRn MaTcHiNg DiAlEcT"
|
||||||
|
(specifically #spoiler[otesunki] said something like that)
|
||||||
|
|
||||||
|
#flink("https://egraphs-good.github.io/")[egg] is a IR pattern matching and transformation library
|
||||||
|
that uses #inline-block(flink("https://en.wikipedia.org/wiki/E-graph")[E-Graphs]) to
|
||||||
|
magically solves (almost) all problems regarding IR pattern matching.
|
||||||
|
|
||||||
|
Even though egg solves most problems, I still recommend using a pattern matching dialect, especially in multi-level compilers,
|
||||||
|
to be more flexible, and have more future-proof pattern matching, if for example there suddenly is a better alternative to egg,
|
||||||
|
or you decide that you want to match some complex patterns manually.
|
||||||
|
]
|
||||||
|
|
||||||
|
#section[
|
||||||
|
A problem with using egg in combination with pattern matching dialects is that it might be harder
|
||||||
|
to write the code to convert the pattern matching dialect to egg patterns.
|
||||||
|
|
||||||
|
Additionally, some more complex transformations (not the matches) can't always be directly converted to egg transformations
|
||||||
|
(depending on the feature set provided by the transformation dialect),
|
||||||
|
but that can be solved by using a custom ```rust egg::Applier```
|
||||||
|
]
|
||||||
|
|
||||||
#section[
|
#section[
|
||||||
= More Advantages of Structured Pattern Matching
|
= More Advantages of Structured Pattern Matching
|
||||||
|
|
||||||
@@ -192,7 +215,7 @@
|
|||||||
#section[
|
#section[
|
||||||
== Reversible Transformations
|
== Reversible Transformations
|
||||||
I don't think that there currently is any compiler that does this.
|
I don't think that there currently is any compiler that does this.
|
||||||
If you do know one, again, please #flink(alex_contact_url)[contact me.]
|
If you do know one, again, please contact me.
|
||||||
]
|
]
|
||||||
|
|
||||||
#section[
|
#section[
|
||||||
@@ -207,7 +230,7 @@
|
|||||||
#section[
|
#section[
|
||||||
This is not just the case for "low-level" things like bit tests, but also high level concepts,
|
This is not just the case for "low-level" things like bit tests, but also high level concepts,
|
||||||
like a reduction over an array, or even the implementation of a whole algorithm.
|
like a reduction over an array, or even the implementation of a whole algorithm.
|
||||||
For example LLVM, since recently, can detect implementations of #flink("https://en.wikipedia.org/wiki/Cyclic_redundancy_check")[CRC].
|
For example LLVM, since recently, can detect implementations of #flink("https://en.wikipedia.org/wiki/Cyclic_redundancy_check")[CRC.]
|
||||||
]
|
]
|
||||||
|
|
||||||
#section[
|
#section[
|
||||||
@@ -244,6 +267,54 @@
|
|||||||
I don't think any compiler currently does this either.
|
I don't think any compiler currently does this either.
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#section[
|
||||||
|
= Problems with Pattern Matching
|
||||||
|
The main problem is ordering the patterns.
|
||||||
|
|
||||||
|
As an example, consider these three patterns:
|
||||||
|
#context html-frame[```lisp
|
||||||
|
;; A
|
||||||
|
(add x:Const y) => (add y x)
|
||||||
|
|
||||||
|
;; B
|
||||||
|
(sub (add x y:Const) z:Const) => (lea x y (const_neg z))
|
||||||
|
|
||||||
|
;; C
|
||||||
|
(add x 1) => (inc x)
|
||||||
|
```]
|
||||||
|
]
|
||||||
|
|
||||||
|
#section[
|
||||||
|
Now what should the compiler do when it sees this?
|
||||||
|
#context html-frame[```lisp (sub (add 5 1) 2)```]
|
||||||
|
]
|
||||||
|
|
||||||
|
#section[
|
||||||
|
All three patterns would match:
|
||||||
|
#context html-frame[```lisp
|
||||||
|
;; apply A
|
||||||
|
(sub (add 5 1) 2) => (sub (add 1 5) 2)
|
||||||
|
;; only B applies now
|
||||||
|
(sub (add 1 5) 2) => (lea 1 5 (const_neg 2))
|
||||||
|
;; nothing applies anymore
|
||||||
|
|
||||||
|
;; alternatively apply B
|
||||||
|
(sub (add 5 1) 2) => (lea 5 1 (const_neg 2))
|
||||||
|
;; nothing applies anymore
|
||||||
|
|
||||||
|
;; atlernatively apply C
|
||||||
|
(sub (add 5 1) 2) => (sub (inc 5) 2)
|
||||||
|
;; nothing applies anymore
|
||||||
|
```]
|
||||||
|
]
|
||||||
|
|
||||||
|
#section[
|
||||||
|
Now which of those transformations should be performed?
|
||||||
|
|
||||||
|
This is not as easy to solve as it seems, especially in the context of instruction selection (specifically scheduling),
|
||||||
|
where the performance on processors depends on a sequence of instructions, instead of just a single instruction.
|
||||||
|
]
|
||||||
|
|
||||||
#section[
|
#section[
|
||||||
= Conclusion
|
= Conclusion
|
||||||
One can see how pattern matching dialects are the best option by far.
|
One can see how pattern matching dialects are the best option by far.
|
||||||
|
@@ -60,6 +60,9 @@
|
|||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hide { display: inline; background: black; transition: background 0.3s linear; }
|
||||||
|
.hide:hover, .hide:focus { background: transparent; }
|
||||||
")
|
")
|
||||||
}],
|
}],
|
||||||
)),
|
)),
|
||||||
|
Reference in New Issue
Block a user