예제 #1
0
            private static Node ForTree(BasicBlock BB, Instruction Instruction, CpState State, Node Node, bool TopIsDef, ref bool Changed, Dictionary <Location, LocDef> InsertedDict)
            {
                if (Node == null)
                {
                    return(null);
                }

                if (!TopIsDef && Node.NodeType == NodeType.Location)
                {
                    LocationNode LocationNode = (LocationNode)Node;
                    LocDef       LocDef;

                    if (LocationNode.Location.LocationType == LocationType.CilStack && State.Defs.TryGetValue(LocationNode.Location, out LocDef))
                    {
                        InsertedDict[LocationNode.Location] = LocDef;

                        Changed = true;
                        Node    = LocDef.Node;
                    }
                }
                else
                {
                    for (int i = 0; i < Node.SubNodes.Count; i++)
                    {
                        Node SubNode = Node.SubNodes[i];
                        SubNode          = ForTree(BB, Instruction, State, SubNode, (SubNode.NodeType == NodeType.AddressOf) ? true : false, ref Changed, InsertedDict);
                        Node.SubNodes[i] = SubNode;
                    }
                }

                return(Node);
            }
예제 #2
0
 public static extern bool GetCpuStatusH(int ocbNum, out CpState pCpState);
예제 #3
0
            /// <summary>
            /// Perform intra-block copy propagation.
            /// </summary>
            /// <param name="Graph">HlGraph.</param>
            /// <returns>TRUE if any changes have occured, FALSE otherwise.</returns>
            public static bool Do(HlGraph Graph)
            {
                bool    Changed = false;
                CpState State   = new CpState();
                Dictionary <Location, LocDef> InsertedDict = new Dictionary <Location, LocDef>();
                List <Location> RemoveKeys = new List <Location>();
                List <KeyValuePair <Location, LocDef> > NewDefs = new List <KeyValuePair <Location, LocDef> >();

                //
                // Get the list of undefined locations at the end of each basic block
                //

                DataFlow <LocationList> .Result DfResult = DeadAssignmentElimination.DoDF(Graph);

                //
                // Iterate through basic blocks
                //

                foreach (BasicBlock BB in Graph.BasicBlocks)
                {
                    //
                    // Iterate through instructions
                    //

                    State.Defs.Clear();
                    for (int InstructionIndex = 0; InstructionIndex < BB.Instructions.Count; InstructionIndex++)
                    {
                        Instruction Instruction = BB.Instructions[InstructionIndex];

                        //
                        // Query lists of used and defined locations for the current instruction. If it uses
                        // a location that is present in the CpState, the definition can only be pasted if:
                        //
                        // 1) The definition is not of the form "x := f(..., x, ...)"; i.e., the location
                        //    does not depend on an equally-named one at the defining site,
                        //
                        // OR
                        //
                        // 2) The definition is of the form "x := f(..., x, ...)", and the definition is dead after
                        //    the current instruction.
                        //
                        // NOTE: Pasting the definition in case (2) duplicates evaluation of "f" at the current
                        // instruction, as dead assignment elimination will not be able to remove the original
                        // defining site due to location x being used here. Therefore, in this case, we need to
                        // remove the instruction itself if the definition is pasted, but we can only do so if the
                        // value is not used afterwards.
                        //

                        LocationUsage LocationUsage = LocationUsage.ForInstruction(Instruction);

                        foreach (Location Location in LocationUsage.UsedLocations)
                        {
                            LocDef LocDef;
                            if (State.Defs.TryGetValue(Location, out LocDef) && LocDef.SelfRef)
                            {
                                LocationList DeadList = DeadAssignmentElimination.BeforeInstruction(BB, InstructionIndex + 1, DfResult.ExitState[BB]);
                                if (!DeadList.Contains(Location))
                                {
                                    State.Defs.Remove(Location);
                                }
                            }
                        }

                        //
                        // Rewrite trees
                        //

                        Instruction.Argument = ForTree(BB, Instruction, State, Instruction.Argument, false, ref Changed, InsertedDict);
                        Instruction.Result   = ForTree(BB, Instruction, State, Instruction.Result, true, ref Changed, InsertedDict);

                        //
                        // Change CpState to reflect any newly defined locations
                        //

                        foreach (Location Location in LocationUsage.DefinedLocations)
                        {
                            State.Defs.Remove(Location);
                            if (Location.LocationType == LocationType.CilStack || Location.LocationType == LocationType.LocalVariable)
                            {
                                System.Diagnostics.Debug.Assert(Instruction.InstructionType == InstructionType.Assignment);

                                if (Instruction.Result != null && Instruction.Result.NodeType == NodeType.Location)
                                {
                                    LocDef NewLocDef = new LocDef(BB, Instruction, Location, Instruction.Argument);
                                    NewDefs.Add(new KeyValuePair <Location, LocDef>(Location, NewLocDef));
                                }
                            }

                            //
                            // Remove other definition entries that have been invalidated by redefining one of their inputs
                            //

                            foreach (KeyValuePair <Location, LocDef> Entry in State.Defs)
                            {
                                if (Entry.Value.UsedLocations.Contains(Location))
                                {
                                    RemoveKeys.Add(Entry.Key);
                                }
                            }
                        }

                        //
                        // Remove and add entries to CpState as necessary
                        //

                        if (RemoveKeys != null && RemoveKeys.Count != 0)
                        {
                            foreach (Location RemoveLocation in RemoveKeys)
                            {
                                State.Defs.Remove(RemoveLocation);
                            }
                            RemoveKeys.Clear();
                        }

                        if (NewDefs != null && NewDefs.Count != 0)
                        {
                            foreach (KeyValuePair <Location, LocDef> Entry in NewDefs)
                            {
                                State.Defs.Add(Entry.Key, Entry.Value);
                            }
                            NewDefs.Clear();
                        }

                        //
                        // Remove instructions at defining sites that have become obsolete. This is only
                        // true for CilStack locations, as they are the only ones guaranteed to be consumed
                        // at most once. All other obsolete instructions are taken care of by dead code
                        // elimination.
                        //
                        // BUGBUG: this fails for the DUP instruction...
                        //

                        if (InsertedDict.Count != 0 && LocationUsage.UsedLocations.Count != 0)
                        {
                            foreach (Location Location in LocationUsage.UsedLocations)
                            {
                                LocDef RemoveLocDef;
                                if (Location.LocationType == LocationType.CilStack && InsertedDict.TryGetValue(Location, out RemoveLocDef))
                                {
                                    bool OK = RemoveLocDef.BasicBlock.Instructions.Remove(RemoveLocDef.Instruction);

                                    //System.Diagnostics.Debug.Assert(OK);
                                    System.Diagnostics.Debug.Assert(object.ReferenceEquals(RemoveLocDef.BasicBlock, BB));
                                    if (object.ReferenceEquals(RemoveLocDef.BasicBlock, BB) && OK)
                                    {
                                        System.Diagnostics.Debug.Assert(object.ReferenceEquals(BB.Instructions[InstructionIndex - 1], Instruction));
                                        InstructionIndex--;
                                    }
                                }
                            }
                        }
                        InsertedDict.Clear();
                    }
                }

                return(Changed);
            }