SortedSet <int> finalRewrite(FunctionTranslation translation, bool scalar) { SortedSet <int> ret = new SortedSet <int>(); for (var node = translation.List.First; node != null; node = node.Next) { Assembly ins = node.Value; if (ins.OPCode != "") { // if (ins.SDef.Overlaps(ins.SOut) || ins.VDef.Overlaps(ins.VOut)) // { for (int i = 0; i < ins.Operands.Count; i++) { string op = ins.Operands[i]; if (op[0] == '.') { if ((op[0..2] == ".S" && scalar) || (op[0..2] == ".V" && !scalar))
void rewrite(FunctionTranslation translation, bool scalar) { // throw new Exception("sble"); Dictionary <int, int> offsets = new Dictionary <int, int>(); foreach (var item in spilledNodes) { offsets[item] = translation.function.StackSize; translation.function.StackSize += scalar ? 4 : 16; } for (var node = translation.List.First; node != null; node = node.Next) { Assembly ins = node.Value; var thisNode = node; if (scalar) { HashSet <int> defs = new HashSet <int>(); HashSet <int> uses = new HashSet <int>(); foreach (var item in ins.SDef) { if (ins.SDef.Overlaps(ins.SOut)) // if define is used { defs.Add(graph.Map[item]); } } foreach (var item in ins.SUse) { uses.Add(graph.Map[item]); } if (spilledNodes.Overlaps(defs)) // Trace defines physical register, should not be spilled { defs.IntersectWith(spilledNodes); var i = getFirstInSet(defs); if (defs.Count > 1) { throw new Exception("fv<k"); } var tempVar = ".S" + Statement.VariableCounter; ins.changeDef(tempVar); tempNodes.Add(tempVar); translation.List.AddAfter(thisNode, new Assembly("s_store_4byte", new List <string> { tempVar, "RS28", offsets[i].ToString() })); node = node.Next; } uses.IntersectWith(spilledNodes); foreach (var item in uses) { var tempVar = ".S" + Statement.VariableCounter; ins.changeUse(graph.ReverseMap[item], tempVar); tempNodes.Add(tempVar); translation.List.AddBefore(thisNode, new Assembly("s_load_4byte", new List <string> { tempVar, "RS28", offsets[item].ToString() })); } } else { HashSet <int> defs = new HashSet <int>(); HashSet <int> uses = new HashSet <int>(); foreach (var item in ins.VDef) { if (ins.VDef.Overlaps(ins.VOut)) // if define is used { defs.Add(graph.Map[item]); } } foreach (var item in ins.VUse) { uses.Add(graph.Map[item]); } if (spilledNodes.Overlaps(defs)) { defs.IntersectWith(spilledNodes); var i = getFirstInSet(defs); if (defs.Count > 1) { throw new Exception("fv<k"); } var tempVar = ".V" + Statement.VariableCounter; ins.changeDef(tempVar); tempNodes.Add(tempVar); translation.List.AddAfter(thisNode, new Assembly("v_store_16byte", new List <string> { tempVar, "RS28", offsets[i].ToString() })); node = node.Next; } uses.IntersectWith(spilledNodes); foreach (var item in uses) { var tempVar = ".V" + Statement.VariableCounter; ins.changeUse(graph.ReverseMap[item], tempVar); tempNodes.Add(tempVar); translation.List.AddBefore(thisNode, new Assembly("v_load_16byte", new List <string> { tempVar, "RS28", offsets[item].ToString() })); } } } }