1 .\" process with 'troff -ms', with no preprocessors
10 . \" roman numeral page numbers
21 .if !\\n(Nc .if o .tl ' ' '%'
22 .if !\\n(Nc .if e .tl '%' ' '
23 .if \\n(Nc .tl ' '%' '
27 . \" arabic numeral page numbers
37 .if !\\n(Nc .if o .tl ' ' '%'
38 .if !\\n(Nc .if e .tl '%' ' '
39 .if \\n(Nc .tl ' '%' '
46 . \" choose roman page numbers
131 A Loop Restructuring Research Tool
136 Oregon Graduate Institute of Science and Technology
137 19600 NW von Neumann Drive
138 Beaverton, OR 97006 USA
141 email: mwolfe@cse.ogi.edu
147 .\" First page of real text
156 \*t is designed around a character menu interface (for the nonce);
157 to choose a menu item, move the menu bar between menu items
158 by using the space or backspace key, then typing the return key
159 when the desired choice is highlighted.
160 A quicker method is to type the leading character of the desired choice;
161 uppercase or lowercase may be used.
163 Three keys always (almost) have special meaning.
165 at any menu should quit \*t and take
166 you back to the shell prompt.
168 at any menu should escape or exit out of this menu.
169 Alternatively, the 'escape' key has the same effect.
171 A control-L will refresh the screen.
172 Occasional junk gets by the Curses package and will not be corrected by ^L.
179 The screen display shows positions via highlighting, though
180 the screen dumps in this documentation don't show that highlighting.
181 To save space, multiple blank lines in the screen dumps are deleted.
183 When starting up \*t with no file argument, you get the screen:
186 Tiny Tool [as of December 1990]
187 *Browse File Parse Restor System Trans Write Msgs Quit
189 The first 22 lines (on a standard 24 line display) are the main window;
190 the next to last line is a message line, and the bottom line is the
192 The message would give the file name of the current program,
194 The main menu has 8 choices; choices can be made from any menu by
195 using the space bar and backspace key to
196 move the menu position (shown with highlighting and the asterisk)
197 to the desired choice and hitting the return key, or (faster) by typing
198 the leading character of the choice.
199 Here, for instance, typing 'Q' will quit \*t.
200 All menus in \*t have the Msgs, Quit and Xcape options
201 (except for the main menu, which has no Xcape).
202 Choosing Quit from any menu will quit \*t completely and
203 immediately (in the absence of bugs).
204 Choosing Msgs from any menu will display the most recent
205 saved messages in the main window.
206 Choosing Xcape from any menu returns to the previous menu;
207 Xcape may also be chosen by typing the 'Escape' key on your keyboard.
209 To read in a program from a file after starting up \*t, we choose the
210 Parse option; \*t then asks for the name of the file we wish
215 Tiny Tool [as of December 1990]
218 We then respond with the name of a file name:
222 Tiny Tool [as of December 1990]
225 and this file is read in and displayed:
228 1: real a(1:100,1:100)
232 7: a(k,k) = sqrt(a(k,k))
234 11: a(i,k) = a(i,k)/a(k,k)
236 15: a(i,j) = a(i,j)-a(i,k)*a(j,k)
242 Browse File *Parse Restor System Trans Write Msgs Quit
244 A quicker way to start up \*t on a file is to give the file
245 name on the command line:
249 which will start up by first parsing and displaying the program.
257 \*t currently implements 8 elementary loop restructuring transformations,
258 with plans for several more to be added.
276 vectorization (simple)
278 Each of these is explained here with examples.
285 Bumping is simple adjusting loop lower and upper limits by adding
286 (or subtracting) a constant integer.
287 This is occasionally used to make lower or upper limits of two
288 loops match exactly, for instance to satisfy the strict requirements
289 of loop interchanging for non-tightly nested loops.
290 A more sophisticated tool would notice the need for bumping automatically.
291 An example is given under loop interchanging.
298 Circulation is a generalization of loop interchanging;
299 it is equivalent to interchanging a loop inside of (or outside of)
300 multiple inner (outer) loops in a single step.
301 For example, take the smoothing program:
304 1: real a(1:100,1:100,1:100)
309 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
316 Browse File *Parse Restor System Trans Write Msgs Quit
318 The outermost 'k' loop can be 'innermosted', or interchanged to the
319 innermost position, or 'intercirculated' inside of the 'j' loop in
320 one step by choosing the Circ menu item, then choosing the circulate
321 inside of the 'j' loop:
324 1: real a(1:100,1:100,1:100)
329 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
335 Intercirculating loop k inside of j
336 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
338 In contrast, outercirculating the 'j' loop (of the original program)
339 to the outermost position, in one step, would produce:
342 1: real a(1:100,1:100,1:100)
347 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
353 Outercirculating loop j outside of k
354 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
356 The data dependence tests for intercirculation and outercirculation
357 are explained in two recent papers:
358 Utpal Banerjee, "A Theory of Loop Permutations" (which appears
359 in the Springer-Verlag monograph
361 Languages and Compilers for Parallel Computing,
362 Gelernter, Nicolau and Padua (eds.), 1990) and
363 Michael Wolfe, "Data Dependence and Program Restructuring"
366 The Journal of Supercomputing
367 in late 1990 or early 1991).
368 After these transformations, dependence direction or distance vectors
369 are modified to account for the new loop ordering.
375 3.3 Loop Distribution
378 Loop distribution is a well-known transformation which is often used
379 to distribute an outer loop around non-tightly nested inner loops.
380 As an example, we use a Cholesky decomposition program:
383 1: real a(1:100,1:100)
387 7: a(k,k) = sqrt(a(k,k))
389 11: a(i,k) = a(i,k)/a(k,k)
391 15: a(i,j) = a(i,j)-a(i,k)*a(j,k)
397 Bump Circ *Dist Inter Neg Par Skew Vec Msgs Quit Xcape
399 After distribution, the loop looks like:
402 1: real a(1:100,1:100)
406 7: a(k,k) = sqrt(a(k,k))
408 11: a(i,k) = a(i,k)/a(k,k)
412 15: a(i,j) = a(i,j)-a(i,k)*a(j,k)
418 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
420 The dependence test for loop distribution involves finding dependence cycles,
421 and keeping all dependence cycles in a single distributed loop.
427 3.4 Loop Interchanging
430 In \*t, choosing Interchanging will interchange the current loop
431 with its immediate outer loop.
432 Taking the distributed loops from the loop distribution example,
433 we can move to the 'j' loop and interchange it with the 'i' loop to get:
436 1: real a(1:100,1:100)
440 7: a(k,k) = sqrt(a(k,k))
442 11: a(i,k) = a(i,k)/a(k,k)
445 9: for i = max(k+1,j),n do
446 15: a(i,j) = a(i,j)-a(i,k)*a(j,k)
451 Interchanging loops i and j
452 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
454 Note how the triangular loop limits have been modified;
455 some future version of \*t will simplify the loop limits of the 'i'
456 loop to be simply 'j,n', eliminating the 'max' when unnecessary.
457 Loop interchanging is legal if there are no (<,>) dependence relations,
458 and the dependence direction and distance vector elements for the
459 interchanged loops are also interchanged.
461 Non-tightly nested loops can also be interchanged.
462 For instance, we can take the above example (after interchanging
463 the 'i' and 'j' loops) and choose to interchange the 'j' loop outwards.
464 This produces the result:
467 1: real a(1:100,1:100)
472 9: for i = max(k+1,j),n do
473 15: a(i,j) = a(i,j)-a(i,k)*a(j,k)
476 7: a(j,j) = sqrt(a(j,j))
478 11: a(i,j) = a(i,j)/a(j,j)
482 Interchanging loops k and j
483 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
485 Note that lines 4 through 6 have been moved from above the inner loop
486 to below the inner loop, and that the loop index 'k' has been replaced by 'j'.
487 Currently, interchanging nontightly nested loops requires the loop limits
488 to be perfectly square or triangular;
489 while other loops limits could be handled by adding 'if' statements or
490 adjusting the loop limits automatically, this current restriction
491 sometimes requires 'bumping' a loop limit.
492 For instance, suppose we take the original Cholesky decomposition
493 and instead of distributing the 'i' loop, we interchange the 'i' loop
497 1: real a(1:100,1:100)
502 11: a(i,k) = a(i,k)/a(k,k)
504 15: a(i,j) = a(i,j)-a(i,k)*a(j,k)
507 7: a(i,i) = sqrt(a(i,i))
510 Interchanging loops k and i
511 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
513 Now suppose we want to interchange the 'j' and 'k' loops.
514 If we try to distribute the 'k' loop, we get the message:
518 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
520 since there is a dependence cycle involving lines 6 and 8.
521 If we try to interchange the 'j' loop outwards, we get the message:
524 Imperfect loop interchanging requires square/triangular loops
525 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
527 The loop limits can be made triangular by subtracting one from the 'j' loop
528 limits (or adding one to the 'k' loop limits).
529 We can choose to bump the 'j' loop limits by choosing the 'Bump' menu item
533 1: real a(1:100,1:100)
538 11: a(i,k) = a(i,k)/a(k,k)
540 15: a(i,j) = a(i,j)-a(i,k)*a(j,k)
543 7: a(i,i) = sqrt(a(i,i))
546 Imperfect loop interchanging requires square/triangular loops
547 *Bump Circ Dist Inter Neg Par Skew Vec Msgs Quit Xcape
549 \*t then asks what constant to add to the loop limits:
552 Interchanging loops k and i
555 We answer with '-1', which then produces the program:
558 1: real a(1:100,1:100)
563 11: a(i,k) = a(i,k)/a(k,k)
564 13: for j = k+1-1,i-1 do
565 15: a(i,j+1) = a(i,j+1)-a(i,k)*a(j+1,k)
568 7: a(i,i) = sqrt(a(i,i))
572 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
574 Notice that within the loop, 'j' is replaced by 'j+1';
575 (also notice that no expression simplification is done).
576 Now the two loops can be successfully interchanged:
579 1: real a(1:100,1:100)
584 11: a(i,j) = a(i,j)/a(j,j)
586 15: a(i,j+1) = a(i,j+1)-a(i,k)*a(j+1,k)
589 7: a(i,i) = sqrt(a(i,i))
592 Interchanging loops k and j
593 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
603 Loop negation (also called loop reversal) involves running the loop
605 \*t shows a negated loop by negating and switching
606 the lower and upper limits of a loop, and negating the loop index within
607 the body of the loop.
608 Negating the 'j' loop in the first interchanging example gives:
611 1: real a(1:100,1:100)
615 7: a(k,k) = sqrt(a(k,k))
617 11: a(i,k) = a(i,k)/a(k,k)
619 13: for j = -n,-(k+1) do
620 9: for i = max(k+1,-j),n do
621 15: a(i,-j) = a(i,-j)-a(i,k)*a(-j,k)
627 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
629 Loop negation is legal if the loop carries no dependence relations,
630 and the dependence graph is modified to negate any dependence distance
635 3.6 Loop Parallelization
638 A loop can be parallelized as long as it carries no data dependence relations.
639 Unlike other transformations, this cannot be 'Undone', nor will it
640 show up in the 'Restore' display.
641 In the previous example, the loops that can be parallelized are:
644 1: real a(1:100,1:100)
648 7: a(k,k) = sqrt(a(k,k))
649 9: doall i = k+1,n do
650 11: a(i,k) = a(i,k)/a(k,k)
652 13: doall j = -n,-(k+1) do
653 9: doall i = max(k+1,-j),n do
654 15: a(i,-j) = a(i,-j)-a(i,k)*a(-j,k)
660 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
668 Forward (reverse) loop skewing involves adding (subtracting) an outer loop
669 index to the lower and upper limits for an inner loop.
670 Loop skewing is always legal, but modifies the direction and distance
671 vectors by adding the outer loop elements to the inner loop element.
672 Thus, a (<,=) direction is changed to a (<,<) direction;
673 this means that after loop interchanging, the dependence relation
674 will be carried by the outer loop, allowing parallel execution of the inner
676 This is useful in a smoothing algorithm, as in the circulation example.
677 Forward skewing the inner 'j' loop with respect to the 'k' loop gives:
680 1: real a(1:100,1:100,1:100)
684 9: for j = 2+k,n+k do
685 11: a(k,i,j-k) = a(k,i-1,j-k)+a(k,i,j-k-1)+a(k,i,j-k+1)+a(k,i+1,j-k)+a(k-1,i
691 Forward skew loop j with respect to k
692 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
694 Forward skewing the 'j' loop again with respect to the 'i' loop gives:
697 1: real a(1:100,1:100,1:100)
701 9: for j = 2+k+i,n+k+i do
702 11: a(k,i,j-i-k) = a(k,i-1,j-i-k)+a(k,i,j-i-k-1)+a(k,i,j-i-k+1)+a(k,i+1,j-i-
703 k)+a(k-1,i,j-i-k)+a(k+1,i,j-i-k)
708 Forward skew loop j with respect to i
709 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
711 Now we see the advantage of loop skewing, by circulating
712 the 'j' loop all the way outside:
715 1: real a(1:100,1:100,1:100)
717 9: for j = 2+2+2,n+n+n do
718 5: for k = max(2,j-(n+n)),min(n,j-(2+2)) do
719 7: for i = max(2,j-(n+k)),min(n,j-(2+k)) do
720 11: a(k,i,j-i-k) = a(k,i-1,j-i-k)+a(k,i,j-i-k-1)+a(k,i,j-i-k+1)+a(k,i+1,j-i-
721 k)+a(k-1,i,j-i-k)+a(k+1,i,j-i-k)
726 Outercirculating loop j outside of k
727 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
729 And now we can parallelize the inner 'k' and 'i' loops:
732 1: real a(1:100,1:100,1:100)
734 9: for j = 2+2+2,n+n+n do
735 5: doall k = max(2,j-(n+n)),min(n,j-(2+2)) do
736 7: doall i = max(2,j-(n+k)),min(n,j-(2+k)) do
737 11: a(k,i,j-i-k) = a(k,i-1,j-i-k)+a(k,i,j-i-k-1)+a(k,i,j-i-k+1)+a(k,i+1,j-i-
738 k)+a(k-1,i,j-i-k)+a(k+1,i,j-i-k)
744 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
752 Vectorization is legal when there are no loop-carried dependence cycles
754 Vectorization in \*t works only for trivial cases, as it does not
755 even recognize simple reduction operators;
756 non-inner loops cannot be vectorized, though vectorization within
757 an outer parallel loop is legal.
758 Vectorization does not change the dependence graph at all.
759 As an example, taking the program from the Skewing section, we can
760 vectorize the inner loop to get:
763 1: real a(1:100,1:100,1:100)
765 9: for j = 2+2+2,n+n+n do
766 5: doall k = max(2,j-(n+n)),min(n,j-(2+2)) do
767 7: forall i = max(2,j-(n+k)),min(n,j-(2+k)) do
768 11: a(k,i,j-i-k) = a(k,i-1,j-i-k)+a(k,i,j-i-k-1)+a(k,i,j-i-k+1)+a(k,i+1,j-i-
769 k)+a(k-1,i,j-i-k)+a(k+1,i,j-i-k)
775 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
784 The \*t language is very simple.
785 It comprises scalar and array variables,
786 loops, assignments and block-structured IF statements.
791 stlist ::= statement [';' statement]...
793 statement ::= integerdecl
802 constdecl ::= 'const' constassignment [',' constassignment]...
804 constassignment ::= ID '=' expression
806 integerdecl ::= 'integer' vardecllist
807 realdecl ::= 'real' vardecllist
809 vardecllist ::= vardecl [',' vardecl]...
812 ::= ID '(' [expression ':'] expression
813 [',' [expression ':'] expression]... ')'
817 assignment ::= lhs '=' expression
820 ::= ID '(' expression [',' expression]... ')'
822 loop ::= ['for' | 'doall']
823 ID '=' expression ['to' | ',' | ':'] expression
824 [ ['by' | ',' | ':'] expression]
827 if ::= 'if' expression 'then' stlist ['else' stlist] 'endif'
832 ::= ID '(' expression [',' expression]... ')'
835 ::= expression '+' expression
836 ::= expression '-' expression
837 ::= expression '*' expression
838 ::= expression '/' expression
839 ::= expression '**' expression
842 ::= '(' expression ')'
843 ::= expression '<' expression
844 ::= expression '<=' expression
845 ::= expression '=' expression
846 ::= expression '<>' expression
847 ::= expression '>' expression
848 ::= expression '>=' expression
849 ::= expression 'mod' expression
850 ::= expression 'max' expression
851 ::= expression 'min' expression
852 ::= 'sqrt' '(' expression ')'
853 ::= 'floor' '(' expression '/' expression ')'
854 ::= 'ceiling' '(' expression '/' expression ')'
855 ::= 'max' '(' expression [',' expression]... ')'
856 ::= 'min' '(' expression [',' expression]... ')'
865 Start out by firing up \*t with the command line:
869 \*t will return with the display:
872 Tiny Tool [as of December 1990]
873 *Browse File Parse Restor System Trans Write Msgs Quit
875 Go to the File menu by typing 'f', getting the list of files:
877 /ogc1/staff/mwolfe/tiny
878 Announcement doc/ fix/ source/ test/
879 dif doc.log make.out t* todo
881 Tiny Tool [as of December 1990]
882 *Down Edit Newdir Redo Sh Up Msgs Quit Xcape
884 To move to the 'test' subdirectory, choose 'Down' by typing 'd',
888 Tiny Tool [as of December 1990]
891 Respond by typing 'test', following by the return key;
892 \*t then displays the files in the 'test' subdirectory:
894 /ogc1/staff/mwolfe/tiny/test
895 ave3 dd.4 doc2.log lu parenb wave2
896 ch dd.t1 dynamic ludecomp rev wave3
897 dd.1 dd.t2 example.1 paren rn1 wave3a
898 dd.2 dd.t3 example.2 paren2 wave wave3b
899 dd.3 doc.log example.3 parena wave.8wa
901 Tiny Tool [as of December 1990]
902 *Down Edit Newdir Redo Sh Up Msgs Quit Xcape
904 To check the contents of a file, type 'E' to edit the file;
905 \*t prompts for the file name, so a response of 'ch' gets:
907 real a(100,100), b(100)
910 a(k,k) = sqrt(a(k,k))
912 a(i,k) = a(i,k)/a(k,k)
914 a(i,j) = a(i,j)-a(i,k)*a(j,k)
920 "ch" 11 lines, 191 characters
922 Exiting the editor returns to the same File menu.
923 Return to the Main menu by typing the 'escape' key:
926 Tiny Tool [as of December 1990]
927 Browse *File Parse Restor System Trans Write Msgs Quit
929 Notice that the default menu selection when returning from a submenu
930 is left at the most recent choice;
931 to enter the 'File' menu again, type 'return'.
932 To parse one of those files, so type 'p':
935 Tiny Tool [as of December 1990]
938 Respond with the file name 'decomp.cholesky', followed by 'return':
941 1: real a(1:100,1:100)
945 4: a(k,k) = sqrt(a(k,k))
947 6: a(i,k) = a(i,k)/a(k,k)
949 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
955 Browse File *Parse Restor System Trans Write Msgs Quit
957 To explore some interactive restructuring, go to
958 the Browse menu by typing 'B':
961 1: real a(1:100,1:100)
965 4: a(k,k) = sqrt(a(k,k))
967 6: a(i,k) = a(i,k)/a(k,k)
969 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
975 *Browse DD Loop Restr See Undo Var Msgs Quit Xcape
977 Notice that when entering a new menu, the default menu item is
978 always the first choice, not necessarily the one most often chosen.
979 Notice that in the Browse menu, there is always a current position
980 in the file; initially the current position is the 'Entry' node, at the
982 To look at the data dependence relations in the program,
983 enter the DD Browse Menu by typing 'D':
986 1: real a(1:100,1:100)
990 4: a(k,k) = sqrt(a(k,k))
992 6: a(i,k) = a(i,k)/a(k,k)
994 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1000 *Cycle Goto Next Pred Succ Var Write Msgs Quit Xcape
1002 The message tells that the current position has no DD successors;
1003 this is not surprising since the current position is the Entry node.
1004 (Some future version of \*t may link upwardly-exposed uses to the Entry node.)
1005 Two ways to browse the DD graph are given.
1006 The most useful way is to cycle through all the dependences in the program
1007 by using the Cycle menu choice;
1008 this moves the current position to the next variable reference that has
1009 data dependence successors and displays that dependence relation on the
1011 It will display each dependence successor from that variable reference, then
1012 move on to the next reference.
1013 Typing 'C' (or just return, since Cycle is the default menu item) gives the
1017 1: real a(1:100,1:100)
1021 4: a(k,k) = sqrt(a(k,k))
1023 6: a(i,k) = a(i,k)/a(k,k)
1025 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1030 flow dependence 4: --> 6:(=) (0)
1031 *Cycle Goto Next Pred Succ Var Write Msgs Quit Xcape
1033 Notice the highlighting in lines 4 and 6 showing the variable
1034 references in question.
1035 The message line shows the kind of dependence (flow, anti, output),
1036 the line numbers involved, the direction vector and the distance
1037 vector (unknown directions or distances appear as "*").
1038 Typing 'C' again gives the next dependence relation:
1041 1: real a(1:100,1:100)
1045 4: a(k,k) = sqrt(a(k,k))
1047 6: a(i,k) = a(i,k)/a(k,k)
1049 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1054 flow dependence 6: --> 8:(=,=) (0,0)
1055 *Cycle Goto Next Pred Succ Var Write Msgs Quit Xcape
1059 The other method to browse the dependence relations interactively
1060 is to use the Var menu option to move the current position
1061 to the next variable reference.
1062 The first predecessor or successor of that variable reference may be
1063 displayed by using the Pred or Succ menu items, and Next will show
1064 the next predecessor or successor, as appropriate.
1065 Goto will move the current position to the dependence predecessor or
1066 successor reference shown on the message line.
1068 In any case, all these messages are saved in the message buffer, and
1069 may be displayed by typing the 'M' key:
1073 flow dependence 4: --> 6:(=) (0)
1074 flow dependence 6: --> 8:(=,=) (0,0)
1075 flow dependence 6: --> 8:(=,<=) (0,*)
1076 anti dependence 8: --> 4:(<) (*)
1077 anti dependence 8: --> 6:(<,=) (*,0)
1078 anti dependence 8: --> 8:(<,=,=) (*,0,0)
1079 flow dependence 8: --> 4:(<) (*)
1080 output dependence 8: --> 4:(<) (*)
1081 flow dependence 8: --> 6:(<,=) (*,0)
1082 flow dependence 8: --> 6:(<,<) (*,*)
1083 output dependence 8: --> 6:(<,=) (*,0)
1084 flow dependence 8: --> 8:(<,=,=) (*,0,0)
1085 flow dependence 8: --> 8:(<,=,<) (*,0,*)
1086 flow dependence 8: --> 8:(<,<=,<) (*,*,*)
1087 output dependence 8: --> 8:(<,=,=) (*,0,0)
1093 The dependence relations can all be written to a file by
1094 choosing the Write menu option;
1095 \*t prompts for the file to which to write the dependence information.
1096 The file for this program would look like:
1098 flow dependence: 4 --> 6 (=) (0) a(k,k) --> a(k,k)
1099 flow dependence: 6 --> 8 (=,=) (0,0) a(i,k) --> a(i,k)
1100 flow dependence: 6 --> 8 (=,<=) (0,*) a(i,k) --> a(j,k)
1101 anti dependence: 8 --> 4 (<) (*) a(i,j) --> a(k,k)
1102 anti dependence: 8 --> 6 (<,=) (*,0) a(i,j) --> a(i,k)
1103 anti dependence: 8 --> 8 (<,=,=) (*,0,0) a(i,j) --> a(i,j)
1104 flow dependence: 8 --> 4 (<) (*) a(i,j) --> a(k,k)
1105 output dependence: 8 --> 4 (<) (*) a(i,j) --> a(k,k)
1106 flow dependence: 8 --> 6 (<,=) (*,0) a(i,j) --> a(i,k)
1107 flow dependence: 8 --> 6 (<,<) (*,*) a(i,j) --> a(k,k)
1108 output dependence: 8 --> 6 (<,=) (*,0) a(i,j) --> a(i,k)
1109 flow dependence: 8 --> 8 (<,=,=) (*,0,0) a(i,j) --> a(i,j)
1110 flow dependence: 8 --> 8 (<,=,<) (*,0,*) a(i,j) --> a(i,k)
1111 flow dependence: 8 --> 8 (<,<=,<) (*,*,*) a(i,j) --> a(j,k)
1112 output dependence: 8 --> 8 (<,=,=) (*,0,0) a(i,j) --> a(i,j)
1115 Now to do some transformations.
1116 Type 'X' from the DD Browse Menu to get to the Browse menu:
1119 1: real a(1:100,1:100)
1123 4: a(k,k) = sqrt(a(k,k))
1125 6: a(i,k) = a(i,k)/a(k,k)
1127 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1133 Browse *DD Loop Restr See Undo Var Msgs Quit Xcape
1135 Currently the only transformations supported are loop transformations.
1136 To perform a loop transformation, move the current
1137 position to the loop to be transformed.
1138 Typing 'L' twice will move the current position from
1139 Entry to the first 'for' loop, then to the second 'for' loop:
1142 1: real a(1:100,1:100)
1146 4: a(k,k) = sqrt(a(k,k))
1148 6: a(i,k) = a(i,k)/a(k,k)
1150 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1156 Browse DD *Loop Restr See Undo Var Msgs Quit Xcape
1158 Choose the Restructure menu by typing 'R':
1161 1: real a(1:100,1:100)
1165 4: a(k,k) = sqrt(a(k,k))
1167 6: a(i,k) = a(i,k)/a(k,k)
1169 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1175 *Bump Circ Dist Inter Neg Par Skew Vec Msgs Quit Xcape
1177 The choices are loop bumping,
1178 loop circulation (generalized loop interchanging for tightly nested loops),
1180 loop interchanging (for tightly or non-tightly nested loops),
1182 loop parallelization,
1183 and loop skewing (along with the standard MQX menu choices).
1184 Distribute loop 'i' by typing 'D':
1187 1: real a(1:100,1:100)
1191 4: a(k,k) = sqrt(a(k,k))
1193 6: a(i,k) = a(i,k)/a(k,k)
1197 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1203 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
1205 Now type 'L' to move to the 'j' loop, and go to the restructuring menu
1209 1: real a(1:100,1:100)
1213 4: a(k,k) = sqrt(a(k,k))
1215 6: a(i,k) = a(i,k)/a(k,k)
1219 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1225 *Bump Circ Dist Inter Neg Par Skew Vec Msgs Quit Xcape
1227 This time, let's see what happens when the 'j' loop is
1228 negated by typing 'N':
1231 1: real a(1:100,1:100)
1235 4: a(k,k) = sqrt(a(k,k))
1237 6: a(i,k) = a(i,k)/a(k,k)
1240 7: for j = -i,-(k+1) do
1241 8: a(i,-j) = a(i,-j)-a(i,k)*a(-j,k)
1247 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
1249 This negates and switches the loop limits, and negates
1250 the index variable inside the range of the loop.
1251 It also affects the dependence relations of the loop.
1252 But if this turns out to be uninteresting, and the original
1253 version of the program with the forward loop is desired.
1254 One could re-negate the loop, but it is simpler to undo the negation
1255 by typing 'U' for Undo:
1258 1: real a(1:100,1:100)
1262 4: a(k,k) = sqrt(a(k,k))
1264 6: a(i,k) = a(i,k)/a(k,k)
1268 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1274 Browse DD Loop Restr See *Undo Var Msgs Quit Xcape
1276 Notice that the current position is moved back to the Entry node.
1277 Again move to the 'j' loop (typing 'L') and go to the
1278 Restructure menu, choosing instead the Intchg (interchange) menu item.
1279 This interchanges the 'i' and 'j' loops:
1282 1: real a(1:100,1:100)
1286 4: a(k,k) = sqrt(a(k,k))
1288 6: a(i,k) = a(i,k)/a(k,k)
1291 5: for i = max(k+1,j),n do
1292 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1297 Interchanging loops i and j
1298 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
1300 Parallelize the j loop by going to the Restructure menu
1301 and typing P for Parallelize, giving:
1304 1: real a(1:100,1:100)
1308 4: a(k,k) = sqrt(a(k,k))
1310 6: a(i,k) = a(i,k)/a(k,k)
1312 7: doall j = k+1,n do
1313 5: for i = max(k+1,j),n do
1314 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
1320 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
1322 Now type X to escape to the main menu, and type W to write this version
1323 of the program to a file.
1324 The file will contain the program:
1330 a(k,k) = sqrt(a(k,k))
1332 a(i,k) = a(i,k)/a(k,k)
1335 for i = max(k+1,j),n do
1336 a(i,j) = a(i,j)-a(i,k)*a(j,k)
1341 To work with the wave program,
1342 type 'P' at the main menu (to parse a new program) and
1343 type 'wave' in response to the prompt for the filename.
1344 The new program is displayed:
1347 1: real a(1:100,1:100)
1352 11: a(i,j) = (a(i-1,j)+a(i,j-1)+a(i+1,j)+a(i,j+1))/4
1358 Browse File *Parse Restor System Trans Write Msgs Quit
1360 To try to parallelize the 'j' loop,
1361 enter the 'Browse' menu (by typing 'b') and move to the 'j' loop by
1365 1: real a(1:100,1:100)
1370 11: a(i,j) = (a(i-1,j)+a(i,j-1)+a(i+1,j)+a(i,j+1))/4
1376 Browse DD *Loop Restr See Undo Var Msgs Quit Xcape
1378 Parallelize the 'j' loop by typing 'R' and choosing the Parallelize
1382 1: real a(1:100,1:100)
1387 11: a(i,j) = (a(i-1,j)+a(i,j-1)+a(i+1,j)+a(i,j+1))/4
1393 Bump Circ Dist Inter Neg *Par Skew Vec Msgs Quit Xcape
1395 Unfortunately, parallel execution of the 'j' loop would be illegal;
1396 \*t responds by telling about the offending
1397 data dependence relations:
1400 1: real a(1:100,1:100)
1405 11: a(i,j) = (a(i-1,j)+a(i,j-1)+a(i+1,j)+a(i,j+1))/4
1410 flow dependence 11: --> 11:(<=,=,<) (*,0,1)
1411 *Accept Next Override Msgs Quit Xcape
1413 From this menu, you can accept the facts of life, or look at the next
1414 dependence relation, or override all these dependence relations
1415 (perform the transformation anyway).
1416 Typing 'N' to see the next dependence relation gives:
1419 1: real a(1:100,1:100)
1424 11: a(i,j) = (a(i-1,j)+a(i,j-1)+a(i+1,j)+a(i,j+1))/4
1429 anti dependence 11: --> 11:(<=,=,<) (*,0,1)
1430 Accept *Next Override Msgs Quit Xcape
1432 Any transformation which would violate a data dependence relation
1434 typing 'A' to accept these relations (or 'x' to escape)
1435 returns to the restructuring menu, without performing the transformation:
1438 1: real a(1:100,1:100)
1443 11: a(i,j) = (a(i-1,j)+a(i,j-1)+a(i+1,j)+a(i,j+1))/4
1448 Data Dependence prevents loop parallelization
1449 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
1451 In order to run one of 'i' or 'j' in parallel, since they both
1452 carry dependence relations, one of the loops must be skewed.
1453 Move to the 'j' loop and enter the restructuring menu again:
1456 1: real a(1:100,1:100)
1461 11: a(i,j) = (a(i-1,j)+a(i,j-1)+a(i+1,j)+a(i,j+1))/4
1466 Data Dependence prevents loop parallelization
1467 Bump Circ Dist Inter Neg Par *Skew Vec Msgs Quit Xcape
1469 Choose 'Skew', to get to the skew menu.
1470 Loop skewing with respect to outer loops is always legal;
1471 this menu allows me to choose the loop with respect to which to
1472 skew, though the skewing factor is always one:
1475 1: real a(1:100,1:100)
1480 11: a(i,j) = (a(i-1,j)+a(i,j-1)+a(i+1,j)+a(i,j+1))/4
1485 Data Dependence prevents loop parallelization
1486 Out *Forward Reverse By_Factor Msgs Quit Xcape
1488 Choosing 'Out' here moves the marker to the next outer loop; choosing
1489 'Forward' or 'Reverse' chooses forward (+1 factor) or reverse
1490 (-1 factor )skewing with respect to the marked loop;
1491 choosing By_Factor will skew by any constant integer factor.
1492 To choose forward skewing with respect to the 'i' loop, type 'f':
1495 1: real a(1:100,1:100)
1499 9: for j = 2+i,n-1+i do
1500 11: a(i,j-i) = (a(i-1,j-i)+a(i,j-i-1)+a(i+1,j-i)+a(i,j-i+1))/4
1505 Forward skew loop j with respect to i
1506 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
1508 Forward loop skewing simply adds the outer loop index to the lower and upper
1509 limit expressions (adds 'i' to the limits of 'j'), and subtracts
1510 the outer loop index from the inner loop index within the body of the loop.
1511 The other effect is on the data dependence relations, changing
1513 Now, interchanging the 'j' and 'i' loops gives:
1516 1: real a(1:100,1:100)
1519 9: for j = 2+2,n-1+(n-1) do
1520 7: for i = max(2,j-(n-1)),min(n-1,j-2) do
1521 11: a(i,j-i) = (a(i-1,j-i)+a(i,j-i-1)+a(i+1,j-i)+a(i,j-i+1))/4
1526 Interchanging loops i and j
1527 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
1529 This is the 'wavefront' formulation of the loop.
1530 Now, parallelizing the 'i' loop is legal:
1533 1: real a(1:100,1:100)
1536 9: for j = 2+2,n-1+(n-1) do
1537 7: doall i = max(2,j-(n-1)),min(n-1,j-2) do
1538 11: a(i,j-i) = (a(i-1,j-i)+a(i,j-i-1)+a(i+1,j-i)+a(i,j-i+1))/4
1544 Browse DD Loop *Restr See Undo Var Msgs Quit Xcape
1546 This version of the program can be written to a file
1547 by escaping to the main menu and choosing 'Write'.
1552 6. Menu Descriptions
1555 The various menus are described here.
1556 The main menu is first, and the remaining menus are listed
1558 The menus, along with their parentage, are:
1568 from Restructure Menu
1574 from restructuring transformation
1578 from See or Step Menu
1590 from Restructure Menu
1592 from Browse:Browse Menu
1599 A pictorial diagram of the menu lineage is:
1604 | +--- Browse:Browse
1625 Again, typing 'M' at any menu will get to the Msgs menu, displaying
1626 recent messages from \*t;
1627 typing 'Q' from any menu will quit \*t immediately;
1628 typing 'X' (or the escape key)
1629 from any menu except the Main menu will exit (escape) to the parent menu.
1639 Tiny Tool [as of December 1990]
1640 *Browse File Parse Restor System Trans Write Msgs Quit
1643 From the main menu, there are the following eight choices:
1645 Go to the Browse menu to create new program version via
1646 interactive restructuring or to browse the data structures.
1648 Go to the File menu to move around directories, edit files,
1649 start command shells, etc.
1651 Choose an initial file (if no file was given on the command line)
1652 or choose a different file to parse and then browse.
1653 \*t will ask for the file name to parse.
1655 Go to the Restore menu to restore an old program version.
1657 Go to the System menu to change dependence decision algorithm
1658 or verify data structures.
1660 Go to the Translate menu to change the display language, or
1661 to write out an assembler file.
1663 Write the current program version to a file;
1664 \*t will ask for the name of the file to write.
1666 Go to the Msgs menu and display the most recent messages.
1673 6.2 AutoParallel Menu
1676 This menu lets you decide whether or not \*t should attempt to
1677 parallelize every loop after each transformation.
1678 This is a simple way to see how your transformations have affected the
1679 parallelism in the program.
1680 Initially this option is disabled;
1681 you can enter this menu from the System menu.
1684 Tiny Tool [as of December 1990]
1685 *AutoParallel NoAutoParallel Msgs Quit Xcape
1688 Enable automatic parallelization.
1690 Disable automatic parallelization.
1699 This is the menu where you will probably spend lots of time.
1700 When you enter the Browse Menu, \*t highlights a 'current position'
1702 This will generally be a loop or a variable reference.
1703 When you first enter this mode, the current position will be
1707 1: real a(1:100,1:100,1:100)
1712 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
1719 *Browse DD Loop Restr See Undo Var Msgs Quit Xcape
1721 From this menu you can browse around the data structures,
1722 move the current position to another loop or variable,
1723 and perform or undo restructuring transformations.
1725 Go to the Browse:Browse menu (all right, it's a stupid name).
1727 Go to the DD Browse Menu to examine dependence relations.
1729 Move the current position to the next loop.
1731 Go to the Restructure Menu, to perform a restructuring transformation
1732 on this loop; the current position must be a loop.
1734 Traverse the abstract syntax tree (AST) data structure interactively,
1735 by going to the See menu.
1737 Undo the most recent restructuring transformation.
1738 See the discussion under 'Restore Menu' to see how this is implemented.
1740 Move the current position to the next variable reference.
1741 Note that due to the data structure for assignments, the right
1742 hand side expressions are visited 'before' the left hand side.
1747 6.4 Browse:Browse Menu
1750 This is a simple way to traverse the abstract syntax tree (AST)
1751 in detail, by moving to sibling, parent or child tree nodes one at a time.
1752 As in the Browse menu, the current position is highlighted.
1755 1: real a(1:100,1:100,1:100)
1760 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
1767 *Back Decl Jump Loop Next Step Var Msgs Quit Xcap
1769 The various menu choices move the current position around:
1771 Move the current position to the last position.
1773 If the current position is on a variable reference, move the current
1774 position to the declaration of that variable.
1776 Move to the next non-trivial operator or variable reference.
1778 Move the current position to the next loop.
1780 If the current position is on a variable reference, move the current
1781 position to the next reference of that variable.
1783 Go to the Step Menu.
1785 Move the current position to the next variable reference.
1793 When you want to circulate a loop ordering, this menu
1794 allows you to choose what type of circulation you want.
1795 Intercirculation is a circulation of the current loop to a position
1796 inside of some inner loop;
1797 outercirculation is a circulation of the current loop to a position
1798 outside of some enclosing loop.
1799 The Circulate Menu display highlights the loop inside or outside
1800 of which the current loop can be circulated.
1801 The Out menu choice highlights the next possible choice, and
1802 the Circulate menu choice enables circulation to inside of or outside
1803 of the highlighted loop.
1806 1: real a(1:100,1:100,1:100)
1811 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
1818 *Circulate Out Msgs Quit Xcape
1821 attempt to circulate the current loop inside of or outside of
1822 the highlighted loop.
1824 move the highlight to the next tightly-nested outer loop.
1832 At this menu you can inspect the data dependence relations in the program.
1835 1: real a(1:100,1:100,1:100)
1840 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
1847 *Cycle Goto Next Pred Succ Var Write Msgs Quit Xcape
1849 The message line will display the first dependence relation from the
1850 current position; if there are no dependence relations (as, for instance,
1851 for non-variable reference nodes) then this will also be displayed.
1852 The kind of dependence, line numbers, direction vector and distance
1853 vector are displayed; direction or distance vector elements which are unknown
1854 are displayed as asterisks.
1855 By default, this will display dependence successors of the current node,
1856 and both source and target of the dependence relation are highlighted.
1858 perhaps the most useful menu choice, this cycles through all the
1859 dependence relations in the program, moving the current position
1862 move the current position to the 'other end' of the dependence relation
1865 display the next dependence successor or predecessor of the current node.
1867 display dependence predecessors of the current node.
1869 display dependence successors of the current node.
1871 move the current position to the next variable reference.
1873 prompts for a file name, and write the dependence relations to that file.
1878 6.7 DD Algorithm Menu
1881 This menu lets the user choose what decision algorithm to use to
1882 solve the subscript dependence equation.
1883 This option will not take effect until the next program is
1884 parsed (using the Parse item from the Main Menu).
1887 *Simple Triang GGCD Lambda Power Msgs Quit Xcape
1890 Use a simple set of tests, including an exact test when only a single
1891 loop index variable appears in a subscript (to get dependence distances),
1892 and the GCD and simple Banerjee's Inequalities otherwise (to get
1893 dependence directions).
1894 These tests are applied subscript-by-subscript.
1896 As above, except use triangular Banerjee's Inequalities instead of
1897 the simple Inequalities.
1899 Use Banerjee's Generalized GCD simultaneous subscript test;
1900 this gives dependence distances if fixed.
1902 Use an implementation of the Lambda Test (see Li, Yew and Zhu's paper
1903 "Data Dependence Analysis on Multi-Dimensional Array References"
1904 in the 1989 ACM Int'l Conf. on Supercomputing proceedings, or
1906 "Data Dependence Analysis: The Lambda Test Revisited"
1907 in the 1990 Int'l Conf. on Parallel Processing proceedings).
1909 Use Banerjee's Generalized GCD test, extended by a different
1910 search for an empty solution space by modified Fourier-Motzgin search.
1915 6.8 DD Prevents Menu
1918 When data dependence relations prevent application of a restructuring
1919 transformation, those dependence relations are displayed.
1920 The user can view all the relations (using the Next menu option),
1921 Accept the restriction, or Override the dependence relations.
1922 Note: Choosing Override will blindly apply the transformation;
1923 the modified dependence graph after the transformation will probably
1925 In the example shown, the user tried to parallelize the 'k' loop.
1926 Since the 'k' loop carries a dependence relation (actually, two dependence
1927 relations), parallel execution is not allowed.
1930 1: real a(1:100,1:100,1:100)
1935 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
1941 flow dependence 11: --> 11:(=,=,<) (0,0,1)
1942 *Accept Next Override Msgs Quit Xcape
1945 accept this dependence restriction; do not apply the transformation.
1947 display the next data dependence relations that prevents this dependence.
1949 override the dependence restrictions and apply the transformation anyway.
1957 The file menu appears with a listing of the file names in the
1959 Subdirectory names are shown with a '/', and executable file
1960 names are shown with a '*', much as the command 'ls\ -F' does;
1961 the current directory name is shown at the top of the file listing:
1963 /ogc1/staff/mwolfe/tiny/test
1964 ave3 dd.t1 doc.wave example.3 parenb wave3
1965 ch dd.t2 doc2.log lu rev wave3a
1966 dd.1 dd.t3 doc3.log ludecomp rn1 wave3b
1967 dd.2 doc.ch dynamic paren wave
1968 dd.3 doc.ddfile example.1 paren2 wave.8wa
1969 dd.4 doc.log example.2 parena wave2
1971 Data Dependence prevents loop parallelization
1972 *Down Edit Newdir Redo Sh Up Msgs Quit Xcape
1975 Move down to a subdirectory; \*t will prompt for the subdirectory
1976 name to which to change.
1977 Currently the whole subdirectory name must be typed.
1979 Edit a file; currently, the editor to use is hard-coded in \*t as 'vi'.
1981 Make a new directory; \*t will prompt for the name of the subdirectory
1984 Go to the Redo (Restart) menu, from which stopped subprocesses
1986 Currently, the only processes that can be stopped are editor subprocesses.
1988 Start up a command shell; currently, the shell to use is
1989 hard-coded in \*t as 'csh'.
1991 Move Up to the parent menu (a la 'cd ..').
1993 Go to the Message display and menu.
1997 Return to the Main Menu.
2005 From the See or Step Menu, this menu moves the current position to the
2006 next operator of the specified type:
2009 1: real a(1:100,1:100)
2014 11: a(i,j) = (a(i-1,j)+a(i,j-1)+a(i+1,j)+a(i,j+1))/4
2020 *Asgn Entry Index Loop Oper Var Msgs Quit Xcap
2023 move the current position to the next assignment operator.
2025 move the current position to the entry node.
2027 move the current position to the next loop index reference.
2029 move the current position to the next loop.
2031 move the current position to the next operator.
2033 move the current position to the next variable reference.
2041 A list of stopped processes is given.
2046 spawned process 3a28 edit ave3 can be restarted
2047 *Start Msgs Quit Xcape
2049 Any one process can be restarted by choosing the menu item Start,
2050 and typing the number (0-9, in square brackets) corresponding
2052 Currently only 9 stopped processes are saved, and only
2053 editor processes may be stopped.
2055 Start one of the stopped processes.
2063 This interface is all new since the last version.
2064 When you restructure programs, or parse new programs, as long as you
2065 do not quit \*t, the data structures for each version of each program is saved.
2066 Using the Restore Menu, you can return to any previously parsed or
2067 restructured version of a program in this \*t session.
2068 The Restore display shows the chain of restructuring transformations
2069 taken to get to the 'current' version of the program:
2073 Skew loop j with respect to i
2074 Skew loop j with respect to k
2075 Circulate loop j outside of loop k
2077 Outercirculating loop j outside of k
2078 *Child Parent Next Prev Msgs Quit Xcape
2080 This display says that the original program was read from
2081 file 'wave3a', then skewed the 'j' loop with respect to 'i' and 'k', then
2082 circulated (interchanged) the 'j' loop to outside the 'k' loop.
2083 To return to a previous version, choose Parent from the menu,
2084 which will effectively 'undo' the bottom transformation;
2085 this is exactly how the 'Undo' menu item in the Browse Menu is implemented.
2086 That transformation can be effectively reapplied by choosing 'Child'
2088 If there are 'children' programs or derived programs from the current
2089 one, they are displayed with number identifiers:
2093 Skew loop j with respect to i
2094 Skew loop j with respect to k
2095 0: Circulate loop j outside of loop k
2097 Outercirculating loop j outside of k
2098 Child *Parent Next Prev Msgs Quit Xcape
2100 Choosing Child will cause Tiny to ask which child you want,
2101 and you are expected to respond with a digit, 0 through 9.
2103 Choose a child version of the program as the current version,
2104 effectively 'reapplying' a transformation.
2106 Choose the parent version of the program as the current version,
2107 effectively 'undoing' a transformation.
2109 Choose the next version of the program, essentially the next child
2111 For a top-level program, this goes to a 'later-parsed' program.
2113 Choose the previous version of the program, essentially the previous child
2115 For a top-level program, this goes to an 'earlier-parsed' program.
2120 6.13 Restructure Menu
2123 Here you choose one of several restructuring transformations
2124 to perform on the current loop.
2125 The current position must be a loop.
2128 1: real a(1:100,1:100)
2132 4: a(k,k) = sqrt(a(k,k))
2134 6: a(i,k) = a(i,k)/a(k,k)
2136 8: a(i,j) = a(i,j)-a(i,k)*a(j,k)
2142 *Bump Circ Dist Inter Neg Par Skew Vec Msgs Quit Xcape
2144 Most transformations have dependence tests which must be satisfied for
2145 the transformation to be legal.
2146 They also may modify the dependence relations, such as changing
2147 the dependence direction or distance.
2148 The restructuring transformations allowed are:
2150 bump a loop by adding a signed integer constant to both lower and upper limits.
2152 circulate the current loop inside or outside of a nest of tightly-nested loops.
2154 distribute the current loop.
2156 interchange the current loop with its immediately surrounding tightly
2157 nested surrounding loop.
2159 negate (reverse) the current loop.
2161 parallelize the current loop.
2163 skew the current loop with respect to an outer loop.
2165 vectorize the current loop, if it is an inner loop and has
2166 no dependence cycles (change to a 'forall').
2168 Transformations in the works are loop rotation, tiling and vectorization.
2176 This allows you to see a 'binary dump' of each abstract syntax tree
2177 node, and to move around the AST:
2181 value: 50578 (329080)
2193 Down *Find Goto Left Mark Rght Up Msgs Quit Xcap
2195 The binary dump includes the hexadecimal address of the node, with
2196 its line number (in square brackets), the node operator,
2197 its value in hex and decimal, the extra nodes and window position,
2198 and graphical display of the parent, child, sibling and link
2200 The menu choices are the same as for the Step Menu.
2202 Move the current position to its first child.
2204 Go to the Find Menu, to move the current position
2205 to the next operator of a particular type.
2207 Move the current position to one of the 26 previously marked positions.
2209 Move the current position to its left sibling.
2211 Mark the current position as one of 26 saved positions;
2212 \*t will prompt for a single-letter position name, [a-z].
2214 Move the current position to its right sibling.
2216 Move the current position to its parent.
2224 When you want to skew a loop, this menu
2225 allows you to choose what type of skewing (forward or reverse)
2226 and the loop with respect to which you want to skew.
2227 Forward skewing means skewing with a factor of +1, and reverse
2228 skewing is with a factor of -1.
2229 The Circulate Menu display highlights the outer loop with respect to which
2230 the skewing will be done.
2231 The Out menu choice highlights the next possible choice, and
2232 the Forward or Reverse menu choice enables the appropriate kind of skewing.
2235 1: real a(1:100,1:100,1:100)
2240 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
2246 No saved program in that direction
2247 *Out Forward Reverse By_Factor Msgs Quit Xcape
2250 Move the highlight to the next outer loop.
2252 Enable loop skewing by factor of +1.
2254 Enable loop skewing by factor of -1.
2256 Prompts for a (optionally signed) constant integer skewing factor;
2257 enables skewing by that factor.
2265 This is reached from the Browse:Browse Menu, and allows detailed traversal of
2266 the data structures.
2269 1: real a(1:100,1:100,1:100)
2274 11: a(k,i,j) = a(k,i-1,j)+a(k,i,j-1)+a(k,i,j+1)+a(k,i+1,j)+a(k-1,i,j)+a(k+1,
2280 No saved program in that direction
2281 *Down Find Goto Left Mark Rght Up Msgs Quit Xcap
2284 Move the current position to its first child.
2286 Go to the Find Menu, to move the current position
2287 to the next operator of a particular type.
2289 Move the current position to one of the 26 previously marked positions.
2291 Move the current position to its left sibling.
2293 Mark the current position as one of 26 saved positions;
2294 \*t will prompt for a single-letter position name, [a-z].
2296 Move the current position to its right sibling.
2298 Move the current position to its parent.
2306 The system menu lets the user change certain special options.
2309 *Auto DDalg File Output Struc Verify Write Msgs Quit Xcape
2312 Go to the AutoParallel Menu to decide whether or not to autoparallelize
2313 every loop after each transformation.
2315 Go to the DD Algorithm Menu to change the DD decision algorithm.
2317 Prompts for a file name, then reopens 'debug' as that file.
2319 Reopens 'debug' as standard output.
2321 Dump the abstract syntax tree (AST) data structure to the current 'debug' file.
2323 Verifies that the abstract syntax tree (AST) has no bogus pointers.
2324 The verifier reports any data structure inconsistencies.
2325 This is useful when debugging new transformations.
2327 Writes the program to the current 'debug' file.
2328 This is useful when 'debug' is another file.
2336 This menu lets you choose to view the program in a Fortran syntax
2337 as opposed to \*t syntax, or to compile the program
2338 into Alliant assembler code.
2341 *Fortran Tiny Asm Quit Xcape
2344 This option lets you view the program using Fortran syntax for loops.
2345 You may have to type ^L (control-L) to get the Fortran to show up.
2346 Here, Alliant directives are used to show parallel and vector loops.
2347 If Fortran is chosen, then when the program is written out, it will also
2349 Note that Tiny does NOT have a Fortran parser, so it will not accept this
2351 Also note that the output may need modifications to be compiled and executed,
2352 since the Tiny language has no procedure header statements and the like.
2354 This option lets you view the program in the default Tiny syntax.
2356 This option will "compile" the program, as it has been transformed,
2357 into Alliant FX/8 assembler code.
2360 AST Dump Information
2362 7. AST Dump Information
2365 A sample 'dump' is given here.
2371 a(i,j) = a(i,j-1) + 1
2375 the interactive display is:
2378 1: real a(1:10,1:10)
2381 4: a(i,j) = a(i,j-1)+1
2387 Auto DDalg File Output *>Struc< Verify Write Msgs Quit Xcape
2389 The dump (to the 'debug' file, whether it be opened to standard output,
2390 the default, or to a file) would be:
2394 .[ 35424] 0=Child, 353f0=Next, entry
2395 . 0=Parnt, 0=Prev, 0=Val
2396 .[ 353f0] 353bc=Child, 3521c=Next, declare
2397 . 0=Parnt, 35424=Prev, 21404=Val
2398 ..[ 353bc] 35388=Child, 35320=Next, bounds
2399 .. 353f0=Parnt, 0=Prev, 0=Val
2400 ...[ 35388] 0=Child, 35354=Next, constant
2401 ... 353bc=Parnt, 0=Prev, 1=Val
2402 ...[ 35354] 0=Child, 0=Next, constant
2403 ... 353bc=Parnt, 35388=Prev, a=Val
2404 ..[ 35320] 352ec=Child, 0=Next, bounds
2405 .. 353f0=Parnt, 353bc=Prev, 0=Val
2406 ...[ 352ec] 0=Child, 352b8=Next, constant
2407 ... 35320=Parnt, 0=Prev, 1=Val
2408 ...[ 352b8] 0=Child, 0=Next, constant
2409 ... 35320=Parnt, 352ec=Prev, a=Val
2410 .[ 3521c] 351e8=Child, 0=Next, do
2411 . 0=Parnt, 353f0=Prev, 1=Val
2412 ..[ 351e8] 3514c=Child, 35284=Next, dolimit
2413 .. 3521c=Parnt, 0=Prev, 21444=Val
2414 ...[ 3514c] 35118=Child, 0=Next, do
2415 ... 351e8=Parnt, 0=Prev, 2=Val
2416 ....[ 35118] 34edc=Child, 351b4=Next, dolimit
2417 .... 3514c=Parnt, 0=Prev, 21484=Val
2418 .....[ 34edc] 34ea8=Child, 34e40=Next, stmtnumber
2419 ..... 35118=Parnt, 0=Prev, 1=Val
2420 ......[ 34ea8] 0=Child, 34e74=Next, index
2421 ...... 34edc=Parnt, 0=Prev, 351e8=Val
2422 ......[ 34e74] 0=Child, 0=Next, index
2423 ...... 34edc=Parnt, 34ea8=Prev, 35118=Val
2424 .....[ 34e40] 34f10=Child, 0=Next, assign
2425 ..... 35118=Parnt, 34edc=Prev, 0=Val
2426 ......[ 34f10] 35048=Child, 350e4=Next, add
2427 ...... 34e40=Parnt, 0=Prev, 0=Val
2428 .......[ 35048] 35014=Child, 34f44=Next, fetch_array
2429 ....... 34f10=Parnt, 0=Prev, 353f0=Val
2430 ........[ 35014] 0=Child, 34f78=Next, index
2431 ........ 35048=Parnt, 0=Prev, 351e8=Val
2432 ........[ 34f78] 34fe0=Child, 0=Next, subtract
2433 ........ 35048=Parnt, 35014=Prev, 0=Val
2434 .........[ 34fe0] 0=Child, 34fac=Next, index
2435 ......... 34f78=Parnt, 0=Prev, 35118=Val
2436 .........[ 34fac] 0=Child, 0=Next, constant
2437 ......... 34f78=Parnt, 34fe0=Prev, 1=Val
2438 .......[ 34f44] 0=Child, 0=Next, constant
2439 ....... 34f10=Parnt, 35048=Prev, 1=Val
2440 ......[ 350e4] 350b0=Child, 0=Next, store
2441 ...... 34e40=Parnt, 34f10=Prev, 353f0=Val
2442 .......[ 350b0] 0=Child, 3507c=Next, index
2443 ....... 350e4=Parnt, 0=Prev, 351e8=Val
2444 .......[ 3507c] 0=Child, 0=Next, index
2445 ....... 350e4=Parnt, 350b0=Prev, 35118=Val
2446 ....[ 351b4] 0=Child, 35180=Next, constant
2447 .... 3514c=Parnt, 35118=Prev, 2=Val
2448 ....[ 35180] 0=Child, 0=Next, constant
2449 .... 3514c=Parnt, 351b4=Prev, a=Val
2450 ..[ 35284] 0=Child, 35250=Next, constant
2451 .. 3521c=Parnt, 351e8=Prev, 1=Val
2452 ..[ 35250] 0=Child, 0=Next, constant
2453 .. 3521c=Parnt, 35284=Prev, a=Val
2457 The number in brackets is the hexadecimal address of that AST entry.
2458 The Child, Next, Parnt and Prev numbers are the hexadecimal addresses
2459 of the AST entries pointed to by the Child, Next, Parent and Previous pointers.
2460 The Node Operator is given in text, and the Value is given is hex.
2463 Installation and Distribution
2465 8. Installation and Distribution
2468 \*t was designed to be relatively portable, but it's pretty rough;
2469 in many cases, a choice between elegance, portability and simplicity
2470 was made in favor of ease of implementation.
2471 It has been installed on many a Unix system using native compilers
2472 and the Gnu 'gcc', and on an IBM PC-clone using the Turbo C++ compiler.
2473 The entire design and implementation is geared toward supporting
2474 a research effort into elementary program restructuring, not toward
2475 developing an industrial-strength product.
2476 It is written in ANSI 'C' (bleah), with special hooks to be able
2477 to compile it on compilers without ANSI function headers
2478 (just about the only ANSI C features used).
2479 \*t uses a character-based interface, using the 'Curses' character windowing
2480 package to manage the screen (bleah) under Unix, and uses
2481 the Turbo C screen addressing routines on a PC.
2482 I would like to install \*t on an X-window interface, but
2483 that awaits some other interested graduate student.
2485 In the best of cases, a simple 'make t' do all the compiles and links.
2486 Some modifications may be necessary.
2488 I will gladly accept bug reports, suggestions or enhancements, but
2489 I cannot promise that anything will get fixed, except that I'll do my best,
2490 given the time and resources at my command.
2492 The source or object code of
2493 \*t may be freely redistributed and reused as you see fit.