protected override void BlockStart(BasicBlock block) { long current = codeEmitter.CurrentPosition; base.BlockStart(block); simAdapter.SimCPU.SetSymbol(block.ToString() + ":" + MethodCompiler.Method.FullName, (ulong)(sectionAddress + startPosition + current), 0); }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> public SimpleFastDominance(BasicBlocks basicBlocks, BasicBlock entryBlock) { // Blocks in reverse post order topology List<BasicBlock> blocks = BasicBlocks.ReversePostorder(entryBlock); //basicBlocks.GetConnectedBlocksStartingAtHead(entryBlock); CalculateDominance(blocks); CalculateChildren(blocks); CalculateDominanceFrontier(blocks); }
List<BasicBlock> IDominanceProvider.GetChildren(BasicBlock block) { List<BasicBlock> child; if (children.TryGetValue(block, out child)) return child; else return new List<BasicBlock>(); // Empty List }
public IDominanceAnalysis GetDominanceAnalysis(BasicBlock headBlock) { IDominanceAnalysis analysis; if (!blockAnalysis.TryGetValue(headBlock, out analysis)) { analysis = dominanceAnalysisFactory(); analysis.PerformAnalysis(basicBlocks, headBlock); blockAnalysis.Add(headBlock, analysis); } return analysis; }
/// <summary> /// Inserts the copy statement. /// </summary> /// <param name="predecessor">The predecessor.</param> /// <param name="result">The result.</param> /// <param name="operand">The operand.</param> private void InsertCopyStatement(BasicBlock predecessor, Operand result, Operand operand) { var context = new Context(this.instructionSet, predecessor); while (!context.EndOfInstruction && IsBranchInstruction(context)) context.GotoNext(); if (context.Index != -1) context = context.InsertBefore(); var source = operand is SsaOperand ? (operand as SsaOperand).Operand : operand; var destination = result is SsaOperand ? (result as SsaOperand).Operand : result; Debug.Assert(!(source is SsaOperand)); Debug.Assert(!(destination is SsaOperand)); context.SetInstruction(IR.Instruction.MoveInstruction, destination, source); }
private bool FindTarget(BasicBlock block) { foreach (var b in branchInstructions) { if (b.BranchTargets.Contains(block)) return true; } return false; }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="condition">The condition.</param> /// <param name="block">The block.</param> public void SetInstruction(BaseInstruction instruction, ConditionCode condition, BasicBlock block) { Node.SetInstruction(instruction, condition, block); }
/// <summary> /// Collects all local variables assignments into a list. /// </summary> /// <param name="locals">Holds all locals found by the stage.</param> /// <param name="block">The block.</param> private void CollectLocalVariables(List<StackOperand> locals, BasicBlock block) { for (Context ctx = new Context(instructionSet, block); !ctx.EndOfInstruction; ctx.GotoNext()) { // Does this instruction define a new stack variable? foreach (Operand op in ctx.Results) { // The instruction list may not be in SSA form, so we have to check existence again here unfortunately. // FIXME: Allow us to detect the state of blocks LocalVariableOperand lvop = op as LocalVariableOperand; if (lvop != null && !locals.Contains(lvop)) locals.Add(lvop); } } }
/// <summary> /// Initializes a new instance of the <see cref="Context" /> class. /// </summary> /// <param name="block">The block.</param> public Context(BasicBlock block) : this(block.First) { }
/// <summary> /// Appends the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="block1">The block1.</param> /// <param name="block2">The block2.</param> public void AppendInstruction(BaseInstruction instruction, BasicBlock block1, BasicBlock block2) { AppendInstruction(); Node.SetInstruction(instruction, block1, block2); }
/// <summary> /// Empties the block of all instructions. /// </summary> /// <param name="block">The block.</param> protected void EmptyBlockOfAllInstructions(BasicBlock block) { for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next) { node.Empty(); } }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="condition">The condition.</param> /// <param name="block">The block.</param> public void SetInstruction(BaseInstruction instruction, ConditionCode condition, BasicBlock block) { SetInstruction(instruction); ConditionCode = condition; AddBranchTarget(block); }
/// <summary> /// Updates the branch target. /// </summary> /// <param name="index">The index.</param> /// <param name="block">The block.</param> public void UpdateBranchTarget(int index, BasicBlock block) { Node.UpdateBranchTarget(index, block); }
/// <summary> /// Sets the branch target. /// </summary> /// <param name="block">The basic block.</param> public void AddBranchTarget(BasicBlock block) { Node.AddBranchTarget(block); }
protected static void UpdatePhiInstructionTargets(List <BasicBlock> targets, BasicBlock source, BasicBlock newSource) { foreach (var target in targets) { Debug.Assert(target.PreviousBlocks.Count > 0); for (var node = target.First; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmptyOrNop) { continue; } if (node.Instruction != IRInstruction.Phi) { break; } int index = node.PhiBlocks.IndexOf(source); node.PhiBlocks[index] = newSource; } } }
/// <summary> /// Appends the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="result">The result.</param> /// <param name="block">The block.</param> public void AppendInstruction(BaseInstruction instruction, Operand result, BasicBlock block) { AppendInstruction(); Node.SetInstruction(instruction, result, block); }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="condition">The condition.</param> /// <param name="result">The result.</param> /// <param name="operand1">The operand1.</param> /// <param name="operand2">The operand2.</param> /// <param name="block">The block.</param> public void SetInstruction(BaseInstruction instruction, ConditionCode condition, Operand result, Operand operand1, Operand operand2, BasicBlock block) { SetInstruction(instruction, 2, (byte)((result == null) ? 0 : 1)); Result = result; Operand1 = operand1; Operand2 = operand2; ConditionCode = condition; AddBranchTarget(block); }
private ExceptionHandlingClause FindExceptionClause(BasicBlock block) { Context ctx = new Context(instructionSet, block); int label = ctx.Label; foreach (ExceptionHandlingClause clause in methodCompiler.ExceptionClauseHeader.Clauses) { if (clause.IsLabelWithinTry(label)) return clause; //if (clause.IsLabelWithinHandler(label)) // return null; } return null; }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="condition">The condition.</param> /// <param name="result">The result.</param> /// <param name="operand1">The operand1.</param> /// <param name="operand2">The operand2.</param> /// <param name="block">The block.</param> public void SetInstruction(BaseInstruction instruction, ConditionCode condition, Operand result, Operand operand1, Operand operand2, BasicBlock block) { Node.SetInstruction(instruction, condition, result, operand1, operand2, block); }
protected static void UpdatePhiList(BasicBlock removedBlock, BasicBlock[] nextBlocks) { foreach (var next in nextBlocks) { for (var node = next.First; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) continue; if (node.Instruction != IRInstruction.Phi) continue; var sourceBlocks = node.PhiBlocks; int index = sourceBlocks.IndexOf(removedBlock); if (index < 0) continue; sourceBlocks.RemoveAt(index); for (int i = index; index < node.OperandCount - 1; index++) { node.SetOperand(i, node.GetOperand(i + 1)); } node.SetOperand(node.OperandCount - 1, null); node.OperandCount--; } } }
/// <summary> /// Appends the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="condition">The condition.</param> /// <param name="block">The block.</param> public void AppendInstruction(BaseInstruction instruction, ConditionCode condition, BasicBlock block) { AppendInstruction(); Node.SetInstruction(instruction, condition, block); }
public static void UpdatePHIInstructionTargets(List <BasicBlock> targets, BasicBlock source, BasicBlock newSource) { foreach (var target in targets) { UpdatePHIInstructionTarget(target, source, newSource); } }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="result">The result.</param> /// <param name="block">The block.</param> public void SetInstruction(BaseInstruction instruction, Operand result, BasicBlock block) { SetInstruction(instruction, result); AddBranchTarget(block); }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="condition">The condition.</param> /// <param name="block">The block.</param> public InstructionNode(BaseInstruction instruction, ConditionCode condition, BasicBlock block) : this(instruction, condition) { AddBranchTarget(block); }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="block1">The block1.</param> /// <param name="block2">The block2.</param> public InstructionNode(BaseInstruction instruction, BasicBlock block1, BasicBlock block2) : this(instruction) { AddBranchTarget(block1); AddBranchTarget(block2); }
/// <summary> /// Inserts the jump instruction. /// </summary> /// <param name="context">The context.</param> /// <param name="Destination">The destination.</param> public override void InsertJumpInstruction(Context context, BasicBlock destination) { context.AppendInstruction(X86.Jmp, destination); }
protected void RemoveEmptyBlockWithSingleJump(BasicBlock block) { Debug.Assert(block.NextBlocks.Count == 1); BasicBlock target = block.NextBlocks[0]; foreach (var previous in block.PreviousBlocks.ToArray()) { ReplaceBranchTargets(previous, block, target); } EmptyBlockOfAllInstructions(block); Debug.Assert(block.NextBlocks.Count == 0); Debug.Assert(block.PreviousBlocks.Count == 0); }
/// <summary> /// Inserts the jump instruction. /// </summary> /// <param name="context">The context.</param> /// <param name="destination">The destination.</param> public abstract void InsertJumpInstruction(Context context, BasicBlock destination);
/// <summary> /// Inserts the jump instruction. /// </summary> /// <param name="context">The context.</param> /// <param name="Destination">The destination.</param> public override void InsertJumpInstruction(Context context, BasicBlock Destination) { // TODO }
private MosaExceptionHandler FindExceptionClause(BasicBlock block) { Context ctx = new Context(InstructionSet, block); int label = ctx.Label; foreach (var clause in MethodCompiler.Method.ExceptionBlocks) { if (clause.IsLabelWithinTry(label)) return clause; //if (clause.IsLabelWithinHandler(label)) // return null; } return null; }
/// <summary> /// Creates empty blocks. /// </summary> /// <param name="blocks">The Blocks.</param> /// <returns></returns> protected BasicBlock[] CreateNewBlocks(int blocks) { // Allocate the block array var result = new BasicBlock[blocks]; for (int index = 0; index < blocks; index++) { result[index] = CreateNewBlock(); } return result; }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="block1">The block1.</param> /// <param name="block2">The block2.</param> public void SetInstruction(BaseInstruction instruction, BasicBlock block1, BasicBlock block2) { SetInstruction(instruction); AddBranchTarget(block1); AddBranchTarget(block2); }
/// <summary> /// Determines whether [is empty block with single jump] [the specified block]. /// </summary> /// <param name="block">The block.</param> /// <returns> /// <c>true</c> if [is empty block with single jump] [the specified block]; otherwise, <c>false</c>. /// </returns> protected bool IsEmptyBlockWithSingleJump(BasicBlock block) { if (block.NextBlocks.Count != 1) return false; for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) continue; if (node.Instruction == IRInstruction.Nop) continue; if (node.Instruction.FlowControl != FlowControl.UnconditionalBranch) return false; } return true; }
/// <summary> /// Replaces the branch targets. /// </summary> /// <param name="block">The current from block.</param> /// <param name="oldTarget">The current destination block.</param> /// <param name="newTarget">The new target block.</param> protected void ReplaceBranchTargets(BasicBlock block, BasicBlock oldTarget, BasicBlock newTarget) { for (var node = block.Last; !node.IsBlockStartInstruction; node = node.Previous) { if (node.IsEmpty) continue; if (node.BranchTargets != null && node.BranchTargetsCount > 0) { var targets = node.BranchTargets; for (int index = 0; index < targets.Count; index++) { if (targets[index] == oldTarget) { node.UpdateBranchTarget(index, newTarget); } } } } }
/// <summary> /// Creates the context. /// </summary> /// <param name="block">The block.</param> /// <returns></returns> protected Context CreateContext(BasicBlock block) { return new Context(instructionSet, block); }
/// <summary> /// Sets the branch target. /// </summary> /// <param name="block">The basic block.</param> public void AddBranchTarget(BasicBlock block) { Debug.Assert(block != null); if (branchTargets == null) { branchTargets = new List<BasicBlock>(1); } branchTargets.Add(block); if (Block != null) { Block.AddBranchInstruction(this); } }