private void visitSignature(DNode call, Signature signature) { for (int i = 0; i < call.numOperands && i < signature.args.Length; i++) { DNode node = call.getOperand(i); Argument arg = i < signature.args.Length ? signature.args[i] : signature.args[signature.args.Length - 1]; TypeUnit tu = TypeUnit.FromArgument(arg); if (tu != null) { node.addType(tu); } } // Peek ahead for constants. if (signature.args.Length > 0 && signature.args[signature.args.Length - 1].type == VariableType.Variadic) { for (int i = signature.args.Length - 1; i < call.numOperands; i++) { DNode node = call.getOperand(i); if (node.type != NodeType.Constant) { continue; } DConstant constNode = (DConstant)node; Variable global = graph_.file.lookupGlobal(constNode.value); if (global != null) { call.replaceOperand(i, new DGlobal(global)); continue; } // Guess a string... call.replaceOperand(i, new DString(graph_.file.stringFromData(constNode.value))); } } }
private void visitSignature(DNode call, Signature signature) { for (int i = 0; i < call.numOperands && i < signature.args.Length; i++) { DNode node = call.getOperand(i); Argument arg = i < signature.args.Length ? signature.args[i] : signature.args[signature.args.Length - 1]; TypeUnit tu = TypeUnit.FromArgument(arg); if (tu != null) node.addType(tu); } // Peek ahead for constants. if (signature.args.Length > 0 && signature.args[signature.args.Length - 1].type == VariableType.Variadic) { for (int i = signature.args.Length - 1; i < call.numOperands; i++) { DNode node = call.getOperand(i); if (node.type != NodeType.Constant) continue; DConstant constNode = (DConstant)node; Variable global = graph_.file.lookupGlobal(constNode.value); if (global != null) { call.replaceOperand(i, new DGlobal(global)); continue; } // Guess a string... call.replaceOperand(i, new DString(graph_.file.stringFromData(constNode.value))); } } }
private static bool CollapseArrayReferences(NodeBlock block) { bool changed = false; for (NodeList.reverse_iterator iter = block.nodes.rbegin(); iter.more(); iter.next()) { DNode node = iter.node; if (node.type == NodeType.Store || node.type == NodeType.Load) { if (node.getOperand(0).type != NodeType.ArrayRef && IsArray(node.getOperand(0).typeSet)) { DConstant index0 = new DConstant(0); DArrayRef aref0 = new DArrayRef(node.getOperand(0), index0, 0); block.nodes.insertBefore(node, index0); block.nodes.insertBefore(node, aref0); node.replaceOperand(0, aref0); continue; } } if (node.type != NodeType.Binary) { continue; } DBinary binary = (DBinary)node; if (binary.spop != SPOpcode.add) { continue; } if (binary.lhs.type == NodeType.LocalRef) { //Debug.Assert(true); } // Check for an array index. DNode abase = GuessArrayBase(binary.lhs, binary.rhs); if (abase == null) { continue; } DNode index = (abase == binary.lhs) ? binary.rhs : binary.lhs; if (!IsReallyLikelyArrayCompute(binary, abase)) { continue; } // Multi-dimensional arrays are indexed like: // x[y] => x + x[y] // // We recognize this and just remove the add, ignoring the // underlying representation of the array. if (index.type == NodeType.Load && index.getOperand(0) == abase) { node.replaceAllUsesWith(index); node.removeFromUseChains(); block.nodes.remove(iter); changed = true; continue; } // Otherwise, create a new array reference. DArrayRef aref = new DArrayRef(abase, index); iter.node.replaceAllUsesWith(aref); iter.node.removeFromUseChains(); block.nodes.remove(iter); block.nodes.insertBefore(iter.node, aref); changed = true; } return(changed); }