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); }
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); }
protected bool Equals(ThreeAddressCommand other) { return(string.Equals(Label, other.Label)); }
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); }