Esempio n. 1
0
 public IRReturn(IRBasicBlock parentBlock, IRExpression returnValue)
     : base(parentBlock)
 {
     ReturnValue = returnValue;
     if (!(ReturnValue is null))
     {
         Uses.UnionWith(ReturnValue.GetAllVariables());
     }
 }
Esempio n. 2
0
 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());
 }
Esempio n. 3
0
 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());
 }
Esempio n. 4
0
        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);
            }
        }