private void writeIf(IfBlock block) { string cond; if (block.logic == null) { writeStatements(block.source); DJumpCondition jcc = (DJumpCondition)block.source.nodes.last; if (block.invert) { if (jcc.getOperand(0).type == NodeType.Unary && ((DUnary)jcc.getOperand(0)).spop == SPOpcode.not) { cond = buildExpression(jcc.getOperand(0).getOperand(0)); } else if (jcc.getOperand(0).type == NodeType.Load) { cond = "!" + buildExpression(jcc.getOperand(0)); } else { cond = "!(" + buildExpression(jcc.getOperand(0)) + ")"; } } else { cond = buildExpression(jcc.getOperand(0)); } } else { cond = buildLogicChain(block.logic); Debug.Assert(!block.invert); } outputLine("if (" + cond + ")"); outputLine("{"); increaseIndent(); writeBlock(block.trueArm); decreaseIndent(); if (block.falseArm != null && BlockAnalysis.GetEmptyTarget(block.falseArm.source) == null) { outputLine("}"); outputLine("else"); outputLine("{"); increaseIndent(); writeBlock(block.falseArm); decreaseIndent(); } outputLine("}"); if (block.join != null) { writeBlock(block.join); } }
private ControlType findLoopJoinAndBody(NodeBlock header, NodeBlock effectiveHeader, out NodeBlock join, out NodeBlock body, out NodeBlock cond) { //Debug.Assert(effectiveHeader.lir.numSuccessors == 2); LBlock succ1 = effectiveHeader.lir.getSuccessor(0); LBlock succ2 = effectiveHeader.lir.getSuccessor(1); if (succ1.loop != header.lir || succ2.loop != header.lir) { //Debug.Assert(succ1.loop == header.lir || succ2.loop == header.lir); if (succ1.loop != header.lir) { join = graph_[succ1.id]; body = graph_[succ2.id]; } else { join = graph_[succ2.id]; body = graph_[succ1.id]; } cond = header; // If this is a self-loop, it is more correct to decompose it // to a do-while loop. This may not be source accurate in the // case of something like |while (x);| but it catches many more // source-accurate cases. if (header == effectiveHeader && BlockAnalysis.GetEmptyTarget(body) == header) { body = null; return(ControlType.DoWhileLoop); } return(ControlType.WhileLoop); } else { // Neither successor of the header exits the loop, so this is // probably a do-while loop. For now, assume it's simple. //Debug.Assert(header == effectiveHeader); LBlock backedge = header.lir.backedge; if (BlockAnalysis.GetEmptyTarget(graph_[backedge.id]) == header) { // Skip an empty block sitting in between the backedge and // the condition. //Debug.Assert(backedge.numPredecessors == 1); backedge = backedge.getPredecessor(0); } //Debug.Assert(backedge.numSuccessors == 2); succ1 = backedge.getSuccessor(0); succ2 = backedge.getSuccessor(1); body = header; cond = graph_[backedge.id]; if (succ1.loop != header.lir) { join = graph_[succ1.id]; } else { //Debug.Assert(succ2.loop != header.lir); join = graph_[succ2.id]; } return(ControlType.DoWhileLoop); } }