feat(mlirlite): 新增 IRBuilder.build_store_at_entry,支持在入口块写入以建立支配关系
M3 owned slife 的所有权影子标志必须在函数入口块置 0:赋值语句可能落在 if/while 里而运行期不执行,那种路径上出口 free 的是未初始化栈垃圾。实现照搬 build_alloca_at_entry:文本插到入口终止符之前,保证支配所有路径。
This commit is contained in:
1 parent
77c8d4f9e4
commit
76deaa27bf
2 files changed
+41
No files matched your search
@@ -266,6 +266,38 @@ novirtual class IRBuilder:
|
||||
self._emit(line)
|
||||
|
||||
|
||||
def build_store_at_entry(self, val: Value*, ptr: Value*,
|
||||
is_volatile: int = 0):
|
||||
"""store [volatile ]<val_ty> <val>, <ptr_ty> <ptr>, emitted in the **entry block**
|
||||
(inserted before the entry terminator) so the write dominates every path.
|
||||
|
||||
Used to zero/null-initialize a local slot at function entry: a slot that is not
|
||||
assigned on some path must still hold a safe value, e.g. the M3 owned-slife guard —
|
||||
the exit-time `free(load slot)` must be `free(NULL)` (a no-op) instead of freeing
|
||||
uninitialized stack garbage. Mirrors build_alloca_at_entry's insertion strategy.
|
||||
"""
|
||||
if self is None or val is None or ptr is None: return
|
||||
pool: memhub.MemBuddy* = self.Pool
|
||||
func: Function* = self.Func
|
||||
if func is None or func.Blocks is None:
|
||||
self.build_store(val, ptr, is_volatile)
|
||||
return
|
||||
blocks: GSList[BasicBlock]* = func.Blocks
|
||||
entry_blk: BasicBlock* = blocks.Head
|
||||
if entry_blk is None:
|
||||
self.build_store(val, ptr, is_volatile)
|
||||
return
|
||||
val_ty_s: str = self._type_str(val.Ty)
|
||||
ptr_ty_s: str = self._type_str(ptr.Ty)
|
||||
line: str = pool.alloc(_LINE_CAP)
|
||||
if line is None: return
|
||||
if is_volatile != 0:
|
||||
viperlib.snprintf(line, _LINE_CAP, "store volatile %s %s, %s %s", val_ty_s, val.Name, ptr_ty_s, ptr.Name)
|
||||
else:
|
||||
viperlib.snprintf(line, _LINE_CAP, "store %s %s, %s %s", val_ty_s, val.Name, ptr_ty_s, ptr.Name)
|
||||
block_insert_text_before_terminator(pool, entry_blk, line)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Binary operation instructions
|
||||
# ============================================================
|
||||
@@ -1298,6 +1330,14 @@ def build_store(builder: IRBuilder*, val: Value*, ptr: Value*,
|
||||
builder.build_store(val, ptr, is_volatile)
|
||||
|
||||
|
||||
def build_store_at_entry(builder: IRBuilder*, val: Value*, ptr: Value*,
|
||||
is_volatile: int = 0):
|
||||
"""store [volatile ]<val_ty> <val>, <ptr_ty> <ptr> emitted in the entry block
|
||||
(before the entry terminator) so the write dominates every path; used for
|
||||
null-initializing a local slot at function entry (M3 owned-slife guard)."""
|
||||
builder.build_store_at_entry(val, ptr, is_volatile)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Binary operation instructions
|
||||
# ============================================================
|
||||
|
||||
@@ -62,6 +62,7 @@ from .__builder import (
|
||||
builder_cur_block_is_terminated,
|
||||
builder_set_debug_location, builder_clear_debug_location,
|
||||
build_alloca, build_alloca_aligned, build_alloca_at_entry, build_load, build_store,
|
||||
build_store_at_entry,
|
||||
build_add, build_sub, build_mul, build_sdiv, build_udiv, build_srem, build_urem,
|
||||
build_and, build_or, build_xor, build_shl, build_lshr, build_ashr,
|
||||
build_fadd, build_fsub, build_fmul, build_fdiv, build_frem, build_fneg,
|
||||
|
||||
Reference in new issue
Block a user