public override Dictionary <string, string> CommandTransferFunction(Dictionary <string, string> input, BasicBlock block, int commandNumber)
        {
            ThreeAddressCommand command = block.Commands[commandNumber];

            if (command.GetType() == typeof(Assignment))
            {
                string     newValue = NAC;
                Expression expr     = (command as Assignment).Value;
                if (expr.GetType() == typeof(Int32Const) || expr.GetType() == typeof(Identifier))
                {
                    newValue = getConstantFromSimpleExpression(input, (expr as SimpleExpression));
                }
                else if (expr.GetType() == typeof(UnaryOperation))
                {
                    UnaryOperation operation = (expr as UnaryOperation);
                    newValue = calculateVal(getConstantFromSimpleExpression(input, operation.Operand), operation.Operation);
                }
                else if (expr.GetType() == typeof(BinaryOperation))
                {
                    BinaryOperation operation = (expr as BinaryOperation);
                    newValue = calculateVal(getConstantFromSimpleExpression(input, operation.Left), getConstantFromSimpleExpression(input, operation.Right), operation.Operation);
                }
                string leftOperand = (command as Assignment).Target.Name;
                input[leftOperand] = newValue;
            }
            return(input);
        }
 public GenKillOneCommand CalculateGenAndKill(BasicBlock block, ThreeAddressCommand command)
 {
     Kill.Clear();
     Gen = null;
     if (command.GetType() == typeof(Assignment))
     {
         Gen = new CommandNumber(block.BlockId, block.Commands.IndexOf(command));
         string target = (command as Assignment).Target.Name;
         foreach (var c in CommandStorage[target])
             if (c.BlockId != block.BlockId && c.CommandId != block.Commands.IndexOf(command))
                 Kill.Add(new CommandNumber(c.BlockId, c.CommandId));
     }
     return new GenKillOneCommand(Gen, Kill);
 }
示例#3
0
        public static BasicBlocksList CreateBasicBlocks(Program program)
        {
            BasicBlocksList            basicBlocks = new BasicBlocksList();
            List <ThreeAddressCommand> commands    = program.Commands;
            Dictionary <string, int>   labels      = new Dictionary <string, int>();
            List <int> firstCommandsOfBlocks       = new List <int>();
            List <int> lastCommandsOfBlocks        = new List <int>();

            firstCommandsOfBlocks.Add(0);
            for (int i = 0; i < commands.Count; ++i)
            {
                ThreeAddressCommand currentCommand = commands[i];
                if (currentCommand.Label != null)
                {
                    labels[currentCommand.Label] = i;
                    if (i > 0)
                    {
                        firstCommandsOfBlocks.Add(i);
                        lastCommandsOfBlocks.Add(i - 1);
                    }
                }
                if (currentCommand is Goto && i < commands.Count - 1)
                {
                    firstCommandsOfBlocks.Add(i + 1);
                    lastCommandsOfBlocks.Add(i);
                }
            }
            lastCommandsOfBlocks.Add(commands.Count - 1);
            firstCommandsOfBlocks = firstCommandsOfBlocks.Distinct().ToList();
            lastCommandsOfBlocks  = lastCommandsOfBlocks.Distinct().ToList();

            int[] BlockByFirstCommand = new int[commands.Count];
            int[] BlockByLastCommand  = new int[commands.Count];
            for (int i = 0; i < firstCommandsOfBlocks.Count; ++i)
            {
                BlockByFirstCommand[firstCommandsOfBlocks[i]] = i;
            }
            for (int i = 0; i < lastCommandsOfBlocks.Count; ++i)
            {
                BlockByLastCommand[lastCommandsOfBlocks[i]] = i;
            }

            List <int>[] PreviousBlocksByBlockID = new List <int> [commands.Count];
            List <int>[] NextBlocksByBlockID     = new List <int> [commands.Count];
            for (int i = 0; i < commands.Count; ++i)
            {
                PreviousBlocksByBlockID[i] = new List <int>();
                NextBlocksByBlockID[i]     = new List <int>();
            }

            foreach (var currentNumOfLastCommand in lastCommandsOfBlocks)
            {
                ThreeAddressCommand currentCommand = commands[currentNumOfLastCommand];
                int numOfCurrentBlock = BlockByLastCommand[currentNumOfLastCommand];
                if ((currentCommand.GetType() != typeof(Goto)) && (currentNumOfLastCommand < commands.Count - 1))
                {
                    int numOfNextBlock = numOfCurrentBlock + 1;
                    NextBlocksByBlockID[numOfCurrentBlock].Add(numOfNextBlock);
                    PreviousBlocksByBlockID[numOfNextBlock].Add(numOfCurrentBlock);
                }
                if (currentCommand is Goto)
                {
                    int numOfNextBlock = BlockByFirstCommand[labels[(currentCommand as Goto).GotoLabel]];
                    NextBlocksByBlockID[numOfCurrentBlock].Add(numOfNextBlock);
                    PreviousBlocksByBlockID[numOfNextBlock].Add(numOfCurrentBlock);
                }
            }

            for (int i = 0; i < firstCommandsOfBlocks.Count; ++i)
            {
                BasicBlock block = new BasicBlock();
                block.Commands = new List <ThreeAddressCommand>(commands.Take(lastCommandsOfBlocks[i] + 1).Skip(firstCommandsOfBlocks[i]).ToList());
                basicBlocks.Blocks.Add(block);
                basicBlocks.BlockByID[block.BlockId] = block;
            }

            for (int i = 0; i < basicBlocks.Count(); ++i)
            {
                for (int j = 0; j < PreviousBlocksByBlockID[i].Count; ++j)
                {
                    PreviousBlocksByBlockID[i][j] = basicBlocks.Blocks[PreviousBlocksByBlockID[i][j]].BlockId;
                }
                for (int j = 0; j < NextBlocksByBlockID[i].Count; ++j)
                {
                    NextBlocksByBlockID[i][j] = basicBlocks.Blocks[NextBlocksByBlockID[i][j]].BlockId;
                }
                basicBlocks.Blocks[i].InputBlocks.AddRange(PreviousBlocksByBlockID[i]);
                basicBlocks.Blocks[i].OutputBlocks.AddRange(NextBlocksByBlockID[i]);
            }

            return(basicBlocks);
        }
示例#4
0
 protected bool Equals(ThreeAddressCommand other)
 {
     return(string.Equals(Label, other.Label));
 }
示例#5
0
        public List <ThreeAddressCommand> transformToThreeAddressCode()
        {
            var res = new List <ThreeAddressCommand>();

            var done  = new HashSet <BasicBlock>();
            var stack = new Stack <BasicBlock>();

            stack.Push(getBlockById(GetMinBlockId()));

            BasicBlock cur = null;

            while (done.Count < this.GetCount())
            {
                cur = stack.Pop();
                done.Add(cur);

                foreach (var c in cur.Commands)
                {
                    res.Add(c);
                }

                switch (cur.OutputBlocks.Count)
                {
                case 0:
                    continue;

                case 1:
                    BasicBlock outBlock = getBlockById(cur.OutputBlocks[0]);
                    if (!done.Contains(outBlock) && !stack.Contains(outBlock))
                    {
                        stack.Push(outBlock);
                    }
                    break;

                case 2:
                    int             lastStatementIndex = cur.Commands.Count - 1;
                    ConditionalGoto lastStatement      = (ConditionalGoto)cur.Commands[lastStatementIndex];

                    BasicBlock outFirst  = getBlockById(cur.OutputBlocks[0]);
                    BasicBlock outSecond = getBlockById(cur.OutputBlocks[1]);

                    string labelFirst  = outFirst.Commands[0].Label;
                    string labelSecond = outSecond.Commands[0].Label;
                    string gotoLabel   = lastStatement.GotoLabel;

                    if (gotoLabel == labelFirst)
                    {
                        BasicBlock t = outFirst;
                        outFirst  = outSecond;
                        outSecond = t;
                    }

                    int firstLastIndex             = outFirst.Commands.Count - 1;
                    ThreeAddressCommand secondLast = outFirst.Commands[firstLastIndex];
                    if ((secondLast is Goto) && !(secondLast is ConditionalGoto))
                    {
                        BasicBlock afterIfStatement = getBlockById(outFirst.OutputBlocks[0]);
                        if (!stack.Contains(afterIfStatement) && !done.Contains(afterIfStatement))
                        {
                            stack.Push(afterIfStatement);
                        }
                    }

                    if (!done.Contains(outSecond) && !stack.Contains(outSecond))
                    {
                        stack.Push(outSecond);
                    }

                    if (!done.Contains(outFirst) && !stack.Contains(outFirst))
                    {
                        stack.Push(outFirst);
                    }
                    break;

                default:
                    throw new Exception("There cannot be more than two output blocks!");
                }
            }

            return(res);
        }