polsys / cle Goto Github PK
View Code? Open in Web Editor NEWA native code compiler for a C-like language.
Home Page: https://polsys.github.io/cle/
License: MIT License
A native code compiler for a C-like language.
Home Page: https://polsys.github.io/cle/
License: MIT License
Allow importing functions from DLLs such as the C Runtime via a special attribute.
Import
attribute, and allow not having a method body in annotated methodsEspecially useful with #19, and a prerequisite for doing instance methods with this
references.
BasicBlockGraphBuilder
to perform block renaming and drop dead blocksShould global constants live in the same namespace as functions, or can they be distinguished by the usage? Local variables should certainly shadow global constants.
internal
visibility is respectedNot very high priority, as I can't remember when I last wrote one.
I'll be updating to VS2019 soon after it is released, and since there is no reason to maintain VS2017 compatibility once the CI servers have the latest compilers, we might as well have a bit safer compiler.
The intention is that the IR would always be in SSA form. MethodCompiler
should probably invoke a transformation pass directly after completing the non-SSA IR. This pass would also clean up the basic block graph of dropped blocks.
I think this is worth doing even in non-optimizing builds. The perf impact shouldn't be that bad, and codegen may then take advantage of the SSA guarantees.
Cle.SemanticAnalysis
READMESSA optimizations and IR cleanup should happen in a separate pass for debuggability.
The current allocator is a quick prototype for the initial codegen bringup. It does not support
Implement a proper SSA LSRA algorithm, as described by Wimmer et al.
Related to #15. String would be an immutable UTF-8 array, a special case of the array type. Strings can be created at run time or compile time.
int32::ToString()
)Investigate the best way to interface with the console API: directly consuming C Runtime, a wrapper library, or something else?
Arrays would be a reference type with runtime sizing.
new
causes terminationProbably can leave multidimensional arrays out for now.
this
be a reference or value?)Tracking issue for this TODO comment:
Once #17 is implemented, it should be quite simple to benchmark ExpressionCompiler
without depending on MethodCompiler
and friends. Investigate whether parameter passing (lots of parameters, deep call trees) impacts perf, and whether collecting parameters to an readonly struct speeds things up (and potentially simplifies the code). There might be other low-hanging fruits as well.
Need to benchmark several scenarios:
For example:
if (true) { } // Warning: condition is always true
else { } // Warning: unreachable code
This should be done mostly after modules and some basic optimization phases are in place, to have a realistic benchmark.
The current compiler still allows using void
as variable or parameter type. Add a diagnostic for this.
The Azure Pipelines CI build collects coverage data but does not merge it. It would be nice to see the coverage in the repo. Not very high priority, of course.
Not very high priority, could wait after 0.1.
Support method call parameters and spilled locals on stack. This is also related to #19. This requires small changes to the register allocator and an additional code path for each instruction in the emitter.
As part of #36, the operators &&
and ||
are parsed but not enabled in semantic compilation. I left them disabled because they would introduce control flow to expression compilation. I'm not convinced that the added complexity is worth it, even though the operators are useful. This is not a practical language, after all.
The question therefore is:
Either answer will close this issue.
I do think that the language can do (at least for now) without overloading. This makes parameter type checking simple.
Should be done before #6 because this complicates register allocation.
Related to #15. Parse property (member field access) syntax and compile/emit a Length
field on arrays. The biggest task is refactoring the parser to support member access.
Left this out of the initial implementation as we don't have large enough test cases yet.
The last chunk of the initial vertical slice.
Functional
test casesThe algorithm is designed for on-the-fly SSA conversion, but I did not want to do so in the initial implementation for debuggability. Once the compilation process has stabilized more, SsaConverter
should be removed and the algorithm implemented in SemanticCompiler
. This removes unnecessary allocations from building the IR twice and should give some nice time savings.
Currently, the lowering phase converts high IR to low IR and then the peephole optimizer is run as a separate pass. The optimizer could be converted to a streaming LIR writer: each time the lowering phase would add an instruction, the writer would check for pattern matches.
This could remove unncecessary array shuffling without making the code much more complicated.
Currently the parser stops parsing a file at first error. If in need of a research project, consider implementing enough error recovery to e.g. continue at the next statement/block/function. There are some TODO comments in the parser related to this.
Several common x64 instructions support an immediate, but we emit temporary loads instead:
add
, sub
, imul
)cmp
Either add new LowOp
versions or update the existing ones to contain the immediate in their Data
field (with the right local set to -1
).
Related to #52.
ExpressionCompiler
to handle the types; needs some rule designInitially, the language could do with just double
. Conversions are non-trivial.
ExpressionCompiler
to evaluate floating-point expressionsWould be quite useful additions to while
loops (and #29 too). They were initially left out as they slightly complicate the compilation.
continue
is the easy one, as we know the basic block to jump to,break
needs to jump forward to a block not yet emitted.Replace the quick and dirty front-end with a real, tested command line parser. It should be able to
Write down what the current language is and does, and publish it on GitHub Pages.
ExpressionCompiler
can not do this)The codebase uses System.Collections.ImmutableList<T>
quite a lot, but almost always just builds the list with a builder and then leaves it alone. Consider wrapping List<T>
in a struct and surfacing only the enumerator instead. (Can this be a near-zero cost abstraction, or at least better than passing IReadOnlyList
s around? I'd like to have devirtualized calls if feasible.)
Note that the usage patterns may be slightly different once optimization passes are implemented.
Compiling [ModuleName]...
to indicate progressAdd a short introduction to using Clé to the documentation site. Also fix up the download link mess.
Implement skipping content between //
and newline in lexer.
Emit PDB symbols containing method names. More debug info can be considered later, but the compiler pipeline does not really surface e.g. variable names or sequence points.
&&
ExpressionCompiler
to compile these expressionsThis includes introducing types more properly to expression compilation and opens room for some nice refactoring.
...and while at it, update other dependencies too.
No need to spend over a minute caching packages on a VM that will be destroyed immediately afterwards.
I accidentally committed the change on master
and due to not enforcing branch protections on administrators (now fixed), it got through without a PR (6f4aa93). It successfully disabled the cache but the build step spends more time restoring packages now. Keeping this issue open to track the overall build time across more runs.
As the compiler supports more complex programs, add some performance tests. They should have exactly equivalent implementations in other languages too (C++, C#, Python?). Ideally the tests would be run on every PR but reliability might be an issue.
Some test ideas:
The CI image did not yet have a C# 8 compatible .NET Core SDK. Remove the workaround (re-)introduced in #71 once Azure has caught up.
Some optimizations that could be applied even in non-optimizing builds, since the peephole optimizer covers up a lot of inefficient lowering:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.