- When the compiler takes a long time time to compile (like 20 to 30 minutes) how does one find out the reason?
- Is there any option to tell the time taken for each phase, so I know which phase is sinking more time?
Find out where the compiler is spending its time
The first thing to do is to run the compiler with the -v option. That
will give you a phase-by-phase breakdown about where the compiler is
spending its time. As for debugging long compilation times. it depends
on which phase is taking the time. Depending on the particular phase,
there are different debugging strategies.
Debugging Strategies by Phase
Scheduling
If scheduling is taking a long time, you can try:
- To turn down the -scheduler-effort (so the compiler does less aggressive disjointness testing).
- To break up your design into more modules (since scheduling is O(n^2) in the number of rules, generally speaking).
Static Elaboration
If expanded (i.e. static elaboration) is
taking a long time, usually what makes sense is trying to think about
what sort of elaboration is going on and trying to make it simpler
- Replace Lists with Vectors
- Expressing a computation in a way
where the compiler has to do less optimization and/or rewriting
- Break the design up into more synthesized modules so there is less inlining, etc.).
Transform
If transform (an optimization phase) is taking a long time,
usually trying to make boolean predicates simpler and less involved
helps, and so on.
Check the Statistics
A second flag you can use is -show-stats, that will tell you various
statistics the compiler has noticed about the design (e.g. the number
of rules and interface methods). That might be a clue to what's taking
all the time. Remember that scheduling is O(n^2) in the number of
rules and methods (since the compiler has to at least consider every
pair of rules/methods for conflicts). This is one of the reasons
breaking up the design into multiple modules can help (since breaking
the rules into smaller groups can give you a decent speedup). Another
reason is that if a module is instantiated and inlined 10 times, there
are 10 copies of its code that the compiler needs to analyze and
schedule (a synthesis boundary is what permits the compiler to do this
once and remember the results).
Disjointness Testing
One other reason that the scheduler takes a lot of time is
disjointness testing. This can be an issue if you have a few rules,
but they have very complicated predicates. One way to check if this is
an issue is to compile with -scheduler-effort 0 (which effectively
turns off disjointness testing). One thing that is a good idea to do
with that is to turn on the -warn-scheduler-effort flag, so the
compiler will complain if it gives up on disjointness testing (so you
know if the lack of disjointness testing is having an impact on the
final schedule you're getting).
|