public IReadonlyNodeArray CollectGarbage() { foreach (Node n in ChildArray) n.needed = false; GraphProcessor graphProcessor = new GraphProcessor(); GCVisitor gcVisitor = new GCVisitor(graphProcessor); foreach (Node n in NextArray) gcVisitor.AddTask(n, null); graphProcessor.Process(); NodeArray arr = new NodeArray(); foreach (Node n in ChildArray) if (! n.needed) arr.Add(n); return arr; }
public BasicBlockStub(Variable var, BasicBlock block) { prev = new ArrayList(); next = new ArrayList(); isEmpty = true; foreach (ManageVar node in var.UsersArray) isEmpty &= (node.Options[BasicBlock.BASIC_BLOCK_OPTION] as BasicBlock) != block; usageArray = new NodeArray(); if (! isEmpty) { foreach (Node node in block.Body) if (node is ManageVar) { ManageVar usage = node as ManageVar; if (usage.Var == var) usageArray.Add(usage); } } }
private bool performUnnecessaryStoringRemoval() { bool result = false; bool containsProtectedBlock = false; MethodBodyBlock mbb = Entry.Body[0] as MethodBodyBlock; foreach (Node node in mbb.ChildArray) containsProtectedBlock |= node is ProtectedBlock; if (containsProtectedBlock) { Hashtable varFlags = new Hashtable(); foreach (BasicBlock block in blockList) { int i; NodeArray body = block.Body; if (body.Count > 0) { Node lastNode = body[body.Count-1]; bool initialFlag = lastNode is Leave && lastNode.Parent is MethodBodyBlock; foreach (Variable var in mbb.Variables) varFlags[var] = initialFlag; for (i = body.Count-1; i >= 0; i--) { Node node = body[i]; if (node is LoadVar || node is StoreVar) { Variable var = (node as ManageVar).Var; if (varIsNotReferenced(var)) { bool flag = (bool)(varFlags[var]); if (node is LoadVar && flag) varFlags[var] = false; else if (node is StoreVar && ! flag) varFlags[var] = true; else if (node is StoreVar && flag) { result = true; replaceNodeByPop(node); node.RemoveFromGraph(); } } } } } } } else { foreach (Variable var in mbb.Variables) if (varIsNotReferenced(var)) { VarUsage usage = analyseVariable(var); NodeArray nodesToRemove = new NodeArray(); foreach (ManageVar node in var.UsersArray) if (node is StoreVar) { StoreVar storer = node as StoreVar; if (! usage.IsUsed(storer)) nodesToRemove.Add(storer); } foreach (StoreVar storer in nodesToRemove) { result = true; replaceNodeByPop(storer); storer.RemoveFromGraph(); } } } return result; }
private bool performVariableAliasesRemoval() { bool result = false; foreach (Variable v in mbb.Variables) { if (v.UsersArray.Count == 1) { Node varUseNode = v.UsersArray[0]; if (varUseNode is LoadVar) { BasicBlock block = varUseNode.Options[BasicBlock.BASIC_BLOCK_OPTION] as BasicBlock; Node nextNode = varUseNode.Next; while (nextNode is DuplicateStackTop && nextNode.Options[BasicBlock.BASIC_BLOCK_OPTION] == block) nextNode = nextNode.Next; if (nextNode is StoreVar && nextNode.Options[BasicBlock.BASIC_BLOCK_OPTION] == block) { LoadVar ldNode = varUseNode as LoadVar; StoreVar stNode = nextNode as StoreVar; Variable var = ldNode.Var, alias = stNode.Var; if (var != alias && var.Type.Equals(alias.Type)) { result = true; replaceNodeByPop(stNode); stNode.RemoveFromGraph(); NodeArray aliasUsageList = new NodeArray(); foreach (Node node in alias.UsersArray) aliasUsageList.Add(node); foreach (ManageVar node in aliasUsageList) node.Var = var; } } } } } return result; }
private bool performConstantAliasesRemoval() { bool result = false; foreach (Variable v in mbb.Variables) if (varIsNotReferenced(v) && v.Kind == VariableKind.Local) { Node varUseNode = null; int count = 0; foreach (Node node in v.UsersArray) if (node is StoreVar) { varUseNode = node; count++; } if (count == 1) { BasicBlock block = varUseNode.Options[BasicBlock.BASIC_BLOCK_OPTION] as BasicBlock; Node prevNode = varUseNode.PrevArray[0]; while (prevNode is DuplicateStackTop && prevNode.Options[BasicBlock.BASIC_BLOCK_OPTION] == block) prevNode = prevNode.PrevArray[0]; if (prevNode is LoadConst && prevNode.Options[BasicBlock.BASIC_BLOCK_OPTION] == block) { result = true; StoreVar stNode = varUseNode as StoreVar; LoadConst ldNode = prevNode as LoadConst; NodeArray aliasUsageList = new NodeArray(); foreach (Node node in stNode.Var.UsersArray) if (node is LoadVar) aliasUsageList.Add(node); replaceNodeByPop(stNode); stNode.RemoveFromGraph(); foreach (LoadVar node in aliasUsageList) { Node n = ldNode.Clone(); BasicBlock blk = node.Options[BasicBlock.BASIC_BLOCK_OPTION] as BasicBlock; n.Options[BasicBlock.BASIC_BLOCK_OPTION] = blk; blk.Body[blk.Body.IndexOf(node)] = n; node.ReplaceByNode(n); n.Next = node.Next; node.RemoveFromGraph(); } } } } return result; }