/// <summary cref="IPhiBindingAllocator.Allocate(CFG.Node, PhiValue)"/> public void Allocate(CFG.Node node, PhiValue phiValue) { var variable = Parent.Allocate(phiValue); var targetNode = node; foreach (var argument in phiValue) { targetNode = argument.BasicBlock == null ? CFG.EntryNode : Dominators.GetImmediateCommonDominator( targetNode, CFG[argument.BasicBlock]); if (targetNode == CFG.EntryNode) { break; } } if (!phiMapping.TryGetValue(targetNode.Block, out var phiVariables)) { phiVariables = new List <Variable>(); phiMapping.Add(targetNode.Block, phiVariables); } phiVariables.Add(variable); }
/// <summary> /// Constructs a new data instance. /// </summary> /// <param name="node">The CFG node.</param> public NodeData(CFG.Node node) { Node = node; Index = -1; LowLink = -1; OnStack = false; }
private static bool MergeChain( Method.Builder builder, CFG.Node rootNode, HashSet <CFG.Node> mergedNodes) { if (rootNode.NumSuccessors != 1) { return(false); } var rootBlockBuilder = builder[rootNode.Block]; var successors = rootNode.Successors; bool result = false; do { var nextBlock = successors[0]; // We cannot merge jump targets in div. control flow if (nextBlock.NumPredecessors > 1) { break; } mergedNodes.Add(nextBlock); successors = nextBlock.Successors; rootBlockBuilder.MergeBlock(nextBlock.Block); result = true; }while (successors.Count == 1); return(result); }
/// <summary> /// Returns the first dominator of the given node. /// This might be the node itself if there are no other /// dominators. /// </summary> /// <param name="cfgNode">The node.</param> /// <returns>The first dominator.</returns> public CFG.Node GetImmediateDominator(CFG.Node cfgNode) { Debug.Assert(cfgNode != null, "Invalid CFG node"); var rpoNumber = idomsInRPO[cfgNode.NodeIndex]; return(nodesInRPO[rpoNumber]); }
/// <summary> /// Returns true if the given <paramref name="cfgNode"/> node is /// dominated by the <paramref name="dominator"/> node. /// </summary> /// <param name="cfgNode">The node.</param> /// <param name="dominator">The potential dominator.</param> /// <returns>True, if the given node is dominated by the dominator.</returns> public bool IsDominatedBy(CFG.Node cfgNode, CFG.Node dominator) { Debug.Assert(cfgNode != null, "Invalid CFG node"); Debug.Assert(dominator != null, "Invalid dominator"); var left = cfgNode.NodeIndex; var right = dominator.NodeIndex; return(Intersect(left, right) == right); }
/// <summary> /// Returns the first dominator of the given node. /// This might be the node itself if there are no other /// dominators. /// </summary> /// <param name="first">The first node.</param> /// <param name="second">The first node.</param> /// <returns>The first dominator.</returns> public CFG.Node GetImmediateCommonDominator(CFG.Node first, CFG.Node second) { Debug.Assert(first != null, "Invalid first CFG node"); Debug.Assert(second != null, "Invalid second CFG node"); if (first == second) { return(first); } var left = first.NodeIndex; var right = second.NodeIndex; var idom = Intersect(left, right); return(nodesInRPO[idom]); }
private static bool TryCreate( Dominators dominators, CFG.Node exitNode, out IfInfo ifInfo) { Debug.Assert(dominators != null, "Invalid dominators"); Debug.Assert(exitNode != null, "Invalid exit node"); ifInfo = default; // Check whether this node can be the exit node of an if branch if (exitNode.NumPredecessors != 2) { return(false); } // Interpret each predecessor as one branch var truePred = exitNode.Predecessors[0]; var falsePred = exitNode.Predecessors[1]; // Try to resolve the branch node var entryNode = dominators.GetImmediateCommonDominator(truePred, falsePred); if (entryNode.NumSuccessors != 2) { return(false); } var entryBlock = entryNode.Block; if (!(entryBlock.Terminator is ConditionalBranch branch)) { return(false); } ifInfo = new IfInfo( branch.Condition, entryBlock, branch.TrueTarget, branch.FalseTarget, exitNode.Block); return(true); }
/// <summary cref="IPhiBindingAllocator.Allocate(CFG.Node, PhiValue)"/> public void Allocate(CFG.Node node, PhiValue phiValue) => Parent.Allocate(phiValue);
/// <summary cref="IPhiBindingAllocator.Process(CFG.Node, Phis)"/> public void Process(CFG.Node node, Phis phis) { }
/// <summary> /// Constructs a new SSA block. /// </summary> /// <param name="parent">The associated parent builder.</param> /// <param name="node">The current node.</param> internal ValueContainer(SSABuilder <TVariable> parent, CFG.Node node) { Debug.Assert(parent != null, "Invalid parent"); Parent = parent; Node = node; }
public NodeData GetValue(CFG.Node node) => new NodeData(node);
/// <summary> /// Tries to resolve the given node to an if-info instance. /// </summary> /// <param name="node">The node to lookup.</param> /// <param name="ifInfo">The resolved if info (if any).</param> /// <returns>True, if any if info could be resolved.</returns> public bool TryGetIfInfo(CFG.Node node, out IfInfo ifInfo) => ifs.TryGetValue(node, out ifInfo);
/// <summary> /// Returns true if the given <paramref name="dominator"/> node. is /// dominating the <paramref name="cfgNode"/> node. /// </summary> /// <param name="dominator">The potential dominator.</param> /// <param name="cfgNode">The other node.</param> /// <returns>True, if the given node is dominating the other node.</returns> public bool Dominates(CFG.Node dominator, CFG.Node cfgNode) => IsDominatedBy(cfgNode, dominator);