protected void Inline(InstructionNode callSiteNode, BasicBlocks blocks) { var mapBlocks = new Dictionary <BasicBlock, BasicBlock>(blocks.Count); var map = new Dictionary <Operand, Operand>(); var nextBlock = Split(callSiteNode); // create basic blocks foreach (var block in blocks) { var newBlock = CreateNewBlock(); mapBlocks.Add(block, newBlock); } // copy instructions foreach (var block in blocks) { var newBlock = mapBlocks[block]; for (var node = block.AfterFirst; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) { continue; } if (node.Instruction == IRInstruction.Prologue) { continue; } if (node.Instruction == IRInstruction.Epilogue) { newBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Jmp, nextBlock)); continue; } if (node.Instruction == IRInstruction.SetReturn32 || node.Instruction == IRInstruction.SetReturn64 || node.Instruction == IRInstruction.SetReturnR4 || node.Instruction == IRInstruction.SetReturnR8 || node.Instruction == IRInstruction.SetReturnCompound) { if (callSiteNode.Result != null) { var newOperand = Map(node.Operand1, map, callSiteNode); BaseInstruction moveInstruction = null; if (node.Instruction == IRInstruction.SetReturn32) { moveInstruction = IRInstruction.Move32; } else if (node.Instruction == IRInstruction.SetReturn64) { moveInstruction = IRInstruction.Move64; } else if (node.Instruction == IRInstruction.SetReturnR4) { moveInstruction = IRInstruction.MoveR4; } else if (node.Instruction == IRInstruction.SetReturnR8) { moveInstruction = IRInstruction.MoveR8; } else if (node.Instruction == IRInstruction.SetReturnCompound) { moveInstruction = IRInstruction.MoveCompound; } Debug.Assert(moveInstruction != null); var moveNode = new InstructionNode(moveInstruction, callSiteNode.Result, newOperand); newBlock.BeforeLast.Insert(moveNode); } continue; } var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount) { ConditionCode = node.ConditionCode, Label = callSiteNode.Label }; if (node.BranchTargets != null) { // copy targets foreach (var target in node.BranchTargets) { newNode.AddBranchTarget(mapBlocks[target]); } } // copy results for (int i = 0; i < node.ResultCount; i++) { var op = node.GetResult(i); var newOp = Map(op, map, callSiteNode); newNode.SetResult(i, newOp); } // copy operands for (int i = 0; i < node.OperandCount; i++) { var op = node.GetOperand(i); var newOp = Map(op, map, callSiteNode); newNode.SetOperand(i, newOp); } // copy other if (node.MosaType != null) { newNode.MosaType = node.MosaType; } if (node.MosaField != null) { newNode.MosaField = node.MosaField; } UpdateParameterInstructions(newNode); newBlock.BeforeLast.Insert(newNode); } } var prologue = mapBlocks[blocks.PrologueBlock]; var callSiteOperands = callSiteNode.GetOperands(); if (callSiteOperands.Count > 1) { var context = new Context(prologue); for (int i = 1; i < callSiteOperands.Count; i++) { var operand = callSiteOperands[i]; if (!operand.IsVirtualRegister || operand.Low == null) { continue; } context.AppendInstruction(IRInstruction.GetLow64, operand.Low, operand); context.AppendInstruction(IRInstruction.GetHigh64, operand.High, operand); } } callSiteNode.SetInstruction(IRInstruction.Jmp, prologue); }
protected BasicBlocks CopyInstructions() { var newBasicBlocks = new BasicBlocks(); var mapBlocks = new Dictionary <BasicBlock, BasicBlock>(BasicBlocks.Count); var map = new Dictionary <Operand, Operand>(); foreach (var block in BasicBlocks) { var newBlock = newBasicBlocks.CreateBlock(block.Label); mapBlocks.Add(block, newBlock); } var newPrologueBlock = newBasicBlocks.GetByLabel(BasicBlock.PrologueLabel); foreach (var operand in MethodCompiler.Parameters) { if (operand.Definitions.Count > 0) { var newOp = Map(operand, map); var newOperand = Operand.CreateVirtualRegister(operand.Type, -operand.Index); var moveInstruction = StoreOnStack(newOperand.Type) ? IRInstruction.MoveCompound : GetMoveInstruction(newOperand.Type); var moveNode = new InstructionNode(moveInstruction, newOperand, newOp); newPrologueBlock.BeforeLast.Insert(moveNode); // redirect map from parameter to virtual register going forward map.Remove(operand); map.Add(operand, newOperand); } } foreach (var block in BasicBlocks) { var newBlock = newBasicBlocks.GetByLabel(block.Label); for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) { continue; } var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount); newNode.Size = node.Size; newNode.ConditionCode = node.ConditionCode; if (node.BranchTargets != null) { // copy targets foreach (var target in node.BranchTargets) { newNode.AddBranchTarget(mapBlocks[target]); } } // copy results for (int i = 0; i < node.ResultCount; i++) { var op = node.GetResult(i); var newOp = Map(op, map); newNode.SetResult(i, newOp); } // copy operands for (int i = 0; i < node.OperandCount; i++) { var op = node.GetOperand(i); var newOp = Map(op, map); newNode.SetOperand(i, newOp); } // copy other if (node.MosaType != null) { newNode.MosaType = node.MosaType; } if (node.MosaField != null) { newNode.MosaField = node.MosaField; } if (node.InvokeMethod != null) { newNode.InvokeMethod = node.InvokeMethod; } newBlock.BeforeLast.Insert(newNode); } } var trace = CreateTraceLog("InlineMap"); if (trace.Active) { foreach (var entry in map) { trace.Log(entry.Value.ToString() + " from: " + entry.Key.ToString()); } } return(newBasicBlocks); }
protected BasicBlocks CopyInstructions() { var newBasicBlocks = new BasicBlocks(); var mapBlocks = new Dictionary<BasicBlock, BasicBlock>(BasicBlocks.Count); var map = new Dictionary<Operand, Operand>(); foreach (var block in BasicBlocks) { var newBlock = newBasicBlocks.CreateBlock(block.Label); mapBlocks.Add(block, newBlock); } var newPrologueBlock = newBasicBlocks.GetByLabel(BasicBlock.PrologueLabel); foreach (var operand in MethodCompiler.Parameters) { if (operand.Definitions.Count > 0) { var newOp = Map(operand, map); var newOperand = Operand.CreateVirtualRegister(operand.Type, -operand.Index); newPrologueBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Move, newOperand, newOp)); // redirect map from parameter to virtual register going forward map.Remove(operand); map.Add(operand, newOperand); } } foreach (var block in BasicBlocks) { var newBlock = newBasicBlocks.GetByLabel(block.Label); for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) continue; var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount); newNode.Size = node.Size; newNode.ConditionCode = node.ConditionCode; if (node.BranchTargets != null) { // copy targets foreach (var target in node.BranchTargets) { newNode.AddBranchTarget(mapBlocks[target]); } } // copy results for (int i = 0; i < node.ResultCount; i++) { var op = node.GetResult(i); var newOp = Map(op, map); newNode.SetResult(i, newOp); } // copy operands for (int i = 0; i < node.OperandCount; i++) { var op = node.GetOperand(i); var newOp = Map(op, map); newNode.SetOperand(i, newOp); } // copy other if (node.MosaType != null) newNode.MosaType = node.MosaType; if (node.MosaField != null) newNode.MosaField = node.MosaField; if (node.InvokeMethod != null) newNode.InvokeMethod = node.InvokeMethod; newBlock.BeforeLast.Insert(newNode); } } var trace = CreateTraceLog("InlineMap"); if (trace.Active) { foreach (var entry in map) { trace.Log(entry.Value.ToString() + " from: " + entry.Key.ToString()); } } return newBasicBlocks; }
protected void Inline(InstructionNode callNode, BasicBlocks blocks) { var mapBlocks = new Dictionary <BasicBlock, BasicBlock>(blocks.Count); var map = new Dictionary <Operand, Operand>(); var nextBlock = Split(callNode); // create basic blocks foreach (var block in blocks) { var newBlock = CreateNewBlock(); mapBlocks.Add(block, newBlock); } // copy instructions foreach (var block in blocks) { var newBlock = mapBlocks[block]; for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) { continue; } if (node.Instruction == IRInstruction.Prologue) { continue; } if (node.Instruction == IRInstruction.Epilogue) { continue; } if (node.Instruction == IRInstruction.Return) { if (callNode.Result != null) { var newOp = Map(node.Operand1, map, callNode); var moveInsturction = GetMoveInstruction(callNode.Result.Type); var moveNode = new InstructionNode(moveInsturction, callNode.Result, newOp); newBlock.BeforeLast.Insert(moveNode); } newBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Jmp, nextBlock)); continue; } var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount); newNode.Size = node.Size; newNode.ConditionCode = node.ConditionCode; if (node.BranchTargets != null) { // copy targets foreach (var target in node.BranchTargets) { newNode.AddBranchTarget(mapBlocks[target]); } } // copy results for (int i = 0; i < node.ResultCount; i++) { var op = node.GetResult(i); var newOp = Map(op, map, callNode); newNode.SetResult(i, newOp); } // copy operands for (int i = 0; i < node.OperandCount; i++) { var op = node.GetOperand(i); var newOp = Map(op, map, callNode); newNode.SetOperand(i, newOp); } // copy other if (node.MosaType != null) { newNode.MosaType = node.MosaType; } if (node.MosaField != null) { newNode.MosaField = node.MosaField; } if (node.InvokeMethod != null) { newNode.InvokeMethod = node.InvokeMethod; } UpdateParameterInstructions(newNode); newBlock.BeforeLast.Insert(newNode); } } callNode.SetInstruction(IRInstruction.Jmp, mapBlocks[blocks.PrologueBlock]); }
protected BasicBlocks CopyInstructions() { var newBasicBlocks = new BasicBlocks(); var mapBlocks = new Dictionary <BasicBlock, BasicBlock>(BasicBlocks.Count); var map = new Dictionary <Operand, Operand>(); var staticCalls = new List <MosaMethod>(); foreach (var block in BasicBlocks) { var newBlock = newBasicBlocks.CreateBlock(block.Label); mapBlocks.Add(block, newBlock); } var newPrologueBlock = newBasicBlocks.GetByLabel(BasicBlock.PrologueLabel); foreach (var operand in MethodCompiler.Parameters) { if (operand.Definitions.Count > 0) { var newOp = Map(operand, map); var newOperand = Operand.CreateVirtualRegister(operand.Type, -operand.Index); var moveInstruction = !MosaTypeLayout.CanFitInRegister(newOperand) ? IRInstruction.MoveCompound : GetMoveInstruction(newOperand.Type); var moveNode = new InstructionNode(moveInstruction, newOperand, newOp); newPrologueBlock.BeforeLast.Insert(moveNode); // redirect map from parameter to virtual register going forward map.Remove(operand); map.Add(operand, newOperand); } } foreach (var block in BasicBlocks) { var newBlock = newBasicBlocks.GetByLabel(block.Label); for (var node = block.AfterFirst; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmptyOrNop) { continue; } if (node.Instruction == IRInstruction.CallStatic) { staticCalls.AddIfNew(node.Operand1.Method); } var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount) { ConditionCode = node.ConditionCode, InvokeMethod = node.InvokeMethod, MosaField = node.MosaField, MosaType = node.MosaType, //Label = callSiteNode.Label, }; if (node.BranchTargets != null) { // copy targets foreach (var target in node.BranchTargets) { newNode.AddBranchTarget(mapBlocks[target]); } } // copy results for (int i = 0; i < node.ResultCount; i++) { var op = node.GetResult(i); var newOp = Map(op, map); newNode.SetResult(i, newOp); } // copy operands for (int i = 0; i < node.OperandCount; i++) { var op = node.GetOperand(i); var newOp = Map(op, map); newNode.SetOperand(i, newOp); } // copy other if (node.MosaType != null) { newNode.MosaType = node.MosaType; } if (node.MosaField != null) { newNode.MosaField = node.MosaField; } newBlock.BeforeLast.Insert(newNode); } } var trace = CreateTraceLog("InlineMap", 9); if (trace != null) { foreach (var entry in map) { trace.Log($"{entry.Value} from: {entry.Key}"); } } return(newBasicBlocks); }
protected void Inline(InstructionNode callNode, BasicBlocks blocks) { var mapBlocks = new Dictionary<BasicBlock, BasicBlock>(blocks.Count); var map = new Dictionary<Operand, Operand>(); var nextBlock = Split(callNode); // create basic blocks foreach (var block in blocks) { var newBlock = CreateNewBlock(); mapBlocks.Add(block, newBlock); } // copy instructions foreach (var block in blocks) { var newBlock = mapBlocks[block]; for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) continue; if (node.Instruction == IRInstruction.Prologue) continue; if (node.Instruction == IRInstruction.Epilogue) continue; if (node.Instruction == IRInstruction.Return) { if (callNode.Result != null) { var newOp = Map(node.Operand1, map, callNode); newBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Move, callNode.Result, newOp)); } newBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Jmp, nextBlock)); continue; } var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount); newNode.Size = node.Size; newNode.ConditionCode = node.ConditionCode; if (node.BranchTargets != null) { // copy targets foreach (var target in node.BranchTargets) { newNode.AddBranchTarget(mapBlocks[target]); } } // copy results for (int i = 0; i < node.ResultCount; i++) { var op = node.GetResult(i); var newOp = Map(op, map, callNode); newNode.SetResult(i, newOp); } // copy operands for (int i = 0; i < node.OperandCount; i++) { var op = node.GetOperand(i); var newOp = Map(op, map, callNode); newNode.SetOperand(i, newOp); } // copy other if (node.MosaType != null) newNode.MosaType = node.MosaType; if (node.MosaField != null) newNode.MosaField = node.MosaField; if (node.InvokeMethod != null) newNode.InvokeMethod = node.InvokeMethod; newBlock.BeforeLast.Insert(newNode); } } callNode.SetInstruction(IRInstruction.Jmp, mapBlocks[blocks.PrologueBlock]); }