本文整理汇总了C#中Context.GotoPrevious方法的典型用法代码示例。如果您正苦于以下问题:C# Context.GotoPrevious方法的具体用法?C# Context.GotoPrevious怎么用?C# Context.GotoPrevious使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Context
的用法示例。
在下文中一共展示了Context.GotoPrevious方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Run
// TODO:
// 1. If first branch is to the next basic block,
// then swap branch condition, replace branch target with jump target, and remove jump instruction.
// part of code: ConditionCode = GetOppositeConditionCode(ConditionCode);
// 2. If the basic block contains only a single jump instruction, rewrite all jumps to avoid it.
protected override void Run()
{
var trace = CreateTrace();
for (int f = 0; f < BasicBlocks.Count - 1; f++)
{
var from = BasicBlocks[f];
var next = BasicBlocks[f + 1];
Context context = new Context(InstructionSet, from, from.EndIndex);
context.GotoPrevious();
while (context.IsEmpty)
{
context.GotoPrevious();
}
if (context.Instruction.FlowControl != FlowControl.UnconditionalBranch)
continue;
Debug.Assert(context.Instruction.FlowControl == FlowControl.UnconditionalBranch);
//Debug.Assert(context.BranchTargets.Length == 1);
var target = context.BranchTargets[0];
if (next.Label != target)
continue;
context.Remove();
}
}
示例2: TypeInitializerSchedulerStage
/// <summary>
/// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class.
/// </summary>
public TypeInitializerSchedulerStage()
{
basicBlocks = new BasicBlocks();
// Create the blocks
var prologueBlock = basicBlocks.CreateBlock(BasicBlock.PrologueLabel);
var startBlock = basicBlocks.CreateBlock(BasicBlock.StartLabel);
var epilogueBlock = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel);
// Create the prologue instructions
basicBlocks.AddHeadBlock(prologueBlock);
var prologue = new Context(prologueBlock);
prologue.AppendInstruction(IRInstruction.Prologue);
prologue.Label = -1;
prologue.AppendInstruction(IRInstruction.Jmp, startBlock);
// Create the epilogue instruction
var epilogue = new Context(epilogueBlock);
epilogue.AppendInstruction(IRInstruction.Epilogue);
// create start instructions
start = new Context(startBlock);
start.AppendInstruction(IRInstruction.Jmp, epilogueBlock);
start.GotoPrevious();
}
示例3: UpdateBlockProtectInstructions
private void UpdateBlockProtectInstructions()
{
foreach (var block in BasicBlocks)
{
var context = new Context(InstructionSet, block, block.EndIndex);
while (context.IsEmpty || context.IsBlockEndInstruction)
{
context.GotoPrevious();
}
if (context.Instruction is EndFinallyInstruction)
{
context.ReplaceInstructionOnly(IRInstruction.FinallyEnd);
}
else if (context.Instruction is LeaveInstruction)
{
// Find enclosing finally clause
bool createLink = false;
var entry = FindImmediateExceptionHandler(context);
if (entry != null)
{
if (entry.IsLabelWithinTry(context.Label))
createLink = true;
}
if (createLink)
{
var tryEndNext = context.BranchTargets[0];
var tryEndNextBlock = BasicBlocks.GetByLabel(tryEndNext);
if (entry.HandlerType == ExceptionHandlerType.Finally)
{
var finallyBlock = BasicBlocks.GetByLabel(entry.HandlerStart);
context.SetInstruction(IRInstruction.CallFinally, finallyBlock);
context.AppendInstruction(IRInstruction.TryEnd);
}
else
{
context.SetInstruction(IRInstruction.TryEnd);
}
context.AppendInstruction(IRInstruction.Jmp, tryEndNextBlock);
}
else
{
context.ReplaceInstructionOnly(IRInstruction.ExceptionEnd);
}
}
}
}
示例4: InsertResolvingMoves
public void InsertResolvingMoves(BaseArchitecture architecture, InstructionSet instructionSet)
{
if (moves.Count == 0)
return;
Context context = new Context(instructionSet, Source == Anchor ? Source.EndIndex : Destination.StartIndex);
if (Source == Anchor)
{
context.GotoPrevious();
// Note: This won't work for expanded switch statements... but we can't insert into the end of those blocks anyway
while (context.IsEmpty || context.Instruction.FlowControl == FlowControl.UnconditionalBranch || context.Instruction.FlowControl == FlowControl.ConditionalBranch || context.Instruction.FlowControl == FlowControl.Return)
{
context.GotoPrevious();
}
}
TrySimpleMoves(architecture, context);
TryExchange(architecture, context);
CreateMemoryMoves(architecture, context);
Debug.Assert(moves.Count == 0);
}
示例5: InsertCopyStatement
/// <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(InstructionSet, predecessor, predecessor.EndIndex);
context.GotoPrevious();
while (context.IsEmpty || context.Instruction is IntegerCompareBranch || context.Instruction is Jmp)
{
context.GotoPrevious();
}
var source = operand.IsSSA ? GetFinalVirtualRegister(operand) : operand;
var destination = result.IsSSA ? GetFinalVirtualRegister(result) : result;
Debug.Assert(!source.IsSSA);
Debug.Assert(!destination.IsSSA);
if (destination != source)
{
context.AppendInstruction(IRInstruction.Move, destination, source);
}
}
示例6: AnalyzeBlock
protected void AnalyzeBlock(BasicBlock block)
{
if (analyzed.Get(block.Sequence))
return;
//Debug.WriteLine(String.Format("Analyzing Block #{0} - Label L_{1:X4}", block.Index, block.Label));
traversed.Set(block.Sequence, true);
// Analysis all child blocks first
foreach (BasicBlock nextBlock in block.NextBlocks)
{
if (!traversed.Get(nextBlock.Sequence))
AnalyzeBlock(nextBlock);
}
//Debug.WriteLine(String.Format("Working Block #{0} - Label L_{1:X4}", block.Index, block.Label));
RegisterBitmap used = new RegisterBitmap();
if (block.NextBlocks.Count == 0)
{
if (block.Label == Int32.MaxValue)
{
used.Set(architecture.StackFrameRegister);
used.Set(architecture.StackPointerRegister);
used.Set(architecture.CallingConvention.GetReturnRegisters(methodCompiler.Method.Signature.ReturnType.Type));
used.Set(architecture.CallingConvention.CalleeSavedRegisters);
}
}
else
{
foreach (BasicBlock nextBlock in block.NextBlocks)
used.Or(top[nextBlock.Sequence]);
}
bottom[block.Sequence] = used;
var ctx = new Context(instructionSet, block);
ctx.GotoLast();
for (; ; ctx.GotoPrevious())
{
if (ctx.Ignore || ctx.Instruction == null)
if (ctx.IsFirstInstruction)
break;
else
continue;
RegisterBitmap inputRegisters = new RegisterBitmap();
RegisterBitmap outputRegisters = new RegisterBitmap();
GetRegisterUsage(ctx, ref inputRegisters, ref outputRegisters);
RegisterBitmap assignment = inputRegisters;
assignment.Xor(outputRegisters);
assignment.Not();
used.And(assignment);
used.Or(inputRegisters);
usage[ctx.Index] = used;
if (ctx.IsFirstInstruction)
break;
}
top[block.Sequence] = used;
analyzed.Set(block.Sequence, true);
}
示例7: CreateOutgoingMoves
/// <summary>
/// Creates the outgoing moves.
/// </summary>
/// <param name="block">The block.</param>
/// <param name="operandStack">The operand stack.</param>
/// <param name="joinStack">The join stack.</param>
private void CreateOutgoingMoves(BasicBlock block, Stack<Operand> operandStack, Stack<Operand> joinStack)
{
var context = new Context(block.Last);
context.GotoPrevious();
while ((context.Instruction.FlowControl == FlowControl.ConditionalBranch || context.Instruction.FlowControl == FlowControl.UnconditionalBranch || context.Instruction.FlowControl == FlowControl.Return) || context.Instruction == IRInstruction.Jmp)
{
context.GotoPrevious();
}
while (operandStack.Count > 0)
{
var operand = operandStack.Pop();
var destination = joinStack.Pop();
context.AppendInstruction(IRInstruction.Move, destination, operand);
}
}
示例8: SplitEdge
private void SplitEdge(BasicBlock a, BasicBlock b)
{
// Create new block z
var z = basicBlocks.CreateBlock();
Context ctx = new Context(instructionSet);
ctx.AppendInstruction(IR.IRInstruction.Jmp, a);
ctx.Label = -1;
z.Index = ctx.Index;
// Unlink blocks
a.NextBlocks.Remove(b);
b.PreviousBlocks.Remove(a);
// Link a to z
a.NextBlocks.Add(z);
z.PreviousBlocks.Add(a);
// Link z to b
b.PreviousBlocks.Add(z);
z.NextBlocks.Add(b);
// Insert jump in z to b
ctx.SetInstruction(IRInstruction.Jmp, b);
// Replace any jump/branch target in block a with z
ctx = new Context(instructionSet, a);
ctx.GotoLast();
// Find branch or jump to b and replace it with z
while (ctx.BranchTargets != null)
{
int[] targets = ctx.BranchTargets;
for (int index = 0; index < targets.Length; index++)
{
if (targets[index] == b.Label)
targets[index] = z.Label;
}
ctx.GotoPrevious();
}
}
示例9: InsertRegisterMoves
private void InsertRegisterMoves()
{
var insertTrace = new CompilerTrace(trace, "InsertRegisterMoves");
// collect edge slot indexes
Dictionary<SlotIndex, ExtendedBlock> blockEdges = new Dictionary<SlotIndex, ExtendedBlock>();
foreach (var block in extendedBlocks)
{
blockEdges.Add(block.Start, block);
blockEdges.Add(block.End, block);
}
foreach (var virtualRegister in virtualRegisters)
{
if (virtualRegister.IsPhysicalRegister)
continue;
if (virtualRegister.LiveIntervals.Count <= 1)
continue;
foreach (var currentInterval in virtualRegister.LiveIntervals)
{
if (blockEdges.ContainsKey(currentInterval.End))
continue;
// List is not sorted, so scan thru each one
foreach (var nextInterval in virtualRegister.LiveIntervals)
{
if (nextInterval.Start == currentInterval.End)
{
// next interval is stack - stores to stack are done elsewhere
if (nextInterval.AssignedPhysicalOperand == null)
break;
// check if source and destination operands of the move are the same
if (nextInterval.AssignedOperand == currentInterval.AssignedOperand ||
nextInterval.AssignedOperand.Register == currentInterval.AssignedOperand.Register)
break;
Context context = new Context(instructionSet, currentInterval.End.Index);
context.GotoPrevious();
while (context.IsEmpty || context.Instruction.FlowControl == FlowControl.UnconditionalBranch || context.Instruction.FlowControl == FlowControl.ConditionalBranch || context.Instruction.FlowControl == FlowControl.Return)
{
context.GotoPrevious();
}
architecture.InsertMoveInstruction(context,
nextInterval.AssignedOperand,
currentInterval.AssignedOperand
);
context.Marked = true;
if (insertTrace.Active)
{
insertTrace.Log("REGISTER: " + virtualRegister.ToString());
insertTrace.Log("POSITION: " + currentInterval.End.ToString());
insertTrace.Log(" FROM: " + currentInterval.AssignedOperand.ToString());
insertTrace.Log(" TO: " + nextInterval.AssignedOperand.ToString());
insertTrace.Log("");
}
break;
}
}
}
}
}
示例10: BuildLiveIntervals
//.........这里部分代码省略.........
var register = virtualRegisters[r];
if (b + 1 != basicBlocks.Count && extendedBlocks[b + 1].LiveIn.Get(r))
{
if (intervalTrace.Active) intervalTrace.Log("Add (LiveOut) " + register.ToString() + " : " + block.Start + " to " + extendedBlocks[b + 1].Start);
if (intervalTrace.Active) intervalTrace.Log(" Before: " + LiveIntervalsToString(register.LiveIntervals));
register.AddLiveInterval(block.Start, extendedBlocks[b + 1].Start);
if (intervalTrace.Active) intervalTrace.Log(" After: " + LiveIntervalsToString(register.LiveIntervals));
}
else
{
if (intervalTrace.Active) intervalTrace.Log("Add (!LiveOut) " + register.ToString() + " : " + block.Interval.Start + " to " + block.Interval.End);
if (intervalTrace.Active) intervalTrace.Log(" Before: " + LiveIntervalsToString(register.LiveIntervals));
register.AddLiveInterval(block.Interval);
if (intervalTrace.Active) intervalTrace.Log(" After: " + LiveIntervalsToString(register.LiveIntervals));
}
}
Context context = new Context(instructionSet, block.BasicBlock, block.BasicBlock.EndIndex);
while (!context.IsBlockStartInstruction)
{
if (!context.IsEmpty)
{
SlotIndex slotIndex = new SlotIndex(context);
OperandVisitor visitor = new OperandVisitor(context);
if (context.Instruction.FlowControl == FlowControl.Call)
{
SlotIndex nextSlotIndex = slotIndex.Next;
for (int s = 0; s < physicalRegisterCount; s++)
{
var register = virtualRegisters[s];
if (intervalTrace.Active) intervalTrace.Log("Add (Call) " + register.ToString() + " : " + slotIndex + " to " + nextSlotIndex);
if (intervalTrace.Active) intervalTrace.Log(" Before: " + LiveIntervalsToString(register.LiveIntervals));
register.AddLiveInterval(slotIndex, nextSlotIndex);
if (intervalTrace.Active) intervalTrace.Log(" After: " + LiveIntervalsToString(register.LiveIntervals));
}
callSlots.Add(slotIndex);
}
foreach (var result in visitor.Output)
{
var register = virtualRegisters[GetIndex(result)];
if (register.IsReserved)
continue;
var first = register.FirstRange;
if (!register.IsPhysicalRegister)
{
register.AddDefPosition(slotIndex);
}
if (first != null)
{
if (intervalTrace.Active) intervalTrace.Log("Replace First " + register.ToString() + " : " + slotIndex + " to " + first.End);
if (intervalTrace.Active) intervalTrace.Log(" Before: " + LiveIntervalsToString(register.LiveIntervals));
register.FirstRange = new LiveInterval(register, slotIndex, first.End);
if (intervalTrace.Active) intervalTrace.Log(" After: " + LiveIntervalsToString(register.LiveIntervals));
}
else
{
// This is necesary to handled a result that is never used!
// Common with instructions which more than one result
if (intervalTrace.Active) intervalTrace.Log("Add (Unused) " + register.ToString() + " : " + slotIndex + " to " + slotIndex.Next);
if (intervalTrace.Active) intervalTrace.Log(" Before: " + LiveIntervalsToString(register.LiveIntervals));
register.AddLiveInterval(slotIndex, slotIndex.Next);
if (intervalTrace.Active) intervalTrace.Log(" After: " + LiveIntervalsToString(register.LiveIntervals));
}
}
foreach (var result in visitor.Input)
{
var register = virtualRegisters[GetIndex(result)];
if (register.IsReserved)
continue;
if (!register.IsPhysicalRegister)
{
register.AddUsePosition(slotIndex);
}
if (intervalTrace.Active) intervalTrace.Log("Add (normal) " + register.ToString() + " : " + block.Start + " to " + slotIndex.Next);
if (intervalTrace.Active) intervalTrace.Log(" Before: " + LiveIntervalsToString(register.LiveIntervals));
register.AddLiveInterval(block.Start, slotIndex.Next);
if (intervalTrace.Active) intervalTrace.Log(" After: " + LiveIntervalsToString(register.LiveIntervals));
}
}
context.GotoPrevious();
}
}
}
示例11: CollectLeaveTargets
private List<Tuple<BasicBlock, BasicBlock>> CollectLeaveTargets()
{
var leaveTargets = new List<Tuple<BasicBlock, BasicBlock>>();
foreach (var block in BasicBlocks)
{
var context = new Context(block.Last);
while (context.IsEmpty || context.IsBlockEndInstruction || context.Instruction == IRInstruction.Flow || context.Instruction == IRInstruction.GotoLeaveTarget)
{
context.GotoPrevious();
}
if (context.Instruction == IRInstruction.SetLeaveTarget)
{
leaveTargets.Add(new Tuple<BasicBlock, BasicBlock>(context.BranchTargets[0], block));
}
}
return leaveTargets;
}
示例12: UpdateBlockProtectInstructions
private void UpdateBlockProtectInstructions()
{
foreach (var block in BasicBlocks)
{
var context = new Context(block.Last);
while (context.IsEmpty || context.IsBlockEndInstruction || context.Instruction == IRInstruction.Flow)
{
context.GotoPrevious();
}
if (context.Instruction is EndFinallyInstruction)
{
context.SetInstruction(IRInstruction.FinallyEnd);
var entry = FindFinallyHandler(context.Node);
var list = returns.Get(entry);
if (list == null)
return;
context.AppendInstruction(IRInstruction.FinallyReturn);
foreach (var returnBlock in list)
{
context.AddBranchTarget(returnBlock);
}
}
else if (context.Instruction is LeaveInstruction)
{
// Find enclosing finally clause
bool createLink = false;
var entry = FindImmediateExceptionHandler(context.Node);
if (entry != null)
{
if (entry.IsLabelWithinTry(context.Label))
createLink = true;
}
if (createLink)
{
var tryFinallyBlock = context.BranchTargets[0];
returns.Add(entry, tryFinallyBlock);
context.SetInstruction(IRInstruction.TryEnd);
if (entry.HandlerType == ExceptionHandlerType.Finally)
{
var finallyBlock = BasicBlocks.GetByLabel(entry.HandlerStart);
context.AppendInstruction(IRInstruction.CallFinally, finallyBlock, tryFinallyBlock);
}
else
{
context.AppendInstruction(IRInstruction.Jmp, tryFinallyBlock);
}
//Debug.Assert(context.BasicBlock.NextBlocks.Count <= 1);
}
else
{
context.ReplaceInstructionOnly(IRInstruction.ExceptionEnd);
}
}
}
}
示例13: InsertCopyStatement
/// <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(predecessor.Last);
context.GotoPrevious();
while (context.IsEmpty || context.Instruction is CompareIntegerBranch || context.Instruction is Jmp)
{
context.GotoPrevious();
}
var source = operand.IsSSA ? GetFinalVirtualRegister(operand) : operand;
var destination = result.IsSSA ? GetFinalVirtualRegister(result) : result;
Debug.Assert(!source.IsSSA);
Debug.Assert(!destination.IsSSA);
if (destination != source)
{
if (StoreOnStack(destination.Type))
{
context.AppendInstruction(IRInstruction.CompoundMove, destination, source);
context.MosaType = destination.Type;
}
else
{
var moveInstruction = GetMoveInstruction(destination.Type);
context.AppendInstruction(moveInstruction, destination, source);
}
}
}