source: proto/pablo/src/compiler/semanticAnalyzer/visitors/Pablo2CarryXFormer.java @ 2702

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

General refactoring (variable names). Added final block XFormer. Move final block operations atEOF/inFile out of carry intro transformer to final block transformer.

File size: 16.0 KB
Line 
1package compiler.semanticAnalyzer.visitors;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import ast.*;
7import compiler.ast.Accessors;
8import compiler.ast.Generators;
9import compiler.lang.carryset.CarrySet;
10import compiler.lang.carryset.CarrySet2Lang;
11import compiler.lang.idisa.SIMD;
12import compiler.lang.pablo.*;
13
14
15
16public class Pablo2CarryXFormer {
17               
18        private ASTNode ASTTree;       
19       
20        private Builtins2Lang builtins2Lang;
21        private CarrySet2Lang carrySet2Lang;
22       
23    //    def __init__(self, carryvar="carryQ", carryin = "_ci", carryout = "_co"):
24        //    self.carryvar = ast.Name(carryvar, ast.Load())
25        //    self.carryin = carryin
26        //    self.carryout = carryout   
27       
28    public Pablo2CarryXFormer(ASTNode node, Builtins2Lang builtins2Lang, CarrySet2Lang carrySet2Lang) {
29        this.ASTTree = node; 
30        this.builtins2Lang = builtins2Lang;
31        this.carrySet2Lang = carrySet2Lang;
32    }
33
34    public void XForm(boolean ci /*, boolean co*/) {
35                XFormer visitor = new XFormer(ci /*, co*/);
36                ASTTree.accept(visitor);
37    }                   
38       
39        private class XFormer extends VoidVisitor.Default {
40
41                //private final String ciSuffix = "_ci";
42                //private final String coSuffix = "_co";
43                //private String [] pendindCarryQName = {CarryQ.CarryQ_PACKAGE_NAME, CarryQ.GETCARRYIN.cPPCode()};
44                //private String [] pending64QName = {CarryQ.CarryQ_PACKAGE_NAME, CarryQ.GETPENDING64.cPPCode()};
45               
46                private boolean ciMode;
47                //private boolean coMode;
48                               
49                private int currentCarry;
50                private int currentAdvN;
51                //private int lastStmtCarries;
52               
53                XFormer(boolean ciMode /*, boolean coMode*/) {
54                        this.ciMode = ciMode;
55                        //this.coMode = coMode;
56                        this.currentCarry = 0;
57                        this.currentAdvN = 0;
58                        //this.lastStmtCarries = 0;
59                }
60               
61                //              def xfrm_fndef(self, fndef):
62                //          self.current_carry = 0
63                //          self.current_adv_n = 0
64                //          carry_count = CarryCounter().count(fndef)
65                //          if carry_count == 0: return fndef
66                //          self.generic_visit(fndef)
67                //      #   
68                //      #    fndef.body.insert(0, mkCallStmt('CarryDeclare', [self.carryvar, ast.Num(carry_count)]))
69                //          return fndef
70                public void visitEnter(FuncDefNode node) { // TODO - CarryIf duplicates
71                        this.currentCarry = 0;
72                        this.currentAdvN = 0;
73                        //this.lastStmtCarries = 0;                     
74                }               
75               
76                public void visitLeave(FuncCallNode node) {
77                       
78                        ASTNode replacementNode;
79                       
80                        ASTNode carryCall;
81                        IntegerConstantNode currentCarry = Generators.makeIntegerConstantNode(this.currentCarry, node.getToken());
82                       
83                        ASTNode advNCall;
84                        IntegerConstantNode currentAdvN = Generators.makeIntegerConstantNode(this.currentAdvN, node.getToken());
85
86//                  if self.carryin == "_ci":
87//              carry_args = [mkCall(self.carryvar.id + "." + 'get_carry_in', [ast.Num(self.current_carry)]), ast.Num(self.current_carry)]
88//              adv_n_args = [mkCall(self.carryvar.id + "." + 'get_pending64', [ast.Num(self.current_adv_n)]), ast.Num(self.current_adv_n)]
89//          else:
90//              carry_args = [mkCall('simd<1>::constant<0>', []), ast.Num(self.current_carry)]
91//              adv_n_args = [mkCall('simd<1>::constant<0>', []), ast.Num(self.current_adv_n)]
92
93//                      TODO - Deprecate ciMode - *likely* no longer required
94//
95//                     
96                        if(ciMode) {
97                                carryCall = Generators.makeFuncCallNode(
98                                                new String [] {CarrySet.CarryQ_IDENTIFIER, carrySet2Lang.getCode(CarrySet.GETCARRYIN)}, 
99                                                node.getToken(),
100                                                new ASTNode [] {currentCarry});
101                               
102                                advNCall = Generators.makeFuncCallNode(
103                                                new String [] {CarrySet.CarryQ_IDENTIFIER, carrySet2Lang.getCode(CarrySet.GETPENDING64)}, 
104                                                node.getToken(),
105                                                new ASTNode [] {currentAdvN});
106                               
107                        } else {
108                                carryCall = Generators.makeIntegerConstantNode(0, node.getToken());
109                                advNCall = Generators.makeIntegerConstantNode(0, node.getToken());
110                        }
111                                               
112        //                  if is_BuiltIn_Call(callnode, 'Advance', 1):         
113        //                    #CARRYSET
114        //                    rtn = self.carryvar.id + "." + "BitBlock_advance_ci_co"
115        //                    c = mkCall(rtn, callnode.args + carry_args)
116        //                    self.current_carry += 1
117        //                    return c                 
118                        if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCE.pabloName(), Builtins.ADVANCE.argCount())) {         
119                                replaceFuncCallNode(node, 
120                                                CarrySet.CarryQ_IDENTIFIER, 
121                                                builtins2Lang.getCode(Builtins.ADVANCE), 
122                                                carryCall, 
123                                                currentCarry);
124                                this.currentCarry += 1;
125                        }
126       
127        //          elif is_BuiltIn_Call(callnode, 'ScanThru', 2):
128        //            #CARRYSET
129        //            rtn = self.carryvar.id + "." + "BitBlock_scanthru_ci_co"
130        //            c = mkCall(rtn, callnode.args + carry_args)
131        //            self.current_carry += 1
132        //            return c         
133                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.SCANTHRU.pabloName(), Builtins.SCANTHRU.argCount())) {                           
134                                replaceFuncCallNode(node, 
135                                                CarrySet.CarryQ_IDENTIFIER, 
136                                                builtins2Lang.getCode(Builtins.SCANTHRU), 
137                                                carryCall, 
138                                                currentCarry);
139                                this.currentCarry += 1;
140                        }
141       
142        //          elif is_BuiltIn_Call(callnode, 'AdvanceThenScanThru', 2):
143        //            #CARRYSET
144        //            rtn = self.carryvar.id + "." + "BitBlock_advance_then_scanthru"
145        //            c = mkCall(rtn, callnode.args + carry_args)
146        //            self.current_carry += 1
147        //            return c         
148                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCETHENSCANTHRU.pabloName(), Builtins.ADVANCETHENSCANTHRU.argCount())) {
149                                replaceFuncCallNode(node, 
150                                                CarrySet.CarryQ_IDENTIFIER, 
151                                                builtins2Lang.getCode(Builtins.ADVANCETHENSCANTHRU), 
152                                                carryCall, 
153                                                currentCarry);
154                                this.currentCarry += 1;
155                        }               
156       
157        //          elif is_BuiltIn_Call(callnode, 'SpanUpTo', 2):
158        //            #CARRYSET
159        //            rtn = self.carryvar.id + "." + "BitBlock_span_upto"
160        //            c = mkCall(rtn, callnode.args + carry_args)
161        //            self.current_carry += 1
162        //            return c         
163                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.SPANUPTO.pabloName(), Builtins.SPANUPTO.argCount())) {
164                                replaceFuncCallNode(node, 
165                                                CarrySet.CarryQ_IDENTIFIER, 
166                                                builtins2Lang.getCode(Builtins.SPANUPTO), 
167                                                carryCall, 
168                                                currentCarry);                         
169                                this.currentCarry += 1;
170                        }               
171       
172        //          elif is_BuiltIn_Call(callnode, 'AdvanceThenScanTo', 2):
173        //            #CARRYSET
174        //            rtn = self.carryvar.id + "." + "BitBlock_advance_then_scanthru"
175        //            if self.carryout == "":  scanclass = mkCall('simd_andc', [ast.Name('EOF_mask', ast.Load()), callnode.args[1]])
176        //            else: scanclass = mkCall('simd_not', [callnode.args[1]])
177        //            c = mkCall(rtn, [callnode.args[0], scanclass] + carry_args)
178        //            self.current_carry += 1
179        //            return c
180                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCETHENSCANTO.pabloName(), Builtins.ADVANCETHENSCANTO.argCount())) {
181                                replaceFuncCallNode(node, 
182                                                CarrySet.CarryQ_IDENTIFIER, 
183                                                builtins2Lang.getCode(Builtins.ADVANCETHENSCANTO), 
184                                                carryCall, 
185                                                currentCarry);
186                                this.currentCarry += 1;
187                        }               
188                       
189        //          elif is_BuiltIn_Call(callnode, 'InclusiveSpan', 2):
190        //            #CARRYSET
191        //      #      rtn = self.carryvar.id + "." + "BitBlock_span_upto"
192        //      #      c = mkCall('simd_or', [mkCall(rtn, callnode.args + carry_args), callnode.args[1]])
193        //            rtn = self.carryvar.id + "." + "BitBlock_inclusive_span"
194        //            c = mkCall(rtn, callnode.args + carry_args)
195        //            self.current_carry += 1
196        //            return c
197       
198                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.INCLUSIVESPAN.pabloName(), Builtins.INCLUSIVESPAN.argCount())) {
199                                replaceFuncCallNode(node, 
200                                                CarrySet.CarryQ_IDENTIFIER, 
201                                                builtins2Lang.getCode(Builtins.INCLUSIVESPAN), 
202                                                carryCall, 
203                                                currentCarry);
204                                this.currentCarry += 1;
205                        }                               
206                       
207        //          elif is_BuiltIn_Call(callnode, 'ExclusiveSpan', 2):
208        //            #CARRYSET
209        //      #      rtn = self.carryvar.id + "." + "BitBlock_span_upto"
210        //      #      c = mkCall('simd_andc', [mkCall(rtn, callnode.args + carry_args), callnode.args[0]])
211        //            rtn = self.carryvar.id + "." + "BitBlock_exclusive_span"
212        //            c = mkCall(rtn, callnode.args + carry_args)
213        //            self.current_carry += 1
214        //            return c
215       
216                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.EXCLUSIVESPAN.pabloName(), Builtins.EXCLUSIVESPAN.argCount())) {
217                                replaceFuncCallNode(node, 
218                                                CarrySet.CarryQ_IDENTIFIER, 
219                                                builtins2Lang.getCode(Builtins.EXCLUSIVESPAN), 
220                                                carryCall, 
221                                                currentCarry);
222                                this.currentCarry += 1;
223                        }                                               
224                       
225        //          elif is_BuiltIn_Call(callnode, 'ScanTo', 2):
226        //            # Modified Oct. 9, 2011 to directly use BitBlock_scanthru, eliminating duplication
227        //            # in having a separate BitBlock_scanto routine.
228        //            #CARRYSET
229        //            rtn = self.carryvar.id + "." + "BitBlock_scanthru_ci_co"
230        //            if self.carryout == "":  scanclass = mkCall('simd_andc', [ast.Name('EOF_mask', ast.Load()), callnode.args[1]])
231        //            else: scanclass = mkCall('simd_not', [callnode.args[1]])
232        //            c = mkCall(rtn, [callnode.args[0], scanclass] + carry_args)
233        //            self.current_carry += 1
234        //            return c
235       
236                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.SCANTO.pabloName(), Builtins.SCANTO.argCount())) {
237                                replaceFuncCallNode(node, 
238                                                CarrySet.CarryQ_IDENTIFIER, 
239                                                builtins2Lang.getCode(Builtins.SCANTO), 
240                                                carryCall, 
241                                                currentCarry);
242                                this.currentCarry += 1;
243                        }                                                               
244                       
245        //          elif is_BuiltIn_Call(callnode, 'ScanToFirst', 1):
246        //            #CARRYSET
247        //            rtn = self.carryvar.id + "." + "BitBlock_scantofirst"
248        //            #if self.carryout == "":  carry_args = [ast.Name('EOF_mask', ast.Load())] + carry_args
249        //            c = mkCall(rtn, callnode.args + carry_args)
250        //            self.current_carry += 1
251        //            return c
252       
253                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.SCANTOFIRST.pabloName(), Builtins.SCANTOFIRST.argCount())) {
254                                replaceFuncCallNode(node, 
255                                                CarrySet.CarryQ_IDENTIFIER, 
256                                                builtins2Lang.getCode(Builtins.SCANTOFIRST), 
257                                                carryCall, 
258                                                currentCarry);
259                                this.currentCarry += 1;
260                        }                                                                               
261       
262        //          elif is_BuiltIn_Call(callnode, 'Advance32', 1):     
263        //            #CARRYSET
264        //            rtn = self.carryvar.id + "." + "BitBlock_advance_n_<32>"
265        //            c = mkCall(rtn, callnode.args + adv_n_args)
266        //            self.current_adv_n += 1
267        //            return c
268                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCE32.pabloName(), Builtins.ADVANCE32.argCount())) {
269                                //replaceFuncCallNode(node, CarryQ.CarryQ_PACKAGE_NAME, BuiltinOperations.ADVANCE32.cPPCode(), carryCall, currentAdvN);
270                                // TODO ==> verify advNCall
271                                replaceFuncCallNode(node, 
272                                                CarrySet.CarryQ_IDENTIFIER, 
273                                                builtins2Lang.getCode(Builtins.ADVANCE32), 
274                                                advNCall, 
275                                                currentAdvN);
276                                this.currentAdvN += 1;
277                        }                       
278                       
279        //          if is_BuiltIn_Call(callnode, 'Advance', 2):         
280        //            #CARRYSET
281        //            rtn = self.carryvar.id + "." + "BitBlock_advance_n_<%i>" % callnode.args[1].n
282        //            c = mkCall(rtn, [callnode.args[0]] + adv_n_args)
283        //            self.current_adv_n += 1
284        //            return c         
285                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCEN.pabloName(), Builtins.ADVANCEN.argCount())) {
286                                //replaceFuncCallNode(node, CarryQ.CarryQ_PACKAGE_NAME, BuiltinOperations.ADVANCEN.cPPCode(), carryCall, currentAdvN);                                 
287                                // TODO - verify advNCall is correct
288                                replaceFuncCallNode(node, 
289                                                CarrySet.CarryQ_IDENTIFIER, 
290                                                builtins2Lang.getCode(Builtins.ADVANCE32), 
291                                                advNCall, 
292                                                currentAdvN);           
293                                this.currentAdvN += 1;                 
294                        }                                       
295               
296//                      Deprecated - New bitblock iterators replace StreamScan.
297//                     
298//              elif is_BuiltIn_Call(callnode, 'StreamScan', 2):
299//                      rtn = "StreamScan"           
300//                      c = mkCall(rtn, [ast.Name('(ScanBlock *) &' + callnode.args[0].id, ast.Load()),
301//                                                 ast.Name('sizeof(BitBlock)/sizeof(ScanBlock)', ast.Load()),
302//                                                 ast.Name(callnode.args[1].id, ast.Load())])
303//              return c                                       
304//
305//                      else if (Builtins.isCall(node, Builtins.BUILTIN_PACKAGE_NAME, NoCarry.STREAMSCAN.pabloName(), NoCarry.STREAMSCAN.argCount())) {
306//                              replacementNode = Generators.makeFuncCallNode(NoCarry.STREAMSCAN.cPPCode(), node.getToken());
307//                             
308//                              ASTNode arg0 = Generators.makeIdentifierNode("(ScanBlock *) &" + Accessors.identifierLexeme(Accessors.FuncCallArg(node, 0)), node.getToken());
309//                              ASTNode arg1 = Generators.makeIdentifierNode("sizeof(BitBlock)/sizeof(ScanBlock)", node.getToken());
310//                              ASTNode arg2 = Accessors.FuncCallArg(node, 1);
311//                             
312//                              replacementNode.appendChild(arg0);
313//                              replacementNode.appendChild(arg1);
314//                              replacementNode.appendChild(arg2);
315//                      }
316                       
317//                  else:
318//                    #dump_Call(callnode)
319//                    return callnode
320                        else {
321                                // do nothing // TODO - Dump: allow Func calls to pass through the compiler.
322                        }
323                       
324                }
325                                       
326                // Helpers             
327                private void replaceFuncCallNode(FuncCallNode node, String targetPackage, String targetName,
328                                ASTNode call, IntegerConstantNode carry) {
329                        FuncCallNode replacementNode;
330
331                        List<ASTNode> args = new ArrayList<ASTNode>();
332                                               
333                        for(ASTNode arg : Accessors.funcCallArgsListNode(node).getChildren()) {
334                                args.add(arg);
335                        }       
336                        args.add(call);
337                        args.add(carry);
338                       
339                        replacementNode = Generators.makeFuncCallNode(
340                                        new String [] {targetPackage, targetName}, 
341                                        node.getToken(),
342                                        args);
343                       
344                        node.updateSelf(replacementNode);
345                }
346        }
347}
348
349//class CarryIntro(ast.NodeXFormer):
350
351//        def generic_xfrm(self, node):
352//          self.current_carry = 0
353//          self.current_adv_n = 0
354//          carry_count = CarryCounter().count(node)
355//          adv_n_count = adv_nCounter().count(node)
356//          if carry_count == 0 and adv_n_count == 0: return node
357//          self.generic_visit(node)
358//          return node
359
360//def visit_If(self, ifNode):
361//carry_base = self.current_carry
362//carries = CarryCounter().count(ifNode)
363//assert adv_nCounter().count(ifNode) == 0, "Advance(x,n) within if: illegal\n"
364//self.generic_visit(ifNode)
365//if carries == 0 or self.carryin == "": return ifNode
366//#CARRYSET
367//carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
368//new_test = ast.BoolOp(ast.Or(), [ifNode.test, mkCall(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_arglist)])
369//new_else_part = ifNode.orelse + [mkCallStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), carry_arglist)]
370//return ast.If(new_test, ifNode.body, new_else_part)
371
372//        def visit_While(self, whileNode):
373//          if self.carryout == '':
374//            whileNode.test.args[0] = mkCall("simd_and", [whileNode.test.args[0], ast.Name('EOF_mask', ast.Load())])
375//          carry_base = self.current_carry
376//          assert adv_nCounter().count(whileNode) == 0, "Advance(x,n) within while: illegal\n"
377//          carries = CarryCounter().count(whileNode)
378//          #CARRYSET
379//          if carries == 0: return whileNode
380//          carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
381//          local_carryvar = 'sub' + self.carryvar.id
382//          inner_while = CarryIntro(local_carryvar, '', self.carryout).generic_xfrm(copy.deepcopy(whileNode))
383//          self.generic_visit(whileNode)
384//          local_carry_decl = mkCallStmt('LocalCarryDeclare', [ast.Name(local_carryvar, ast.Load()), ast.Num(carries)])
385//          inner_while.body.insert(0, local_carry_decl)
386//          final_combine = mkCallStmt(ast.Attribute(self.carryvar, 'CarryCombine', ast.Load()), [ast.Attribute(ast.Name(local_carryvar, ast.Load()), 'cq', ast.Load()),ast.Num(carry_base), ast.Num(carries)])
387//          inner_while.body.append(final_combine)
388//          #CARRYSET
389//          if self.carryin == '': new_test = whileNode.test
390//          else: new_test = ast.BoolOp(ast.Or(), [whileNode.test, mkCall(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_arglist)])
391//          else_part = [mkCallStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), carry_arglist)]   
392//          return ast.If(new_test, whileNode.body + [inner_while], else_part)
Note: See TracBrowser for help on using the repository browser.