Skip to content

Commit d145625

Browse files
committed
feat(interfaces): getSuccessorForOperands in ControlFlowInterface
1 parent 97bf36a commit d145625

1 file changed

Lines changed: 61 additions & 2 deletions

File tree

Veir/Interfaces/ControlFlowInterfaces.lean

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ public import Veir.GlobalOpInfo
55
/-!
66
# ControlFlowInterfaces
77
8-
This file provides support for querying which operands are forwarded to a successor
9-
and mapping those operands to successor block arguments.
8+
This file provides support for querying which operands are forwarded to a successor,
9+
mapping those operands to successor block arguments, and selecting a successor from
10+
known constant operands.
1011
-/
1112

1213
namespace Veir
@@ -29,6 +30,18 @@ instance : GetElem? SuccessorOperands Nat ValuePtr
2930

3031
namespace BranchOpInterface
3132

33+
/-- Return the known value of an operand, or `none` when it is unknown. -/
34+
private def getKnownOperand?
35+
(operands : Array (Option RuntimeValue)) (index : Nat) : Option RuntimeValue := do
36+
let operand ← operands[index]?
37+
operand
38+
39+
/-- Return the true or false successor of a conditional branch. -/
40+
private def getConditionalSuccessor?
41+
(branchOp : OperationPtr) (condition : Bool) (raw : IRContext OpCode) : Option BlockPtr :=
42+
let successors := branchOp.getSuccessors! raw
43+
if condition then successors[0]? else successors[1]?
44+
3245
/--
3346
Return the operands passed to `successorIndex` of a branch operation.
3447
-/
@@ -82,6 +95,52 @@ def getSuccessorOperand?
8295
getSuccessorOperands? branchOp successorIndex raw >>= fun operands =>
8396
operands[blockArgumentIndex]?
8497

98+
/--
99+
Return the successor selected by the known constant operands of a branch operation.
100+
An operand is `none` when its value is unknown. Returns `none` when the operation is
101+
not a supported branch or a single successor cannot be determined.
102+
-/
103+
def getSuccessorForOperands?
104+
(branchOp : OperationPtr) (operands : Array (Option RuntimeValue))
105+
(raw : IRContext OpCode) : Option BlockPtr :=
106+
match branchOp.getOpType! raw with
107+
| .cf .br | .llvm .br | .riscv_cf .branch =>
108+
(branchOp.getSuccessors! raw)[0]?
109+
| .cf .cond_br | .llvm .cond_br => do
110+
let .int _ (.val condition) ← getKnownOperand? operands 0 | none
111+
getConditionalSuccessor? branchOp (condition ≠ 0) raw
112+
| .riscv_cf .beqz => do
113+
let .reg condition ← getKnownOperand? operands 0 | none
114+
getConditionalSuccessor? branchOp (condition.val = 0#64) raw
115+
| .riscv_cf .bnez => do
116+
let .reg condition ← getKnownOperand? operands 0 | none
117+
getConditionalSuccessor? branchOp (condition.val ≠ 0#64) raw
118+
| .riscv_cf .beq => do
119+
let .reg lhs ← getKnownOperand? operands 0 | none
120+
let .reg rhs ← getKnownOperand? operands 1 | none
121+
getConditionalSuccessor? branchOp (lhs = rhs) raw
122+
| .riscv_cf .bne => do
123+
let .reg lhs ← getKnownOperand? operands 0 | none
124+
let .reg rhs ← getKnownOperand? operands 1 | none
125+
getConditionalSuccessor? branchOp (lhs ≠ rhs) raw
126+
| .riscv_cf .blt => do
127+
let .reg lhs ← getKnownOperand? operands 0 | none
128+
let .reg rhs ← getKnownOperand? operands 1 | none
129+
getConditionalSuccessor? branchOp (BitVec.slt lhs.val rhs.val) raw
130+
| .riscv_cf .bge => do
131+
let .reg lhs ← getKnownOperand? operands 0 | none
132+
let .reg rhs ← getKnownOperand? operands 1 | none
133+
getConditionalSuccessor? branchOp (!BitVec.slt lhs.val rhs.val) raw
134+
| .riscv_cf .bltu => do
135+
let .reg lhs ← getKnownOperand? operands 0 | none
136+
let .reg rhs ← getKnownOperand? operands 1 | none
137+
getConditionalSuccessor? branchOp (BitVec.ult lhs.val rhs.val) raw
138+
| .riscv_cf .bgeu => do
139+
let .reg lhs ← getKnownOperand? operands 0 | none
140+
let .reg rhs ← getKnownOperand? operands 1 | none
141+
getConditionalSuccessor? branchOp (!BitVec.ult lhs.val rhs.val) raw
142+
| _ => none
143+
85144
end BranchOpInterface
86145

87146
end

0 commit comments

Comments
 (0)