Convert element extractions (`__getitem__`, `operator[](idx)`, `q[1:3]`) to corresponding extraction or slice code in the MLIR. This method handles extraction for `veq` types and `stdvec` types.
(self, node)
| 4558 | self.emitFatalError("unhandled constant value", node) |
| 4559 | |
| 4560 | def visit_Subscript(self, node): |
| 4561 | """Convert element extractions (`__getitem__`, `operator[](idx)`, |
| 4562 | `q[1:3]`) to corresponding extraction or slice code in the MLIR. |
| 4563 | |
| 4564 | This method |
| 4565 | handles extraction for `veq` types and `stdvec` types. |
| 4566 | """ |
| 4567 | |
| 4568 | def get_size(val): |
| 4569 | if quake.VeqType.isinstance(val.type): |
| 4570 | return quake.VeqSizeOp(self.getIntegerType(), val).result |
| 4571 | elif cc.StdvecType.isinstance(val.type): |
| 4572 | return cc.StdvecSizeOp(self.getIntegerType(), val).result |
| 4573 | return None |
| 4574 | |
| 4575 | def fix_negative_idx(idx, get_size): |
| 4576 | if (IntegerType.isinstance(idx.type) and |
| 4577 | hasattr(idx.owner, 'opview') and |
| 4578 | isinstance(idx.owner.opview, arith.ConstantOp) and |
| 4579 | 'value' in idx.owner.attributes): |
| 4580 | concreteIdx = IntegerAttr(idx.owner.attributes['value']).value |
| 4581 | if concreteIdx < 0: |
| 4582 | size = get_size() |
| 4583 | if size is not None: |
| 4584 | return arith.AddIOp( |
| 4585 | size, self.getConstantInt(concreteIdx)).result |
| 4586 | return idx |
| 4587 | |
| 4588 | # handle complex slice, VAR[lower:upper] |
| 4589 | if isinstance(node.slice, ast.Slice): |
| 4590 | self.debug_msg(lambda: f'[(Inline) Visit Slice]', node.slice) |
| 4591 | if self.pushPointerValue: |
| 4592 | self.emitFatalError( |
| 4593 | "slicing a list or qvector does not produce a " |
| 4594 | "modifiable value", node) |
| 4595 | |
| 4596 | self.visit(node.value) |
| 4597 | var = self.popValue() |
| 4598 | vectorSize = get_size(var) |
| 4599 | |
| 4600 | lowerVal, upperVal = None, None |
| 4601 | if node.slice.lower is not None: |
| 4602 | self.visit(node.slice.lower) |
| 4603 | lowerVal = fix_negative_idx(self.popValue(), lambda: vectorSize) |
| 4604 | else: |
| 4605 | lowerVal = self.getConstantInt(0) |
| 4606 | if node.slice.upper is not None: |
| 4607 | self.visit(node.slice.upper) |
| 4608 | upperVal = fix_negative_idx(self.popValue(), lambda: vectorSize) |
| 4609 | else: |
| 4610 | if not quake.VeqType.isinstance( |
| 4611 | var.type) and not cc.StdvecType.isinstance(var.type): |
| 4612 | self.emitFatalError( |
| 4613 | f"unhandled upper slice == None, can't handle " |
| 4614 | f"type {var.type}", node) |
| 4615 | else: |
| 4616 | upperVal = vectorSize |
| 4617 |
nothing calls this directly
no test coverage detected