public static void SolveSimpleValueRegs(SchemeFunction function) { //We iterate commands //If we find a SET(<reg>, <simple value>) command, we // //remove this SET command // //Iterate over the subsequent commands in the base block // //If we find any command with input <reg> we change it to <simple value> // //If we find any command with output <reg> we stop and goto 1. (continuing from the SET command we found) var commands = function.Commands; HashSet <int> removableIndexes = new HashSet <int>(); for (int i = 0; i < commands.Count; ++i) { ISchemeCommand cmd = commands[i]; if (cmd is CommandSetVariable) { CommandSetVariable cmdSet = (CommandSetVariable)cmd; string targetVar = cmdSet.GetVariableName(); string value = cmdSet.GetValue(); if (SchemeExecutor.IsRegister(targetVar)) { removableIndexes.Add(i); for (int i2 = i + 1; i2 < commands.Count; ++i2) { ISchemeCommand cmd2 = commands[i2]; cmd2.ChangeInputs(targetVar, value); if (cmd2 is CommandJumpBase || cmd2.HasOutput(targetVar)) { break; } } } } } RemoveCommandsAt(function, removableIndexes); }
public static void SolveRegisterBuffers(SchemeFunction function) { // if an operation stores its result in a register <reg>, and it is followed by a SET(<var>, <reg>) command // we delete the SET command and set the opperation's output to <var> // we iterate over the following commands and change any <reg> to <var> // we stop if <reg> is set again or we leave the block var commands = function.Commands; HashSet <int> removableIndexes = new HashSet <int>(); for (int i = 0; i < commands.Count; ++i) { ISchemeCommand cmd = commands[i]; var outputs = cmd.GetOutputs(); if (outputs == null) { continue; } // check if any output is a register foreach (var reg in outputs) { if (SchemeExecutor.IsRegister(reg)) { string variable = null; for (int j = i + 1; j < commands.Count; ++j) { ISchemeCommand cmd2 = commands[j]; if (cmd2 is CommandJumpBase) { break; // break if we leave the block } if (cmd2.HasOutput(reg)) { break; // break if the register is set again } if (cmd2 is CommandSetVariable && cmd2.HasInput(reg)) { CommandSetVariable setCmd = (CommandSetVariable)cmd2; variable = setCmd.GetVariableName(); if (SchemeExecutor.IsRegister(variable)) { variable = null; } else { cmd.ChangeOutput(reg, variable); removableIndexes.Add(j); } } if (variable != null && cmd2.HasInput(reg)) { cmd2.ChangeInputs(reg, variable); } } } } } RemoveCommandsAt(function, removableIndexes); }