Purpose of no-codegen option on crystal build? - debugging

What is purpose of no-codegen option when building crystal project ?
I have quite large codebase and when building without this option, it can take up to 20 seconds to build. When I use no-codegen option, it reduces build time to 6 seconds. But I don't understand can executable be debugged when that option is included (currently I debug using LLDB when building with --debug flag)?

--no-codegen means no code is generated. It does not produce any binary.
The purpose of this flag is to check the validity of a program, without actually building it. This is useful when you can't execute the result anyway, then the binary generation can be skipped. For example, this is used for the code examples in the Crystal repo: They are built in CI with --no-codegen just to check that the code is valid, but verifying their execution is out of scope for automated tests.

In short, it allows to check things are alright, but without generating a binary.
In long, there are four main phases within the Crystal compiler:
Typechecking and macro expansion
Code generation to LLVM
Optimization (by LLVM)
Binary generation (by LLVM)
Each process takes some time. In the first phase, the compiler just checks all the types and expand the macros in your program. In the second phase, the dead code is thrown away, some other language-specific optimizations take place, and the program is generated as LLVM. In the fourth phase (only with --release), Crystal calls LLVM to peform many optimization of the generated code. In the last phase LLVM creates the platform-specific binary.
In your case, it's taking 6s to do typechecking, and ~14s to do all the other phases (but 3).

Related

when does the compiler compile the code into machine code?

As far as I know, the compiler compiles the code by converting it to a language that a computer can understand which is the machine language and this is done before running the code.
So, does the compiler compile my code each time I write a character in the file?
And if so, does it check the whole code? Or just the line that updated.
An important part to this question is the type of programming language(PL) we are talking about. Generally speaking, I would categorize PL into 3 groups:
Traditional PLs. Ex: C, C++, Rust
The compiler compiles the code into machine language when you hit the "build" button or the "run" button.
It doesn't compile every time you change the code, but a code linter does continuously observe your code and check it for errors.
Another note, when you change part of the code and compile it, the compiler doesn't recompile everything. It usually only recompile the current assembly file (or module or whatever you call them).
It is also important to note that a lot of modern IDEs, compile when you save the files.
There is also the hot reload feature. It is a smart compiler feature that can swap certain parts of the code while it is running.
Interpreted PLs Ex: python, JS and PHP
Those languages never get compiled; Rather, they get interpreted or translated into native code on the fly and in-memory when you run them.
Those languages usually employee a cache to accelerate the subsequent code execution.
Intermediary Code PL. Ex: Kotlin, java, C#
Have 2 stages of compilation:
Build time compilation.
Just in time (run-time) compilation.
Build time compilation converts the code into intermediary language (IL) machine code, which is special to the run-time.
This code only understood by the run time like Java runtime or dot net runtime
The second compilation happens when the programs get installed or ran for the first time. This is called just in time compilation (JIT)
The run-time convert the code into native code specific to the run-time OS.

hierarchical compile order with modelsim on command line

I'm trying to compile a VHDL design with modelsim on command line. Is there any way to get an automatical compile order according to the design hierarchy?
I didn't find an option in the documentation of vcom. Only link I found is this, where the solution was to write a brute force script. But it's 10 years ago, so maybe there is anything new. It should be like the option -i of ghdl.
I'm using Altera/Intel Modelsim 18.0 on Linux.
VUnit is an open source tool that will that for you. I recommend the following reading
Installation
Compilation (what you're looking for)
Disclaimer: I'm one of the authors
It seems that in recent versions (tested in ModelSim SE-64 2020.4), vcom supports a new -autoorder parameter, which is described as follows:
Source files can be specified in any order. When all source files can
be specified on a single command line, compilation proceeds in a scan
phase, followed by a refresh phase. To perform the scan phase over
multiple compilations, inhibit the refresh phase with
-noautoorderrefresh. Then perform the refresh phase with -refresh_marked (and omit -autoorder).
Just by adding the -autoorder parameter, I was able to easily compile a large VHDL project with many dependencies, that previously failed due to wrong compile order.

General approach for dry run of building a firmware

Static code analysis tools often watch the build process by inserting their own tool which then runs the normal build process.
Thus the compiling output in the console can be monitored by the specific tool.
Is there a simple, general way to run the compilation process without real compiling. Meaning, not a dedicated solution depending on a specific compiler but a general trick.
The idea would be to reduce the compilation time as only the output is relevant.
Remarks are welcome.
Monica

Visual Studio: use the results of Profile Guided Optimization from one exe to a different dll?

I have a dll, call it core.dll which I want to optimize using Visual Studio's excellent Profile Guided Optimization. Most of the code is the dll actually compiles into a library called core.lib which is then wrapped by core.dll.
To unit-test this code I also have a tester executable called test_core.exe. this executable links to core.lib and activates various functions from it. The DLL core.dll has very few exports, only enough to start its main functionality. It cannot be unit tested fully using these exports.
What I want is to do the PGO data collection by activating some of the tests in test_core.exe and then to use this PGO data to link and optimize core.dll.
It seems that the Visual Studio framework was designed so that the collecting executable and optimized executable are the same.
One option is to add the relevant tests to be inside core.dll and run them using a special export but that would bloat core.dll with test code which is not used in any other circumstance.
It seems that the Visual Studio framework was designed so that the collecting executable and optimized executable are the same.
That was very, very intentional. Profile guided optimization can only work properly when it uses profile data that was collected from a realistic simulation of the way your users are going to run your program. That requires the actual executables as deployed to the user and using realistic data that's a reasonable match with the data the program is going to process at the user's site.
Trying to spike it with test unit profile results will achieve the opposite, your user isn't going to run the code the same way. Significant odds that you'd end up with a less optimized program it that was possible. The profile data you've gather is only good enough to optimize the unit test, that's not useful.
Don't try to cook the profile data, it can't work. This does mean that you can't necessarily easily measure the effectiveness of the optimization if you require a unit test to see a signal. In that case you need to just assume that PGO gets the job done.
It seems that the Visual Studio framework was designed so that the
collecting executable and optimized executable are the same.
This is true, but in you're case, you want to optimize a DLL, not an executable. You can compile the static library and the DLL using the /GL switch and link the DLL using the /LTCG:PGINSTRUMENT switch. This creates a DLL that is instrumented. The test_core.exe image doesn't have to be instrumented, so you can just compile it normally (in Debug or Release mode). Then, by running test_core.exe, a PGC file will be generated containing a profile of the behavior of core.dll only. This profile can then be used to optimize core.dll by compiling it again and specifying the /LTCG:PGOPTIMIZE switch. As long as test_core.exe exercises core.dll for common usage scenarios, you'll certainly benefit from it. See this for more information.

Xcode Instruments: profiled hotspots don't match up with source code

When using the Instruments time profiler, I often end up with results that don't make sense. They indicate that time is spent in some part of the file that is either outside of the function being inspected, or contains no executable code (comments, blank lines, etc.). This makes the results often close to useless.
I have tried a number of things to try to solve this:
Close Instruments before recompiling and re-profiling
Clean build, recompile
Restart instruments every time I profile
Updated to Xcode 4.3.2
These occasionally help, but don't always prevent the problem.
What can I do to fix this?
I was running into the same problem on code that I compiled using gcc with the -O3 optimization flag set. Googling around, I learned that Apple's time profiler does not like gcc code that is compiled with optimization flags.
Recompiling my code without the -O3 flag and rerunning the time profiler, hotspots now match the correct lines of my source code. Perhaps this relates to your problem.

Resources