public bool IsBranchTarget(ActionBlock block) { if (null == block) { throw new ArgumentNullException("block"); } foreach (ActionBlock p in block.Predecessors) { switch (p.ActionType) { case ActionType.Branch: BranchActionBlock br = (BranchActionBlock)p; if (br.Target == block) { return(true); } break; case ActionType.ConditionalBranch: ConditionalBranchActionBlock cbr = (ConditionalBranchActionBlock)p; if (cbr.Then == block) { return(true); } break; } } return(false); }
void ConnectActionBlocks() { for (int i = 0; i < _blocks.Count; ++i) { ActionBlock block = _blocks [i]; switch (block.ActionType) { case ActionType.Branch: BranchActionBlock br = (BranchActionBlock)block; br.SetTarget(GetBranchTarget(br.SourceInstruction)); break; case ActionType.ConditionalBranch: ConditionalBranchActionBlock cbr = (ConditionalBranchActionBlock)block; cbr.SetTargets(GetBranchTarget(cbr.SourceInstruction), GetBlockAtOrNull(i + 1)); break; case ActionType.Return: break; default: AbstractFallThroughActionBlock ftb = (AbstractFallThroughActionBlock)block; ftb.SetNext(GetBlockAtOrNull(i + 1)); break; } } }
void SimplifyActionBlocks() { int index = 0; while (index < _blocks.Count) { ActionBlock block = _blocks [index]; switch (block.ActionType) { case ActionType.ConditionalBranch: // if condition goto label // return expression // label: return true // | // V // return (condition || expression) // // label: return false // | // V // return (!condition || expression) ConditionalBranchActionBlock cbr = (ConditionalBranchActionBlock)block; if (IsReturnTrueOrFalse(cbr.Then) && IsReturn(cbr.Else) && 1 == cbr.Then.Predecessors.Count && 1 == cbr.Else.Predecessors.Count) { BinaryOperator op = BinaryOperator.LogicalOr; Expression lhs = cbr.Condition; Expression rhs = ((ReturnActionBlock)cbr.Else).Expression; if (((LiteralExpression)((ReturnActionBlock)cbr.Then).Expression).Value.Equals(0)) { op = BinaryOperator.LogicalAnd; _expressionDecompiler.Negate(lhs); lhs = _expressionDecompiler.Pop(); } ActionBlock newBlock = new ReturnActionBlock( block.SourceInstruction, new BinaryExpression(op, lhs, rhs)); _graph.ReplaceAt(index, newBlock); index = 0; continue; } break; } ++index; } }
private ActionBlock OnConditionalBranch(ConditionalBranchActionBlock block) { throw new QueryOptimizationException(); }
void WriteConditionalBranch (ActionFlowGraph afg, ConditionalBranchActionBlock block) { _writer.Write ("if "); WriteExpression (block.Condition); _writer.Write (' '); WriteGoto (afg, block.Then); }