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 AnalyzeHeapNode(NodeBlock block, DHeap node) { // Easy case: compiler needed a lvalue. if (node.uses.Count == 2) { DUse lastUse = node.uses.Last(); DUse firstUse = node.uses.First(); if ((lastUse.node.type == NodeType.Call || lastUse.node.type == NodeType.SysReq) && firstUse.node.type == NodeType.Store && firstUse.index == 0) { lastUse.node.replaceOperand(lastUse.index, firstUse.node.getOperand(1)); return(true); } if ((lastUse.node.type == NodeType.Call || lastUse.node.type == NodeType.SysReq) && firstUse.node.type == NodeType.MemCopy && firstUse.index == 0) { // heap -> memcpy always reads from DAT + constant DMemCopy memcopy = (DMemCopy)firstUse.node; DConstant cv = (DConstant)memcopy.from; DInlineArray ia = new DInlineArray(cv.value, memcopy.bytes); block.nodes.insertAfter(node, ia); lastUse.node.replaceOperand(lastUse.index, ia); // Give the inline array some type information. Signature signature = SignatureOf(lastUse.node); TypeUnit tu = TypeUnit.FromArgument(signature.args[lastUse.index]); ia.addType(tu); return(true); } } return(false); }