source: proto/s2k/trunk/framework/src/toolchain/s2k/transformer/visitors/S2K2S2K/TempifyCarrySetBuiltinCalls.java @ 4101

Last change on this file since 4101 was 4101, checked in by ksherdy, 4 years ago

Tempify IDISA calls.

File size: 8.6 KB
Line 
1/*
2 * Converts carry generating builtins expressions to a compiled form.
3 * Applied before carry variable insertion.
4 *
5 * @author Ken Herdy <ksherdy at sfu dot ca>
6 *
7 * Case 1: 'assignment' statement
8 *
9 * returnValue = pablo.BUILTIN_CALL(args) 
10 *
11 * =>
12 *
13 * stream temp;
14 * temp = pablo_blk_BUILTIN_CALL(args);
15 *   
16 * Case 2: 'if' condition
17 *
18 * if(pablo.BUILTIN_CALL(args) { ... }
19 *
20 * } 
21 *
22 * =>
23 *
24 * stream temp;
25 * temp = pablo_blk_BUILTIN_CALL(args);
26 * if(temp) { ... }
27 *
28 * Case 3: 'while' condition
29 *
30 * while(pablo.BUILTIN_CALL(args) { ... } 
31 *
32 * =>
33 *
34 * stream temp:
35 * temp = pablo_blk_BUILTIN_CALL(args);
36 * while(temp) {
37 *  ...
38 *   
39 *  stream temp:
40 *  temp = pablo_blk_BUILTIN_CALL(args); 
41 * } 
42 *   
43 */
44package toolchain.s2k.transformer.visitors.S2K2S2K;
45
46import java.util.LinkedHashMap;
47import java.util.List;
48import java.util.Map;
49
50import s2k.ast.*;
51import s2k.inputHandler.Locator;
52import toolchain.s2k.ast.Accessors;
53import toolchain.s2k.ast.Generators;
54import toolchain.s2k.lang.builtin.S2KBuiltinsUtil;
55import toolchain.s2k.lang.builtin.S2KBuiltins.CarryType;
56import toolchain.util.Labeller;
57import toolchain.util.Pair;
58import static toolchain.s2k.lang.signatures.SignatureShorthand.sig_II_S;
59import static toolchain.s2k.lang.signatures.SignatureShorthand.sig_ST_V;
60import static toolchain.s2k.lang.signatures.SignatureShorthand.sig_S_S;
61import static toolchain.util.MapUtil.*;
62
63public class TempifyCarrySetBuiltinCalls {
64       
65        static public ASTNode apply(ASTNode ASTree) {
66           
67            ASTNode xTree = SplitVarDeclInits.apply(ASTree);
68           
69            Tempifier tempifier = new Tempifier();
70            xTree.accept(tempifier);
71                return ASTree;                 
72        }   
73   
74        static private class Tempifier extends VoidVisitor.Default {
75           
76            Labeller labeller;
77            Map<ASTNode, List<ASTNode>> enclBlockStmtTempDecls; 
78            Map<ASTNode, List<Pair<ASTNode, List<ASTNode>>>> tempDeclsInsertionChild;
79           
80            Map<ASTNode, List<ASTNode>> enclBlockStmtTempAssigns; 
81            Map<ASTNode, List<Pair<ASTNode, List<ASTNode>>>> tempAssignsInsertionChild;
82
83            public Tempifier() {
84                this(0);
85            }
86
87            public Tempifier(int nextValue) {
88                labeller = new Labeller("_temp");
89                labeller.setNextValue(nextValue);
90
91            enclBlockStmtTempDecls = new LinkedHashMap<ASTNode, List<ASTNode>>();
92            enclBlockStmtTempAssigns = new LinkedHashMap<ASTNode, List<ASTNode>>();
93               
94                tempDeclsInsertionChild = new LinkedHashMap<ASTNode, List<Pair<ASTNode, List<ASTNode>>>>();
95                tempAssignsInsertionChild = new LinkedHashMap<ASTNode, List<Pair<ASTNode, List<ASTNode>>>>();
96            }
97
98        //////////////////////////////////////////////////////////////
99        // visitor callbacks
100           
101            public void visitEnter(FilterDefNode node) {
102                labeller.reset();
103               
104                enclBlockStmtTempDecls.clear();
105                enclBlockStmtTempAssigns.clear();
106               
107                tempDeclsInsertionChild.clear();
108                tempAssignsInsertionChild.clear();
109            }
110           
111            public void visitLeave(BlockStmtNode node) {
112            insertTempDecls(node);
113            insertTempAssigns(node);
114            }
115   
116            public void visitLeave(AssignNode node) {
117            bindTempDeclsToBlockStmt(node);
118            bindTempAssignToBlockStmt(node);           
119            }
120           
121            public void visitLeave(WhileStmtNode node) {
122
123                appendTempDeclsToWhileBody(node);      // WARNING: appendTemp calls must precede bindTemp calls
124            appendTempAssignsToWhileBody(node);
125               
126                bindTempDeclsToBlockStmt(node);
127            bindTempAssignToBlockStmt(node);
128            }
129
130        public void visitLeave(IfStmtNode node) {
131            bindTempDeclsToBlockStmt(node);
132            bindTempAssignToBlockStmt(node);
133        }
134
135        public void visitLeave(FuncCallNode node) { 
136           
137           
138            if(S2KBuiltinsUtil.isCarry(node)) { // KH: bug to fix
139               
140                if(!(node.getParent() instanceof AssignNode)) {
141               
142                    BlockStmtNode blockStmt          = Accessors.getEnclosingBlockStmt(node);
143                    Locator locator                  = blockStmt;
144                    IdentifierNode name              = Generators.makeIdentifierNode(locator, labeller.newLabel());
145                    StreamTypeNode type              = Generators.makeStreamType(locator);
146                    VarDeclNode varDecl              = Generators.makeVarDeclNode(locator, type, name.deepCopy());
147                    AssignNode assignStmt            = Generators.makeAssignNode(locator, name.deepCopy(), node.deepCopy());
148
149                    addValueToList(enclBlockStmtTempDecls, blockStmt, varDecl);
150                    addValueToList(enclBlockStmtTempAssigns, blockStmt, assignStmt);
151
152                    node.updateSelf(name);               
153                }
154            }
155        }
156       
157        public void visitLeave(IdisaFuncCallNode node) { 
158            if(!(node.getParent() instanceof AssignNode)) {
159           
160                BlockStmtNode blockStmt          = Accessors.getEnclosingBlockStmt(node);
161                Locator locator                  = blockStmt;
162                IdentifierNode name              = Generators.makeIdentifierNode(locator, labeller.newLabel());
163                StreamTypeNode type              = Generators.makeStreamType(locator);
164                VarDeclNode varDecl              = Generators.makeVarDeclNode(locator, type, name.deepCopy());
165                AssignNode assignStmt            = Generators.makeAssignNode(locator, name.deepCopy(), node.deepCopy());
166
167                addValueToList(enclBlockStmtTempDecls, blockStmt, varDecl);
168                addValueToList(enclBlockStmtTempAssigns, blockStmt, assignStmt);
169
170                node.updateSelf(name);               
171            }
172        }       
173       
174        //////////////////////////////////////////////////////////////
175        // helpers
176       
177        private void appendTempAssignsToWhileBody(WhileStmtNode node) {
178            BlockStmtNode whileBody    = Accessors.body(node);
179            BlockStmtNode blockStmt    = Accessors.getEnclosingBlockStmt(node);
180            if(enclBlockStmtTempAssigns.containsKey(blockStmt)) {
181                for(ASTNode tempAssign : enclBlockStmtTempAssigns.get(blockStmt)) {
182                    whileBody.appendChild(tempAssign);
183                }
184            }
185        }
186
187        private void appendTempDeclsToWhileBody(WhileStmtNode node) {
188            BlockStmtNode whileBody    = Accessors.body(node);
189            BlockStmtNode blockStmt    = Accessors.getEnclosingBlockStmt(node);
190            if(enclBlockStmtTempDecls.containsKey(blockStmt)) {
191                for(ASTNode tempDecl : enclBlockStmtTempDecls.get(blockStmt)) {
192                    whileBody.appendChild(tempDecl);
193                }
194            }
195        }
196       
197        private void insertTempAssigns(BlockStmtNode node) {
198            if(tempAssignsInsertionChild.containsKey(node)) {
199                List<Pair<ASTNode, List<ASTNode>>> pairs = tempAssignsInsertionChild.get(node);
200                for(Pair<ASTNode, List<ASTNode>> pair : pairs) {
201                    for(ASTNode predecessor : pair.right()) {
202                        node.insertBeforeChild(pair.left(), predecessor);
203                    }
204                }
205            }
206        }
207
208        private void insertTempDecls(BlockStmtNode node) {
209            if(tempDeclsInsertionChild.containsKey(node)) {
210                List<Pair<ASTNode, List<ASTNode>>> pairs = tempDeclsInsertionChild.get(node);
211                for(Pair<ASTNode, List<ASTNode>> pair : pairs) {
212                    for(ASTNode predecessor : pair.right()) {
213                        node.insertBeforeChild(pair.left(), predecessor);
214                    }
215                }
216            }
217        }
218       
219        private void bindTempAssignToBlockStmt(ASTNode node) {
220            BlockStmtNode blockStmt          = Accessors.getEnclosingBlockStmt(node);
221            if(enclBlockStmtTempAssigns.containsKey(blockStmt)) {
222                addValueToList(tempAssignsInsertionChild, blockStmt, new Pair<ASTNode, List<ASTNode>>(node, enclBlockStmtTempAssigns.get(blockStmt)));
223                enclBlockStmtTempAssigns.remove(blockStmt);
224            }
225        }
226
227        private void bindTempDeclsToBlockStmt(ASTNode node) {
228            BlockStmtNode blockStmt          = Accessors.getEnclosingBlockStmt(node);
229            if(enclBlockStmtTempDecls.containsKey(blockStmt)) {
230                addValueToList(tempDeclsInsertionChild, blockStmt, new Pair<ASTNode, List<ASTNode>>(node, enclBlockStmtTempDecls.get(blockStmt)));
231                enclBlockStmtTempDecls.remove(blockStmt);
232            }
233        }           
234
235    }
236}
237
Note: See TracBrowser for help on using the repository browser.