Dear David,
After trying many example ML programs, printing out IR code tree, I've documented and understood several IR components. I accumulated several questions here, and I would appreciate if I could obtain some hints from you. I only turned on codetree flag of the compiler.
1. In the printed IR of a program, seems the print out has two sections, for example:
2 * 3;
BLOCK(DECL #1{0 uses} = GLOBAL (FUN "run_call2(1)", LAMBDAINLINE( run_call2(1) CL=false CR=0 LEV=0 LOCALS=0 ARGS=G ARGLIVES= RES=G CLOS=() LOCAL(1,1) G $(INDIRECT(0, PARAM(0,1)) G, INDIRECT(1, PARAM(0,1)) G)){LAMBDA} ) (*GLOBAL*){early} G $(LIT <long> G); DECL #2{0 uses} = LOCAL(0,1); MUTUAL(); RECCONSTR(LOCAL(0,2)) ) BLOCK(DECL #1{0 uses} = GLOBAL (FUN "run_call2(1)", LAMBDAINLINE( run_call2(1) CL=false CR=0 LEV=0 LOCALS=0 ARGS=G ARGLIVES= RES=G CLOS=() LOCAL(1,1) G $(INDIRECT(0, PARAM(0,1)) G, INDIRECT(1, PARAM(0,1)) G)){LAMBDA} ) (*GLOBAL*){early} G $(LIT <long> G); DECL #2{0 uses} = LOCAL(0,1); MUTUAL(); RECCONSTR(LOCAL(0,2)) ) POLY_SYS_amul{early} G $(LIT2 G, LIT3 G)
The first section contains two same blocks, and always the block is duplicated in the first section for every input ML program. The second section contains an expression. It seems that the second expression is included in the blocks of the first section, and I'm a little bit confused here, so why the first section duplicates the blocks, and why the expression
POLY_SYS_amul{early} G $(LIT2 G, LIT3 G)
is separately printed out?
2. TAGTEST(x, y, z) is used in several different places such as generation of the boolean constants true and false, or testing whether a list is empty, but I still couldn't find documentation of TagTest from the source code, and I'm wondering what is the semantics of TAGTEST?
3. When I printed the IR of a signature, say:
signature Set =
# sig # type element # type set # val empty : set # end; BLOCK(LIT0) BLOCK(LIT0)
I suppose here again BLOCK(LIT0) is duplicated, and I'm wondering why this signature is represented like this simple instead of using a tuple whose elements are the decls, and its internal representations?
4. I found some documentation about the members of LAMBDA, but still couldn't figure out how CL, CR and LOCALS are determined. In all my testing cases, always CL=false, and CR=0. Also for LOCALS, I thought it indicates the times that local variables are used. For instance:
fun f a = a + 2;
BLOCK(DECL #1{0 uses} = LAMBDA( f(1) CL=false CR=0 LEV=0 LOCALS=0 ARGS=G ARGLIVES= RES=G CLOS=() BLOCK(BLOCK(DECL #2{0 uses} = PARAM(0,1); GLOBAL (FUN "run_call2(1)", LAMBDAINLINE( run_call2(1) CL=false CR=0 LEV=0 LOCALS=0 ARGS=G ARGLIVES= RES=G CLOS=() LOCAL(1,1) G $(INDIRECT(0, PARAM(0,1)) G, INDIRECT(1, PARAM(0,1)) G)){LAMBDA} ) (*GLOBAL*){early} G $(RECCONSTR(LOCAL(0,2), LIT2) G) ) )){LAMBDA}; RECCONSTR(LOCAL(0,1)) )
(* the skip the duplicated copy of the above block)
LAMBDASMALL( f(1) CL=false CR=0 LEV=1 LOCALS=3 ARGS=G ARGLIVES= RES=G CLOS=() POLY_SYS_aplus{early} G $(PARAM(0,1) G, LIT2 G)){LAMBDA}
Here I don't quite understand why LOCALS in the first Block is always 0, and why the LOCALS below is 3.
Thank you very much!!
-- Yue
On Sun, Aug 22, 2010 at 3:22 PM, Yue Li xyly781@gmail.com wrote:
On Sun, Aug 22, 2010 at 5:32 AM, David Matthews David.Matthews@prolingua.co.uk wrote:
Yue Li wrote:
I was trying to understand and document the semantics of the opcode set used by Poly/ML's interpreter, and I'm wondering whether inside Poly/ML's compiler, there are such debugging functions which could print out the IR tree as well as the generated op code for an input ML program? These functions would help me a lot to test my understanding on Poly's IR data structure and code generation. ?Thank you very much!
Yue, There are switches in the PolyML.Compiler structure that will print out various stages of the compilation process when compiling something. Probably the most useful for you would be PolyML.Compiler.codetree := true; which will cause the compiler to print out the code-tree. ?You may also find "codetreeAfterOpt" (i.e. code-tree after it has been through the optimiser) and "assemblyCode" (the machine code generated by the final code-generator) useful as well.
? This works and I can see the printed code tree now. I will have more questions later when I tried more examples.
Many thanks!!
Yue