def conditionallyAddPseudoVar( self, funcName: types.FuncNameT, insn: instr.AssignI, prevInsn: instr.AssignI = None, ) -> Optional[instr.InstrIT]: """Modifies rhs to address of a pseudo var with the correct type. Only two instruction forms should be in insn: <ptr_var> = (<type>*) <tmp_var>; // cast insn <ptr_var> = <malloc/calloc>(...); // memory alloc insn """ lhs: expr.VarE = insn.lhs # if isTmpVar(lhs.name): return None rhs = insn.rhs if isinstance(rhs, expr.CastE): if not isTmpVar(rhs.arg.name): return None # if here, assume that the tmp var is assigned a heap location lhsType: types.Ptr = lhs.type pVar = self.genPseudoVar(funcName, rhs.loc, lhsType.getPointeeType(), insn, prevInsn) newInsn = instr.AssignI(lhs, expr.AddrOfE(pVar, loc=rhs.loc)) self.inferInstrType(newInsn) return newInsn elif isinstance(rhs, expr.CallE): # assume it is malloc/calloc (it should be) lhsType: types.Ptr = lhs.type pVar = self.genPseudoVar(funcName, rhs.loc, lhsType.getPointeeType(), insn, prevInsn) newInsn = instr.AssignI(lhs, expr.AddrOfE(pVar, loc=rhs.loc)) self.inferInstrType(newInsn) return newInsn return None
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: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))