public override void SubstituteUse(IRVariable variable, IRExpression expression) { if (ReferenceEquals(Address, variable)) { Address = expression.CloneComplete(); } else { Address.Substitute(variable, expression); } Uses.Clear(); Uses.UnionWith(Address.GetAllVariables()); if (ReferenceEquals(Operand, variable)) { Operand = expression.CloneComplete(); } else { Operand.Substitute(variable, expression); } Uses.UnionWith(Operand.GetAllVariables()); }
public void ConstConstNeTest() { IRExpression expression = 3; IRExpression template = 7; var mapping = new Dictionary <IRVariable, IRExpression>(); Assert.IsFalse(expression.Unify(template, mapping)); }
public void ConstConstEqTest() { IRExpression expression = 3; IRExpression template = 3; var mapping = new Dictionary <IRVariable, IRExpression>(); Assert.IsTrue(expression.Unify(template, mapping)); Assert.AreEqual(0, mapping.Count); }
public IRReturn(IRBasicBlock parentBlock, IRExpression returnValue) : base(parentBlock) { ReturnValue = returnValue; if (!(ReturnValue is null)) { Uses.UnionWith(ReturnValue.GetAllVariables()); } }
public void VarConstTest() { IRExpression expression = 3; var templateVarA = new IRRegisterVariable(IRPrimitive.S32, "a"); var template = templateVarA; var mapping = new Dictionary <IRVariable, IRExpression>(); Assert.IsTrue(expression.Unify(template, mapping)); Assert.AreEqual(1, mapping.Count); Assert.AreEqual(mapping[templateVarA], expression); }
public void MultiVarNeTest2() { IRExpression irConst3 = 3; IRExpression irConst2 = 2; IRExpression expression = irConst3 + irConst2; var templateVarA = new IRRegisterVariable(IRPrimitive.S32, "a"); var template = templateVarA + templateVarA; var mapping = new Dictionary <IRVariable, IRExpression>(); Assert.IsFalse(expression.Unify(template, mapping)); }
public IRAssignment(IRBasicBlock parentBlock, IRExpression destination, IRExpression source) : base(parentBlock) { Destination = destination; Source = source; if (Destination is IRVariable v) { Defs.Add(v); } Uses.UnionWith(Source.GetAllVariables()); }
public void MultiVarEqTest2() { IRExpression irConst3 = 3; IRExpression expression = irConst3 + irConst3; var templateVarA = new IRRegisterVariable(IRPrimitive.S32, "a"); var template = templateVarA + templateVarA; var mapping = new Dictionary <IRVariable, IRExpression>(); Assert.IsTrue(expression.Unify(template, mapping)); Assert.AreEqual(1, mapping.Count); Assert.AreEqual(mapping[templateVarA], irConst3); }
public IRStore(IRBasicBlock parentBlock, IRType type, IRExpression address, IRExpression operand) : base(parentBlock) { if (type == IRPrimitive.Void || type == IRPrimitive.Bool) { throw new IRTypeException(); } Type = type; Address = address; Operand = operand; Uses.UnionWith(Address.GetAllVariables()); Uses.UnionWith(Operand.GetAllVariables()); }
public override void SubstituteUse(IRVariable variable, IRExpression expression) { if (ReferenceEquals(ReturnValue, variable)) { ReturnValue = expression.CloneComplete(); } else { ReturnValue.Substitute(variable, expression); } Uses.Clear(); Uses.UnionWith(ReturnValue.GetAllVariables()); }
public override void Substitute(IRExpression template, IRExpression substitution, IRExpression.OnMatchFoundHandler callback) { Operand.Substitute(template, substitution, callback); var mapping = new Dictionary <IRVariable, IRExpression>(); if (Operand.Unify(template, mapping) && callback(mapping)) { var newExpr = substitution.CloneComplete(); foreach (var varMap in mapping) { newExpr.Substitute(varMap.Key, varMap.Value); } Operand = newExpr; } }
public override void SubstituteDef(IRVariable variable, IRExpression expression) { if (expression is IRVariable) { if (ReferenceEquals(Destination, variable)) { Destination = expression.CloneComplete(); } else { Destination.Substitute(variable, expression); } Defs.Clear(); Defs.UnionWith(Destination.GetAllVariables()); } }
public override void SubstituteDef(IRVariable variable, IRExpression expression) { }
public abstract void Substitute(IRExpression template, IRExpression substitution, IRExpression.OnMatchFoundHandler callback);
public void Substitute(IRExpression template, IRExpression substitution) { Substitute(template, substitution, _ => true); }
public abstract void SubstituteDef(IRVariable variable, IRExpression expression);
public override void Run(IRContext context) { bool changed = true; while (changed) { changed = false; foreach (var block in context.Function.BasicBlocks) { for (int i = 0; i < block.Instructions.Count; i++) { var instruction = block.Instructions[i]; IRVariable v = null; IRExpression irExpr = null; IRInstruction instr = null; foreach (var use in instruction.Uses) { if (use is IRStackVariable) { continue; } var defs = block.FindDefs(i, use); if (defs.Length != 1) { continue; } if (defs[0] is IRAssignment assgn && !(assgn.Source is IRCallExpression)) { if (assgn.ParentBlock.FindUses(assgn, use).Length != 1) { continue; } v = use; irExpr = assgn.Source; instr = assgn; break; } } if (!(irExpr is null)) { //check that all defs of uses are equal bool ok = true; foreach (var exprVar in irExpr.GetAllVariables()) { var defsOriginal = instr.ParentBlock.FindDefs(instr, exprVar); var defsNew = block.FindDefs(instruction, exprVar); if (!defsOriginal.ToHashSet().SetEquals(defsNew)) { ok = false; break; } } if (ok) { instruction.SubstituteUse(v, irExpr); changed = true; } } if (changed) { break; } } if (changed) { break; } } new DeadCodeEliminator().Run(context); } }