Files
hakorune/src/llvm_py/phi_wiring/analysis.py

69 lines
2.5 KiB
Python

from __future__ import annotations
from typing import Dict, List, Any, Tuple
from .common import trace
def collect_produced_stringish(blocks: List[Dict[str, Any]]) -> Dict[int, bool]:
produced_str: Dict[int, bool] = {}
for block_data in blocks:
for inst in block_data.get("instructions", []) or []:
try:
opx = inst.get("op")
dstx = inst.get("dst")
if dstx is None:
continue
is_str = False
if opx == "const":
v = inst.get("value", {}) or {}
t = v.get("type")
if t == "string" or (
isinstance(t, dict)
and t.get("kind") in ("handle", "ptr")
and t.get("box_type") == "StringBox"
):
is_str = True
elif opx in ("binop", "boxcall", "externcall"):
t = inst.get("dst_type")
if (
isinstance(t, dict)
and t.get("kind") == "handle"
and t.get("box_type") == "StringBox"
):
is_str = True
if is_str:
produced_str[int(dstx)] = True
except Exception:
pass
return produced_str
def analyze_incomings(blocks: List[Dict[str, Any]]) -> Dict[int, Dict[int, List[Tuple[int, int]]]]:
"""Return block_phi_incomings: block_id -> { dst_vid -> [(decl_b, v_src), ...] }"""
result: Dict[int, Dict[int, List[Tuple[int, int]]]] = {}
for block_data in blocks:
bid0 = block_data.get("id", 0)
for inst in block_data.get("instructions", []) or []:
if inst.get("op") == "phi":
try:
dst0 = int(inst.get("dst"))
incoming0 = inst.get("incoming", []) or []
except Exception:
dst0 = None
incoming0 = []
if dst0 is None:
continue
try:
pairs = [(int(b), int(v)) for (v, b) in incoming0]
result.setdefault(int(bid0), {})[dst0] = pairs
trace({
"phi": "analyze",
"block": int(bid0),
"dst": dst0,
"incoming": pairs,
})
except Exception:
pass
return result