static IrFunction ParseFunction(MfNode node) { var types = node.Where(x => x.Name == "type").Select(ParseType).ToList(); Debug.Assert(types.Count > 0); return(new IrFunction { Name = node.Value, ReturnType = types[0], ParameterTypes = types.Skip(1).ToArray(), Blocks = node.Where(x => x.Name == "block").Select(ParseBlock).ToArray() }); }
static IrInst ParseInstruction(MfNode node) { switch (node.Value) { case "alloca": return(new AllocaInst { Output = ParseOperand(node[0]), AllocationRank = ParseOperand(node[2]), AllocationType = ParseType(node[1]) }); case "binary": var operands = node.Where(x => x.Name == "operand").ToList(); var flags = BinaryFlags.None; foreach (var elem in node) { if (elem.Name == "flag" && elem.Value == "nsw") { flags |= BinaryFlags.Nsw; } else if (elem.Name == "flag" && elem.Value == "nuw") { flags |= BinaryFlags.Nuw; } } return(new BinaryInst { Op = node[0].Value, Flags = flags, Output = ParseOperand(operands[0]), A = ParseOperand(operands[1]), B = ParseOperand(operands[2]) }); case "bitcast": return(new BitcastInst { Output = ParseOperand(node[0]), Value = ParseOperand(node[1]) }); case "br": return(new BrInst { Target = node[0].Value }); case "br.if": return(new BrIfInst { Condition = ParseOperand(node[0]), If = node[1].Value, Else = node[2].Value }); case "call": return(new CallInst { Output = ParseOperand(node[0]), Target = node[1].Value, Parameters = node.Skip(2).Select(ParseOperand).ToArray() }); case "icmp": return(new IcmpInst { Predicate = node[0].Value, Output = ParseOperand(node[1]), A = ParseOperand(node[2]), B = ParseOperand(node[3]) }); case "load": return(new LoadInst { Output = ParseOperand(node[0]), Pointer = ParseOperand(node[1]) }); case "phi": return(new PhiInst { Output = ParseOperand(node[0]), Incoming = node.Skip(1).Select(x => (x.Name, x.Value)).ToArray() });