source: proto/pablo/src/compiler/backend/visitors/AdvanceCombinerXFormer.java @ 2710

Last change on this file since 2710 was 2710, checked in by ksherdy, 6 years ago

General refactoring.

File size: 3.0 KB
Line 
1package compiler.backend.visitors;
2
3import ast.*;
4import compiler.ast.Accessors;
5import compiler.ast.Generators;
6import compiler.lang.pablo.BuiltinsUtil;
7
8import tokens.*;
9
10public class AdvanceCombinerXFormer {
11       
12    private ASTNode ASTTree;
13   
14    public AdvanceCombinerXFormer(ASTNode astTree) {
15        this.ASTTree = astTree;
16    }
17   
18    public void XForm() {
19        AdvanceCombinerVisitor visitor = new AdvanceCombinerVisitor();
20        ASTTree.accept(visitor);
21    }   
22   
23        // Original python method optimized calls that look like:
24        //              adv(adv(X))             to      adv(X, 2), and
25        //              adv(adv(X, n))  to  adv(X, n+1)
26        //
27        // presumably adv(adv(X), n) were not optimized because this pattern
28        // was not seen (often) in the input.  We instead choose to optimize
29        // that pattern and also adv(adv(X, n2), n1).
30
31        private class AdvanceCombinerVisitor extends VoidVisitor.Default {
32
33                public void visitEnter(IfStmtNode node) {
34                    // Additional carry logic req'd to support carry combine within If stmts
35                        node.skipChildren();
36                }
37                public void visitEnter(WhileStmtNode node) { 
38                    // Additional carry logic req'd to support carry combine within While stmts
39                        node.skipChildren();
40                }
41
42                public void visitLeave(FuncCallNode node) {
43                       
44                        if(!isAdvanceOfAdvance(node)) { 
45                                return;
46                        }
47                                                       
48                        ASTNode argsList = Accessors.funcCallArgsListNode((FuncCallNode) node);
49                        FuncCallNode child = (FuncCallNode)argsList.child(0);
50                       
51                        int amount1 = advanceAmount(node);
52                        int amount2 = advanceAmount(child);
53                                               
54                        translateAdvanceNode(node, child, amount1, amount2);
55                }               
56        }
57       
58        private int valueOf(ASTNode node) {
59                assert node instanceof IntegerConstantNode;
60                IntConstantToken token = (IntConstantToken) node.getToken();
61                return token.getValue();
62        }
63
64        private int advanceAmount(FuncCallNode node) {
65                assert BuiltinsUtil.isAdvance(node);
66                if(Accessors.funcCallArgsListNode(node).nChildren()==1) {
67                        return 1;
68                }
69                assert Accessors.funcCallArgsListNode(node).nChildren()==2;
70                return valueOf(Accessors.funcCallArgsListNode(node).child(1));
71        }       
72       
73        private boolean isAdvanceOfAdvance(ASTNode node) {
74                if(!BuiltinsUtil.isAdvance(node)) {
75                        return false;
76                }                       
77               
78                ASTNode argsList = Accessors.funcCallArgsListNode((FuncCallNode) node);
79               
80                return BuiltinsUtil.isAdvance(argsList.child(0));
81        }
82       
83        private void translateAdvanceNode(
84                        FuncCallNode node,
85                        FuncCallNode child, 
86                        int amount1, int amount2) {
87               
88                node.replaceChild(      Accessors.funcCallArgsListNode(node), 
89                                                        Accessors.funcCallArgsListNode(child));
90               
91                IntegerConstantNode integerConstantNode = Generators.makeIntegerConstantNode(amount1+amount2, node.getToken());
92                if(Accessors.funcCallArgsListNode(node).nChildren()==1) {
93                        Accessors.funcCallArgsListNode(child).appendChild(integerConstantNode);
94                }
95                assert Accessors.funcCallArgsListNode(node).nChildren()==2;
96                Accessors.funcCallArgsListNode(node).replaceChild(
97                                Accessors.funcCallArgsListNode(node).child(1), 
98                                integerConstantNode);
99        }
100}
Note: See TracBrowser for help on using the repository browser.