/// <summary cref="IBackendCodeGenerator.GenerateCode(UnconditionalBranch)"/> public void GenerateCode(UnconditionalBranch branch) { using var command = BeginCommand(PTXInstructions.BranchOperation); var targetLabel = blockLookup[branch.Target]; command.AppendLabel(targetLabel); }
// 10: brfalse 14 // 11: ldstr "pos" // 12: call System.Void System.Console::WriteLine(System.String) // 13: br 16 // // 14: ldstr "pos" // 15: call System.Void System.Console::WriteLine(System.String) // 16: ret public void VisitBranch(ConditionalBranch conditional) { if (m_offset < 0) { // If it's a forward conditional branch, if (conditional.Target.Index > conditional.Index) { // and the not-taken case ends with a forward unconditional branch, UnconditionalBranch unconditional = m_info.Instructions[conditional.Target.Index - 1] as UnconditionalBranch; if (unconditional != null && unconditional.Target.Index > unconditional.Index) { // then we have a contruct that resembles an if statement so we'll // compare the code in the two branches. int num1 = unconditional.Index - conditional.Index - 1; int num2 = unconditional.Target.Index - conditional.Target.Index; Log.DebugLine(this, "not taken at {0:X2} has {1} instructions, taken has {2} instructions", conditional.Untyped.Offset, num1, num2); if (num1 == num2 && conditional.Target.Index + num2 <= m_info.Instructions.Length) { if (DoMatches(conditional.Index + 1, conditional.Target.Index, num1)) { Log.DebugLine(this, "matches"); m_offset = conditional.Untyped.Offset; } } } } } }
/// <summary cref="IValueVisitor.Visit(UnconditionalBranch)"/> public void Visit(UnconditionalBranch branch) { using (var command = BeginCommand(PTXInstructions.BranchOperation)) { var targetLabel = blockLookup[branch.Target]; command.AppendLabel(targetLabel); } }
//////////////////////////////////////////////////////////////////////////// public override Statement visit(ConditionalBranch s) { ControlStatement result = s; // var ne = si.fae.visit(this); ProgramVariable oc = s.condition; ProgramVariable nc = s.condition; EqualityDatabase.Representative rep = database.tryGetRepresentative(s.condition); if (rep != null) { Expression ne = rep.expression; if (ne is LiteralExpression) { if (((ne as LiteralExpression).value as BooleanValue).value) { result = new UnconditionalBranch(s.trueBranch.source, s.trueBranch.target); } else { result = new UnconditionalBranch(s.falseBranch.source, s.falseBranch.target); } nc = null; } else { if (ne is ProgramVariableExpression) { s.condition = (ne as ProgramVariableExpression).programVariable; nc = s.condition; } else { nc = (EqualityDatabase.getCompactNegationIfBoolean(ne) as ProgramVariableExpression). programVariable; result = new ConditionalBranch( database.statementId.basicBlock, nc, s.falseBranch.target, s.trueBranch.target ); } } } if (nc != null && !database.conditionVariableIndices.ContainsKey(nc.name)) { database.addConditionVariable(nc); } return(result); }
/// <summary cref="IBackendCodeGenerator.GenerateCode(UnconditionalBranch)"/> public void GenerateCode(UnconditionalBranch branch) { if (Schedule.IsImplicitSuccessor(branch.BasicBlock, branch.Target)) { return; } using var command = BeginCommand(PTXInstructions.BranchOperation); var targetLabel = blockLookup[branch.Target]; command.AppendLabel(targetLabel); }
private List <BasicBlock> DoGetDeadBlocks(TypedInstructionCollection instructions, Dictionary <int, BasicBlock> blocks, List <BasicBlock> reachable) { List <BasicBlock> deadBlocks = new List <BasicBlock>(); // If the block isn't the target of a branch and it's preceded by an end // instruction it's dead code. This can happen if a catch block throws. foreach (KeyValuePair <int, BasicBlock> entry in blocks) { BasicBlock b = entry.Value; int i = b.First.Index; if (m_branchTargets.IndexOf(i) < 0) { if (instructions.TryCatchCollection.HandlerStartsAt(i) == null) { if (i > 0 && (instructions[i - 1] is End || instructions[i - 1] is UnconditionalBranch)) { deadBlocks.Add(b); } } } } // If a leave is dead code then its target is dead as well. List <BasicBlock> deaderBlocks = new List <BasicBlock>(); foreach (BasicBlock b in deadBlocks) { if (b.Length > 0) { for (int i = b.First.Index; i <= b.Last.Index; ++i) { if (instructions[i].Untyped.OpCode.Code == Code.Leave || instructions[i].Untyped.OpCode.Code == Code.Leave_S) { UnconditionalBranch branch = (UnconditionalBranch)instructions[i]; if (reachable.IndexOf(blocks[branch.Target.Index]) < 0 && deaderBlocks.IndexOf(blocks[branch.Target.Index]) < 0) { deaderBlocks.Add(blocks[branch.Target.Index]); } } } } } deadBlocks.AddRange(deaderBlocks); return(deadBlocks); }
// 08: switch 26 35 53 44 44 44 // 21: br 53 // 26: ldstr "zero" // 2B: call System.Void System.Console::WriteLine(System.String) // 30: br 53 // 35: ldstr "zero" // 3A: call System.Void System.Console::WriteLine(System.String) // 3F: br 53 // 44: ldstr "zero" // 49: call System.Void System.Console::WriteLine(System.String) // 4E: br 53 // 53: ret public void VisitSwitch(Switch swtch) { if (m_offset < 0) { UnconditionalBranch unconditional = m_info.Instructions[swtch.Index + 1] as UnconditionalBranch; if (unconditional != null && unconditional.Target.Index > unconditional.Index) { TypedInstruction last = unconditional.Target; List <TypedInstruction> cases = new List <TypedInstruction>(); foreach (TypedInstruction ti in swtch.Targets) { if (ti.Index != last.Index) { if (cases.IndexOf(ti) < 0) { cases.Add(ti); } } } cases.Add(last); cases.Sort((lhs, rhs) => lhs.Index.CompareTo(rhs.Index)); for (int i = 0; i < cases.Count - 1 && m_offset < 0; ++i) { TypedInstruction ti1 = cases[i]; int len1 = cases[i + 1].Index - ti1.Index - 1; for (int j = i + 1; j < cases.Count - 1 && m_offset < 0; ++j) { TypedInstruction ti2 = cases[j]; int len2 = cases[j + 1].Index - ti2.Index - 1; if (len1 == len2) { if (DoMatches(ti1.Index, ti2.Index, len1)) { Log.DebugLine(this, "{0:X2} matches {1:X2}", ti1.Untyped.Offset, ti2.Untyped.Offset); m_offset = swtch.Untyped.Offset; } } } } } } }
/// <summary cref="IBackendCodeGenerator.GenerateCode(UnconditionalBranch)"/> public void GenerateCode(UnconditionalBranch branch) { if (Schedule.IsImplicitSuccessor(branch.BasicBlock, branch.Target)) { return; } // Determine the branch operation to be used var branchOperation = Uniforms.IsUniform(branch) ? PTXInstructions.UniformBranchOperation : PTXInstructions.BranchOperation; using var command = BeginCommand(branchOperation); var targetLabel = blockLookup[branch.Target]; command.AppendLabel(targetLabel); }
private int DoFindBranch(int index, int target) { while (index < m_info.Instructions.Length) { UnconditionalBranch ub = m_info.Instructions[index] as UnconditionalBranch; if (ub != null) { return(-1); } Branch branch = m_info.Instructions[index++] as Branch; if (branch != null && branch.Target.Index == target) { Log.DebugLine(this, " found backward branch at {0:X2}", branch.Untyped.Offset); return(branch.Index); } } return(-1); }
public virtual Statement visit(UnconditionalBranch s) { return(s); }
/// <summary cref="IValueVisitor.Visit(UnconditionalBranch)"/> public void Visit(UnconditionalBranch branch) => CodeGenerator.GenerateCode(branch);
/// <summary cref="IValueVisitor.Visit(UnconditionalBranch)"/> public void Visit(UnconditionalBranch branch) { // TODO: implement throw new NotImplementedException(); }
/// <summary cref="IBackendCodeGenerator.GenerateCode(UnconditionalBranch)"/> public void GenerateCode(UnconditionalBranch branch) => GotoStatement(branch.Target);
private void DoWireBlock(TypedInstructionCollection instructions, Dictionary <int, BasicBlock> blocks, BasicBlock block) { var nextBlocks = new List <BasicBlock>(); if (block.First.Index == 0) { DoWireCatches(instructions, nextBlocks, blocks, 0); } do { ConditionalBranch conditional = block.Last as ConditionalBranch; if (conditional != null) { nextBlocks.Add(blocks[conditional.Index + 1]); nextBlocks.Add(blocks[conditional.Target.Index]); DoWireCatches(instructions, nextBlocks, blocks, conditional.Index + 1); DoWireCatches(instructions, nextBlocks, blocks, conditional.Target.Index); break; } UnconditionalBranch unconditional = block.Last as UnconditionalBranch; if (unconditional != null) { nextBlocks.Add(blocks[unconditional.Target.Index]); DoWireCatches(instructions, nextBlocks, blocks, unconditional.Target.Index); if (block.Last.Untyped.OpCode.Code == Code.Leave || block.Last.Untyped.OpCode.Code == Code.Leave_S) { DoAddFinally(instructions, nextBlocks, blocks, block); } break; } Switch swtch = block.Last as Switch; if (swtch != null) { foreach (TypedInstruction t in swtch.Targets) { nextBlocks.Add(blocks[t.Index]); DoWireCatches(instructions, nextBlocks, blocks, t.Index); } nextBlocks.Add(blocks[swtch.Index + 1]); DoWireCatches(instructions, nextBlocks, blocks, swtch.Index + 1); break; } End end = block.Last as End; if (end != null) { DoAddFinally(instructions, nextBlocks, blocks, block); break; } DoWireCatches(instructions, nextBlocks, blocks, block.Last.Index + 1); nextBlocks.Add(blocks[block.Last.Index + 1]); }while (false); block.Next = nextBlocks.ToArray(); Log.DebugLine(this, "Wired block: {0}", block); }
/// <summary cref="IValueVisitor.Visit(UnconditionalBranch)"/> public void Visit(UnconditionalBranch branch) { GotoStatement(branch.Target); }