Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions UnitTest.lean
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import UnitTest.ParserError
import UnitTest.Parser
import UnitTest.AttrParser
import UnitTest.MlirParser
import UnitTest.IR.Operation
import UnitTest.FP
import UnitTest.Bitblasting.Bitblasting
import UnitTest.DataFlowFramework.Dominance
53 changes: 53 additions & 0 deletions UnitTest/IR/Operation.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Veir.IR.Basic
import Veir.Parser.MlirParser

open Veir
open Veir.Parser

private def parse (s : String) : OperationPtr × IRContext OpCode :=
match WfIRContext.create OpCode with
| none => panic! "failed to create IR context"
| some (ctx, _) =>
match ParserState.fromInput s.toByteArray with
| .error _ => panic! "lex error"
| .ok parser =>
match (parseOp none).run (MlirParserState.fromContext ctx) parser with
| .error _ => panic! "parse error"
| .ok (op, state, _) => (op, state.ctx.raw)

private def flattenOps (top : OperationPtr) (ctx : IRContext OpCode) :
Array OperationPtr := Id.run do
let mut ops := #[]
for region in (top.get! ctx).regions do
let region := region.get! ctx
let mut currentBlock := region.firstBlock
while let some block := currentBlock do
let mut currentOp := (block.get! ctx).firstOp
while let some op := currentOp do
ops := ops.push op
currentOp := (op.get! ctx).next
currentBlock := (block.get! ctx).next
ops

private def parsed := parse r#""builtin.module"() ({
%a = "test.test"() : () -> i32
%b = "test.test"() : () -> i32
%c = "arith.muli"(%a, %b) : (i32, i32) -> i32
}) : () -> ()"#

private def ops := flattenOps parsed.1 parsed.2

#guard ops[0]!.getNumOperands! parsed.2 == 0
#guard (ops[0]!.getOpOperands! parsed.2).size == 0

#guard ops[2]!.getNumOperands! parsed.2 == 2
#guard (ops[2]!.getOpOperands! parsed.2).size == ops[2]!.getNumOperands! parsed.2
#guard (ops[2]!.getOpOperands! parsed.2)[0]! == ops[2]!.getOpOperand 0
#guard (ops[2]!.getOpOperands! parsed.2)[1]! == ops[2]!.getOpOperand 1

#guard (ops[2]!.getOpOperands! parsed.2)[0]!.op == ops[2]!
#guard (ops[2]!.getOpOperands! parsed.2)[0]!.index == 0
#guard (ops[2]!.getOpOperands! parsed.2)[1]!.index == 1

#guard ops[2]!.getOperand! parsed.2 0 == (ops[0]!.getResult 0 : ValuePtr)
#guard ops[2]!.getOperand! parsed.2 1 == (ops[1]!.getResult 0 : ValuePtr)
48 changes: 48 additions & 0 deletions Veir/IR/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,54 @@ theorem getOperands!.getElem_eq_getOperand! {op : OperationPtr} {h} :
(op.getOperands! ctx)[index]'h = op.getOperand! ctx index := by
grind [getOperands!, getOperand!]

def getOpOperands (op : OperationPtr) (ctx : IRContext OpInfo)
(inBounds : op.InBounds ctx := by grind) : Array OpOperandPtr :=
Array.map (fun i => op.getOpOperand i) (Array.range (op.getNumOperands ctx inBounds))

def getOpOperands! (op : OperationPtr) (ctx : IRContext OpInfo) : Array OpOperandPtr :=
Array.map (fun i => op.getOpOperand i) (Array.range (op.getNumOperands! ctx))

@[grind =_, eq_bang ←]
theorem getOpOperands!_eq_getOpOperands {op : OperationPtr} (hin : op.InBounds ctx) :
op.getOpOperands! ctx = op.getOpOperands ctx (by grind) := by
grind [getOpOperands, getOpOperands!]

theorem getOpOperands!.mem_iff_exists_index {op : OperationPtr} :
operand ∈ op.getOpOperands! ctx ↔
∃ index, index < op.getNumOperands! ctx ∧ op.getOpOperand index = operand := by
simp only [getOpOperands!, Array.mem_map, getOpOperand, getNumOperands!]
constructor
· rintro ⟨opr, ⟨hopr, oprValue⟩⟩
have ⟨i, hi, hopr⟩ := Array.getElem_of_mem hopr
exists i
grind
· grind

theorem getOpOperands!.mem_getOpOperand {op : OperationPtr} :
index < op.getNumOperands! ctx →
op.getOpOperand index ∈ op.getOpOperands! ctx := by
grind [getOpOperands!, getOpOperand, getNumOperands!]

@[simp, grind =]
theorem getOpOperands!.size_eq_getNumOperands! {op : OperationPtr} :
(op.getOpOperands! ctx).size = op.getNumOperands! ctx := by
grind [getOpOperands!, getNumOperands!]

@[simp, grind =]
theorem getOpOperands!.getElem!_eq_getOpOperand {op : OperationPtr} :
index < op.getNumOperands! ctx →
(op.getOpOperands! ctx)[index]! = op.getOpOperand index := by
simp only [getOpOperands!, getOpOperand]
grind

@[simp, grind =]
theorem getOpOperands!.getElem_eq_getOpOperand
{op : OperationPtr} {h : index < (op.getOpOperands! ctx).size} :
index < op.getNumOperands! ctx →
(op.getOpOperands! ctx)[index]'h = op.getOpOperand index := by
simp only [getOpOperands!, getOpOperand]
grind

def getOperandTypes (op : OperationPtr) (ctx : IRContext OpInfo)
(inBounds : op.InBounds ctx := by grind) : Array TypeAttr :=
(op.get ctx).operands.map fun opr =>
Expand Down
Loading