コード例 #1
0
        public static void SolveDoubleJumps(SchemeFunction function)
        {
            bool changed = true;

            var commands = function.Commands;

            while (changed)
            {
                changed = false;

                for (int i = 0; i < commands.Count; ++i)
                {
                    ISchemeCommand cmd = commands[i];
                    if (cmd is CommandJumpBase)
                    {
                        CommandJumpBase jumpCmd = (cmd as CommandJumpBase);
                        int             line    = jumpCmd.Line;
                        if (line < commands.Count && commands[line] is CommandJump)
                        {
                            CommandJump jumpCmd2 = commands[line] as CommandJump;
                            if (jumpCmd.Line != jumpCmd2.Line)
                            {
                                jumpCmd.SetLine(jumpCmd2.Line);
                                changed = true;
                            }
                        }
                    }
                }
            }
        }
コード例 #2
0
            /* Numeric expressions */

            public override object VisitComplex_numeric_expr([NotNull] scheme_langParser.Complex_numeric_exprContext context)
            {
                //Insert ADD/SUB to computation stack and registers to register stack

                //result reg = params.back()
                //param1 = result reg
                //param2 = first free reg (that is not in params)
                //params.push_back(param2)

                int param2 = GetFirstFreeReg();
                int param1 = PopLastParamReg();

                PushParamRegs(param2, param1);

                ISchemeCommand cmd = null;

                if (context.PLUS() != null)
                {
                    cmd = new CommandAdd(GetRegName(param1), GetRegName(param2), GetRegName(param1));
                }
                else if (context.MINUS() != null)
                {
                    cmd = new CommandSubtract(GetRegName(param1), GetRegName(param2), GetRegName(param1));
                }

                currentFunc.AddCommand(cmd, expression_index);

                return(base.VisitComplex_numeric_expr(context));
            }
コード例 #3
0
            public override object VisitCmd_set_attr([NotNull] scheme_langParser.Cmd_set_attrContext context)
            {
                string attr_name = context.attr_name().GetText();
                string attr_type = context.attr_type().GetText();

                int objectReg = 0;

                ISchemeCommand cmd = null;

                if (attr_type == "set")
                {
                    cmd = new CommandSetAttribute(GetRegName(objectReg), attr_name);
                }
                else if (attr_type == "remove")
                {
                    cmd = new CommandRemoveAttribute(GetRegName(objectReg), attr_name);
                }
                else if (attr_type == "forbid")
                {
                    cmd = new CommandForbidAttribute(GetRegName(objectReg), attr_name);
                }

                currentFunc.AddCommand(cmd);

                SetNewExpression(1);

                return(base.VisitCmd_set_attr(context));
            }
コード例 #4
0
        //Returns starting position of each basic block in the given function's code
        private static HashSet <int> GetBlockPositions(SchemeFunction function)
        {
            HashSet <int> positions = new HashSet <int>();

            var commands = function.Commands;

            for (int i = 0; i < commands.Count; ++i)
            {
                ISchemeCommand cmd = commands[i];

                if (cmd is CommandJumpBase)
                {
                    int line = ((CommandJumpBase)cmd).Line;
                    positions.Add(line);
                    positions.Add(i + 1);
                }
            }

            return(positions);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
            public override object VisitComplex_multiplying_expr([NotNull] scheme_langParser.Complex_multiplying_exprContext context)
            {
                int param2 = GetFirstFreeReg();
                int param1 = PopLastParamReg();

                PushParamRegs(param2, param1);

                ISchemeCommand cmd = null;

                if (context.MUL() != null)
                {
                    cmd = new CommandMultiply(GetRegName(param1), GetRegName(param2), GetRegName(param1));
                }
                else if (context.DIV() != null)
                {
                    cmd = new CommandDivide(GetRegName(param1), GetRegName(param2), GetRegName(param1));
                }

                currentFunc.AddCommand(cmd, expression_index);

                return(base.VisitComplex_multiplying_expr(context));
            }
コード例 #7
0
 public void AddCommand(ISchemeCommand command, int commandIndex)
 {
     Commands.Insert(commandIndex, command);
 }
コード例 #8
0
 public void AddCommand(ISchemeCommand command)
 {
     Commands.Add(command);
 }
コード例 #9
0
        public static void SolveDeadCode(SchemeFunction function)
        {
            //For each command C:
            //. If C uses local variable X that is in V, as input, we remove X from V and the corresponding line from L
            //. If C has local variable output X that is in V, then we remove the line of code that is connected to X (found in L)
            //. If C has local variable output, we store the output variable's name in array V, and the code line in L
            //. If we reach new basic block, we clear V and L

            bool changed = true;

            while (changed)
            {
                changed = false;

                HashSet <int> blocks = GetBlockPositions(function);

                var           commands         = function.Commands;
                HashSet <int> removableIndexes = new HashSet <int>();

                Dictionary <string, int> lastSetLines = new Dictionary <string, int>();

                for (int i = 0; i < commands.Count; ++i)
                {
                    if (blocks.Contains(i))
                    {
                        lastSetLines.Clear();
                    }

                    ISchemeCommand cmd = commands[i];

                    if (cmd is CommandCreateVariable)
                    {
                        continue;                               //We don't want to remove CREATE commands
                    }
                    List <string> inputs  = cmd.GetInputs();
                    List <string> outputs = cmd.GetOutputs();

                    if (inputs != null)
                    {
                        foreach (string input in inputs)
                        {
                            if (SchemeExecutor.IsVariable(input))
                            {
                                lastSetLines.Remove(input);
                            }
                        }
                    }

                    if (outputs != null)
                    {
                        foreach (string output in outputs)
                        {
                            if (SchemeExecutor.IsVariable(output))
                            {
                                if (lastSetLines.ContainsKey(output))
                                {
                                    removableIndexes.Add(lastSetLines[output]);
                                }
                                lastSetLines[output] = i;
                            }
                        }
                    }
                }

                if (removableIndexes.Count > 0)
                {
                    changed = true;
                    RemoveCommandsAt(function, removableIndexes);
                }
            }
        }
コード例 #10
0
        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);
        }