Visit the For node. This node represents the typical Python for statement, `for VAR in ITERABLE`. Currently supported ITERABLEs are the `veq` type, the `stdvec` type, and the result of range() and enumerate().
(self, node)
| 4831 | self.emitFatalError("unhandled subscript", node) |
| 4832 | |
| 4833 | def visit_For(self, node): |
| 4834 | """Visit the For node. |
| 4835 | |
| 4836 | This node represents the typical Python for |
| 4837 | statement, `for VAR in ITERABLE`. Currently supported ITERABLEs are the |
| 4838 | `veq` type, the `stdvec` type, and the result of range() and |
| 4839 | enumerate(). |
| 4840 | """ |
| 4841 | |
| 4842 | getValues = None |
| 4843 | if isinstance(node.iter, ast.Call): |
| 4844 | self.debug_msg(lambda: f'[(Inline) Visit Call]', node.iter) |
| 4845 | |
| 4846 | # We can simplify `for i in range(N)` MLIR code immensely by just |
| 4847 | # building a for loop with N as the upper value, no need to generate |
| 4848 | # an array from the `range` call. |
| 4849 | if node.iter.func.id == 'range': |
| 4850 | iterable = None |
| 4851 | startVal, endVal, stepVal, isDecrementing = self.__processRangeLoopIterationBounds( |
| 4852 | node.iter.args) |
| 4853 | getValues = lambda iterVar: iterVar |
| 4854 | |
| 4855 | # We can simplify `for i,j in enumerate(L)` MLIR code immensely by |
| 4856 | # just building a for loop over the iterable object L and using the |
| 4857 | # index into that iterable and the element. |
| 4858 | elif node.iter.func.id == 'enumerate': |
| 4859 | if len(node.iter.args) != 1: |
| 4860 | self.emitFatalError( |
| 4861 | "invalid number of arguments to enumerate " |
| 4862 | "- expecting 1 argument", node) |
| 4863 | |
| 4864 | self.visit(node.iter.args[0]) |
| 4865 | iterable = self.popValue() |
| 4866 | getValues = lambda iterVar, v: (iterVar, v) |
| 4867 | |
| 4868 | if not getValues: |
| 4869 | self.visit(node.iter) |
| 4870 | iterable = self.popValue() |
| 4871 | |
| 4872 | if iterable: |
| 4873 | |
| 4874 | isDecrementing = False |
| 4875 | startVal = self.getConstantInt(0) |
| 4876 | stepVal = self.getConstantInt(1) |
| 4877 | relevantVals = getValues or (lambda iterVar, v: v) |
| 4878 | |
| 4879 | # we currently handle `veq` and `stdvec` types |
| 4880 | if quake.VeqType.isinstance(iterable.type): |
| 4881 | size = quake.VeqType.getSize(iterable.type) |
| 4882 | if quake.VeqType.hasSpecifiedSize(iterable.type): |
| 4883 | endVal = self.getConstantInt(size) |
| 4884 | else: |
| 4885 | endVal = quake.VeqSizeOp(self.getIntegerType(), |
| 4886 | iterable).result |
| 4887 | |
| 4888 | def loadElement(iterVar): |
| 4889 | val = quake.ExtractRefOp(self.getRefType(), |
| 4890 | iterable, |
no test coverage detected