3,108 karma · joined February 21, 2007
LLVM is a mostly corporate-sponsored open source project. There isn't really a global LLVM roadmap, and developers usually work on things that help their employers.
There has rarely been explicit opposition to features that help other languages, but at the same time it is very difficult to make a large nontrivial change to LLVM at this point. Someone who is not already an active LLVM developer might be overwhelmed and give up on upstreaming their changes. IMO the most successful use of LLVM for a sufficiently non-C++ language has been Azul's work on last-tier JIT compilation using LLVM:
https://llvm.org/devmtg/2017-10/#talk12
> And specifically, what sway does Rust hold on the LLVM project and its goals?
As far as I can tell (and this may be a bit out-of-date), basically none.
Back when Rust was announced, it was much more similar to Go than it is now, even having a similar runtime for concurrency. Go did a better job than Rust of delivering this paradigm, largely because the Go implementors weren't relying on commodity technologies like LLVM and libuv.
As time went on, Rust was given more support by Mozilla, and it evolved into something more suited for browser implementation. It had other major influences at this point:
- The constraints of using LLVM. Many projects have failed trying to make LLVM do something that it's bad at doing. At the end of the day, LLVM is good at compiling C++ and things that look like C++, so if you stick to using LLVM and want an efficient language, your language will end up looking more like C++ over time.
- The swell of momentum around C++11. All of a sudden, programming idioms from the "Modern C++" movement were becoming mainstream.
- The halo of academic research into type-safe systems languages. Very few of the ideas in Rust are new, but some type system features from academia became more palatable for ordinary programmers when combined with the C++11 style.
If you look at the resulting binaries, they don't work as well as you might think.
C++ lends itself to bloated binaries. Template instantiations are duplicated even for types where the instantiations could have identical code. Compilers have traditionally favored overly aggressive inlining over whole-program optimization.
Rust didn't solve the problem; it just duplicated the C++ approach, and made it worse by effectively compiling with the equivalent of C++ exceptions enabled. The next great systems language should target binary size and CPU frontend overhead.
- R0s for interventions are guesses, in some cases informed by data. There is no historical precedent for what is going on right now to draw from.
- The default R0 used in this model is an average. The model does not adjust for the population density, culturally-determined interaction frequency and closeness, humidity, temperature, etc in calculating R0.
- This is not a node-based analysis, and thus assumes everyone spreads the disease at the same rate. In practice, there are some folks who are “super-spreaders,” and others who are almost isolated. Interventions should be targeted primarily at those most likely to spread the disease.
Are there any epidemiologists using less naive statistical models who are producing easily readable results like this? The "average R0" logistic function model seems better suited for examining historical epidemics than estimating risk to inform decision-making for ongoing epidemics.
https://www.the-scientist.com/news-opinion/where-coronavirus... https://www.the-scientist.com/notebook/why-bats-make-such-go... http://nature.com/articles/doi:10.1038/nature22975
The research on Chinese coronavirus outbreaks indicates that bats are a large reservoir for these viruses, and they frequently infect other animals, but it is difficult to pinpoint the final jump to humans exactly. Given the unique status of bats in this regard, it's probably best to keep live ones away from humans or other animals intended for human consumption.
As far as I understand things (which is only from reading articles and watching YouTube videos of people visiting these markets), most of the animals like bats, civets, pangolins, etc. that are implicated in zoonotic diseases are delicacies rather than staples. If they were banned, nobody would starve.
One of the cool techniques we used in earlier versions of JSC (although someone told me it's been dialed back since then) was caching property accesses / method calls in the bytecode interpreter. This technique ended up getting published by someone else in a different context:
https://web.cs.upb.de/cp/download.py?key=ecoop10
I think there's more to be explored along these lines.
The funclet approach (in more ordinary terminology) is to ensure that the stack difference from function invocation upon entry to a basic block is the same across entries to that basic block, and that those additional stack entries all have the same (statically specified) type in each invocation. This is very natural when generating code from an SSA optimizer.
Java bytecode traditionally didn't contain any of this branch target or type information, and required the bytecode verifier to do an iterative combined control/data-flow analysis. Even now that they added some of that type information with stack maps, it's still more complicated than it needs to be due to the historical legacy of this approach.
Obviously, since JS doesn't support arbitrary control flow, Emscripten/Asm.js would need to convert to some simplified form of control flow (although not necessarily fully structured). It seems that this solution was carried over to WebAssembly without much deep thought given.
There does seem to be some backwards association with Java's bytecode verification complexity issues (which are the result of a bad design, not unstructured control flow). In the big GitHub Issue (https://github.com/WebAssembly/design/issues/796) on the topic, one of the core V8 developers even claims that the Java experience justifies the WebAssembly decision. However, the funclets proposal for WebAssembly (https://github.com/WebAssembly/funclets/blob/master/proposal...) shows that you can support arbitrary control flow with linear time verification if you choose a different design than Java.
Most important instructions map 1:1 to CPU micro-ops, with memory operands (on x86) being mapped to separate load/store micro-ops. There are cases where instructions map to long sequences (e.g. VMENTER) or get combined into one micro-op (e.g. compare-and-branch), but this is far from a JIT compiler.
With the C++ memory model you can make std::atomic<char> larger than char. A lot of code assumes that this is not the case and that it is possible to cast between the two, but it's (surprise) undefined behavior.
Would Facebook really let somebody do this to every external frontend server on a Sunday without some boring authorization first? The authorization could simply be denied with a boilerplate response about the right way to do things, with less emotional resources spent than the author apparently did.