Greetings Chapel Developers!
We are Computer Science students at Western Washington University working on a project to improve the debugging experience for Chapel. One of our goals is to provide a generic debugging method which may be called from our debugger with GDB to print out Chapel variables. To do this, we’re attempting to modify the compiler so as to instantiate a generic method for different types. However it seems like our functions are getting pruned away and do not actually get generated. Below are some snippets from what we’re working on:
Here is the definition of the debug function we are attempting to instantiate. The pragma is being used to link it with the well known functions. The implementation is elided as there are many chapel types writeln
does not work on by default (c_string, c_fn_ptr, c_file, etc).
pragma "debug print"
proc chpl_debug_print(param x) {
// TODO writeln(x);
}
We are instantiating the chpl_debug_print
procedure for each type ts
in the program with the following code within compiler/resolution/functionResolution.resolve():
forv_Vec(TypeSymbol, ts, gTypeSymbols) {
if (ts->isKnownToBeGeneric() || strcmp(ts->cname, "void") == 0 || strcmp(ts->cname, "nothing") == 0 || strcmp(ts->cname, "_ref_void") == 0)
continue;
SymbolMap subs;
subs.put(gChplDebugPrint->getFormal(1), paramMap.get(ts));
FnSymbol* debugFn = instantiateWithoutCall(gChplDebugPrint, subs);
debugFn->addFlag(FLAG_COMPILER_GENERATED);
resolveFunction(debugFn);
}
If we run this code before the pruneResolvedTree
pass, the generated debug instances are pruned since they are unused, while if we run this after the prune pass, gChplDebugPrint
is null since (we believe) it has been pruned.
Our immediate question is: How can we ensure our function is instantiated (and ultimately generated) and does not get pruned away?
-- Paul, Aedan, Sakari, Tom