def replaceZeroWithNullPtr(self): """Replace statements assigning Zero to pointers, with a special NULL_OBJ.""" # Add the special null object. self.allVars[NULL_OBJ_NAME] = NULL_OBJ_TYPE for objName, irObj in self.allObjs.items(): if not isinstance(irObj, obj.Func): continue func: obj.Func = irObj # if here, its a function object if not func.basicBlocks: continue # if no body, then don't process for bb in func.basicBlocks.values(): for i in range(len(bb) - 1): insn = bb[i] if isinstance(insn, instr.AssignI) and\ insn.type.typeCode == types.PTR_TC: rhs = insn.rhs if isinstance(rhs, expr.CastE): arg = rhs.arg if isinstance(arg, expr.LitE): if arg.type.isNumeric() and arg.val == 0: rhs = expr.AddrOfE( expr.VarE(NULL_OBJ_NAME, rhs.loc), rhs.loc) insn.rhs = rhs if isinstance(rhs, expr.LitE): if rhs.type.isNumeric() and rhs.val == 0: rhs = expr.AddrOfE( expr.VarE(NULL_OBJ_NAME, rhs.loc), rhs.loc) insn.rhs = rhs
"v:main:a": types.Int, "v:main:b": types.Int, "v:main:c": types.Int, "v:main:u": types.Ptr(to=types.Int), } # end all_vars dict all_func: Dict[types.FuncNameT, graph.FuncNode] = { "f:main": graph.FuncNode( name="f:main", params=[], returns=types.Int, basic_blocks={ 1: graph.BB([ # 1 is always start/entry BB. (REQUIRED) instr.AssignI(expr.VarE("v:main:a"), expr.LitE(10)), instr.AssignI(expr.VarE("v:main:c"), expr.LitE(20)), instr.AssignI(expr.VarE("v:main:b"), expr.LitE(2)), instr.CondI(expr.VarE("v:main:b")), ]), 2: graph.BB([ instr.AssignI(expr.VarE("v:main:u"), expr.UnaryE(op.AddrOf, expr.VarE("v:main:c"))), ]), 3: graph.BB([ instr.AssignI(expr.VarE("v:main:u"), expr.UnaryE(op.AddrOf, expr.VarE("v:main:a"))), ]), -1:
hooplIr.append(hooplInsn) break # must be only one unconditional edge insnList: str = "" with io.StringIO() as sio: prefix = "" for bbInsnId in hooplBbInsnIds[:-1]: sio.write(prefix) sio.write(bbInsnId) if not prefix: prefix = ", " insnList = sio.getvalue() hooplBb = f"bb{currBbLabel} = Block \"BB{currBbLabel}\" [{insnList}] {hooplBbInsnIds[-1]}" hooplBbs.append(hooplBb) hooplIr.append("") # for separation between insns and bbs for hooplBb in hooplBbs: hooplIr.append(hooplBb) return "\n".join(hooplIr) if __name__ == "__main__": instrs = [ instr.AssignI(expr.VarE("v:main:x"), expr.LitE(10)), instr.CondI(expr.VarE("v:main:x"), "True", "False"), instr.LabelI("True"), instr.LabelI("False"), ] print(Func.genBasicBlocks(instrs))
all_vars: Dict[types.VarNameT, types.ReturnT] = { "v:main:x": types.Int, "v:main:y": types.Int, "v:main:b": types.Int, } # end all_vars dict all_func: Dict[types.FuncNameT, graph.FuncNode] = { "f:main": graph.FuncNode( name= "f:main", params= [], returns= types.Int, basic_blocks= { 1: graph.BB([ # 1 is always start/entry BB. (REQUIRED) instr.AssignI(expr.VarE("v:main:b"), expr.LitE(1)), instr.CondI(expr.VarE("v:main:b")), ]), 2: graph.BB([ instr.AssignI(expr.VarE("v:main:y"), expr.VarE("v:main:x")), ]), 3: graph.BB([ instr.AssignI(expr.VarE("v:main:y"), expr.LitE(20)), ]), -1: graph.BB([ # -1 is end/exit block (REQUIRED, if more than one BB present) instr.UseI(expr.VarE("v:main:y")), ]), }, bb_edges= [ graph.BbEdge(1, 2, graph.FalseEdge), graph.BbEdge(1, 3, graph.TrueEdge),
"v:main:x": types.Int, "v:main:y": types.Int, "v:main:z": types.Int, "v:g": types.Int, } # end all_vars dict all_func: Dict[types.FuncNameT, graph.FuncNode] = { "f:main": graph.FuncNode( name="f:main", params=["v:main:argc", "v:main:argv"], returns=types.Int, basic_blocks={ 1: graph.BB([ # 1 is always start/entry BB. (REQUIRED) instr.AssignI(expr.VarE("v:main:x"), expr.LitE(10)), instr.AssignI(expr.VarE("v:main:y"), expr.LitE(20)), instr.AssignI(expr.VarE("v:main:z"), expr.VarE("v:main:y")), instr.AssignI(expr.VarE("v:g"), expr.VarE("v:main:z")), ]), #if only one BB, its START&END both. #-1: graph.BB(), # -1 is end/exit block (REQUIRED, if more than one BB present) }, bb_edges=[], ), } # end all_func dict. # Always build the universe from a 'program' module. # Initialize the universe with program in this module. universe.build(name, description, all_vars, all_func)