private string buildLoadStoreRef(DNode node) { switch (node.type) { case NodeType.TempName: { DTempName temp = (DTempName)node; return(temp.name); } case NodeType.DeclareLocal: { DDeclareLocal local = (DDeclareLocal)node; return(local.var.name); } case NodeType.ArrayRef: return(buildArrayRef((DArrayRef)node)); case NodeType.LocalRef: { DLocalRef lref = (DLocalRef)node; DDeclareLocal local = lref.local; if (local.var.type == VariableType.ArrayReference || local.var.type == VariableType.Array) { return(local.var.name + "[0]"); } if (local.var.type == VariableType.Reference) { return(local.var.name); } throw new Exception("unknown local ref"); } case NodeType.Global: { DGlobal global = (DGlobal)node; if (global.var == null) { return("__unk"); } return(global.var.name); } case NodeType.Load: { DLoad load = (DLoad)node; Debug.Assert(load.from.type == NodeType.DeclareLocal || load.from.type == NodeType.ArrayRef || load.from.type == NodeType.Global); return(buildLoadStoreRef(load.from)); } default: throw new Exception("unknown load"); } }
private void writeTempName(DTempName name) { if (name.getOperand(0) != null) { outputLine("int " + name.name + " = " + buildExpression(name.getOperand(0)) + ";"); } else { outputLine("int " + name.name + ";"); } }
public override void visit(DPhi phi) { // Convert a phi into a move on each incoming edge. Declare the // temporary name in the dominator. NodeBlock idom = graph_[phi.block.lir.idom.id]; DTempName name = new DTempName(graph_.tempName()); idom.prepend(name); for (int i = 0; i < phi.numOperands; i++) { DNode input = phi.getOperand(i); DStore store = new DStore(name, input); NodeBlock pred = graph_[phi.block.lir.getPredecessor(i).id]; pred.prepend(store); } phi.replaceAllUsesWith(name); }
public override void visit(DPhi phi) { // Convert a phi into a move on each incoming edge. Declare the // temporary name in the dominator. var idom = graph_[phi.block.lir.idom.id]; var name = new DTempName(graph_.tempName()); idom.prepend(name); for (var i = 0; i < phi.numOperands; i++) { var input = phi.getOperand(i); var store = new DStore(name, input); var pred = graph_[phi.block.lir.getPredecessor(i).id]; pred.prepend(store); } phi.replaceAllUsesWith(name); }
private string buildExpression(DNode node) { switch (node.type) { case NodeType.Constant: return(buildConstant((DConstant)node)); case NodeType.Boolean: return(buildBoolean((DBoolean)node)); case NodeType.Float: return(buildFloat((DFloat)node)); case NodeType.Character: return(buildCharacter((DCharacter)node)); case NodeType.Function: return(buildFunction((DFunction)node)); case NodeType.Load: return(buildLoad((DLoad)node)); case NodeType.String: return(buildString(((DString)node).value)); case NodeType.LocalRef: return(buildLocalRef((DLocalRef)node)); case NodeType.ArrayRef: return(buildArrayRef((DArrayRef)node)); case NodeType.Unary: return(buildUnary((DUnary)node)); case NodeType.Binary: return(buildBinary((DBinary)node)); case NodeType.SysReq: return(buildSysReq((DSysReq)node)); case NodeType.Call: return(buildCall((DCall)node)); case NodeType.DeclareLocal: { DDeclareLocal local = (DDeclareLocal)node; return(local.var.name); } case NodeType.TempName: { DTempName name = (DTempName)node; return(name.name); } case NodeType.Global: { DGlobal global = (DGlobal)node; return(global.var.name); } case NodeType.InlineArray: { return(buildInlineArray((DInlineArray)node)); } default: throw new Exception("waT"); } }
private void renameBlock(NodeBlock block) { for (NodeList.iterator iter = block.nodes.begin(); iter.more();) { DNode node = iter.node; switch (node.type) { case NodeType.TempName: case NodeType.Jump: case NodeType.JumpCondition: case NodeType.Store: case NodeType.Return: case NodeType.IncDec: case NodeType.DeclareStatic: case NodeType.Switch: { iter.next(); continue; } case NodeType.DeclareLocal: { DDeclareLocal decl = (DDeclareLocal)node; if (decl.var == null) { if (decl.uses.Count <= 1) { // This was probably just a stack temporary. if (decl.uses.Count == 1) { DUse use = decl.uses.First.Value; use.node.replaceOperand(use.index, decl.value); } block.nodes.remove(iter); continue; } DTempName name = new DTempName(graph_.tempName()); node.replaceAllUsesWith(name); name.init(decl.value); block.nodes.replace(iter, name); } iter.next(); continue; } case NodeType.SysReq: case NodeType.Call: { // Calls are statements or expressions, so we can't // remove them if they have no uses. if (node.uses.Count <= 1) { if (node.uses.Count == 1) { block.nodes.remove(iter); } else { iter.next(); } continue; } break; } case NodeType.Constant: { // Constants can be deeply copied. block.nodes.remove(iter); continue; } default: { if (node.uses.Count <= 1) { // This node has one or zero uses, so instead of // renaming it, we remove it from the instruction // stream. This way the source printer will deep- // print it instead of using its 'SSA' name. block.nodes.remove(iter); continue; } break; } } // If we've reached here, the expression has more than one use // and we have to wrap it in some kind of name, lest we // duplicate it in the expression tree which may be illegal. DTempName replacement = new DTempName(graph_.tempName()); node.replaceAllUsesWith(replacement); replacement.init(node); block.nodes.replace(iter, replacement); iter.next(); } }
private void renameBlock(NodeBlock block) { for (NodeList.iterator iter = block.nodes.begin(); iter.more();) { DNode node = iter.node; switch (node.type) { case NodeType.TempName: case NodeType.Jump: case NodeType.JumpCondition: case NodeType.Store: case NodeType.Return: case NodeType.IncDec: case NodeType.DeclareStatic: case NodeType.Switch: { iter.next(); continue; } case NodeType.DeclareLocal: { DDeclareLocal decl = (DDeclareLocal)node; if (decl.var == null) { if (decl.uses.Count <= 1) { // This was probably just a stack temporary. if (decl.uses.Count == 1) { DUse use = decl.uses.First.Value; use.node.replaceOperand(use.index, decl.value); } block.nodes.remove(iter); continue; } DTempName name = new DTempName(graph_.tempName()); node.replaceAllUsesWith(name); name.init(decl.value); block.nodes.replace(iter, name); } iter.next(); continue; } case NodeType.SysReq: case NodeType.Call: { // Calls are statements or expressions, so we can't // remove them if they have no uses. if (node.uses.Count <= 1) { if (node.uses.Count == 1) block.nodes.remove(iter); else iter.next(); continue; } break; } case NodeType.Constant: { // Constants can be deeply copied. block.nodes.remove(iter); continue; } default: { if (node.uses.Count <= 1) { // This node has one or zero uses, so instead of // renaming it, we remove it from the instruction // stream. This way the source printer will deep- // print it instead of using its 'SSA' name. block.nodes.remove(iter); continue; } break; } } // If we've reached here, the expression has more than one use // and we have to wrap it in some kind of name, lest we // duplicate it in the expression tree which may be illegal. DTempName replacement = new DTempName(graph_.tempName()); node.replaceAllUsesWith(replacement); replacement.init(node); block.nodes.replace(iter, replacement); iter.next(); } }
private void writeTempName(DTempName name) { if (name.getOperand(0) != null) outputLine("int " + name.name + " = " + buildExpression(name.getOperand(0)) + ";"); else outputLine("int " + name.name + ";"); }