示例#1
0
文件: Block.cs 项目: Nxun/Naive-Tiger
 public BuildBlocks(List<TExp> instList)
 {
     Dictionary<Temp.Label, BasicBlock> LabelToBlock = new Dictionary<Temp.Label, BasicBlock>();
     foreach (TExp e in instList)
     {
         if (e is Label)
         {
             BasicBlock b = new BasicBlock();
             Blocks.Add(b);
             LabelToBlock[(e as Label).Lab] = b;
         }
         Blocks[Blocks.Count - 1].List.Add(e);
     }
     for (int i = 0; i < Blocks.Count; ++i)
     {
         BasicBlock b = Blocks[i];
         if (b.List[b.List.Count - 1] is Jump)
         {
             b.AddEdge(LabelToBlock[(b.List[b.List.Count - 1] as Jump).Label.Lab]);
         }
         else
         {
             if (i + 1 < Blocks.Count)
                 b.AddEdge(Blocks[i + 1]);
             if (b.List[b.List.Count - 1] is CJump)
                 b.AddEdge(LabelToBlock[(b.List[b.List.Count - 1] as CJump).Label.Lab]);
             else if (b.List[b.List.Count - 1] is CJumpInt)
                 b.AddEdge(LabelToBlock[(b.List[b.List.Count - 1] as CJumpInt).Label.Lab]);
         }
     }
 }
示例#2
0
 public override BasicBlock<MilocInstruction> Load(int target)
 {
     var b = new BasicBlock<MilocInstruction>();
     b.Add(new LoadaiFieldInstruction(addressReg, name, target) { ContainingType = containingType, FieldIndex = fieldIndex, FieldType = this.Type });
     b.Reg = target;
     return b;
 }
示例#3
0
文件: Block.cs 项目: Nxun/Naive-Tiger
 public void AddEdge(BasicBlock target)
 {
     if (target == null)
         return;
     Next.Add(target);
     target.Prev.Add(this);
 }
示例#4
0
 public override BasicBlock<MilocInstruction> Load(int target)
 {
     var b = new BasicBlock<MilocInstruction>();
     b.Add(new LoadglobalInstruction(name, target) { Type = this.Type });
     b.Reg = target;
     return b;
 }
示例#5
0
 public override BasicBlock<MilocInstruction> Load(int target)
 {
     var b = new BasicBlock<MilocInstruction>();
     b.Add(new LoadaiVarInstruction(name, target) { ArgIndex = ArgIndex });
     b.Reg = target;
     return b;
 }
示例#6
0
 public override BasicBlock<MilocInstruction> Load(int target)
 {
     var b = new BasicBlock<MilocInstruction>();
     b.Add(new MovInstruction(this.reg, target) { ArgIndex = ArgIndex, ArgReg = reg });
     b.Reg = target;
     return b;
 }
        /// <summary>
        /// replaces comparisons where one operand has just been set to a const zero.
        /// asumes that instruction is a comparison instruction with two registers.
        /// </summary>
        private bool OptimizeComparisonToConstZero(Instruction ins, BasicBlock bb)
        {
            var r1 = ins.Registers[0];
            var r2 = ins.Registers[1];
            
            bool? r1IsZero = null, r2IsZero = null;

            if (r1.Category == RCategory.Argument || r1.PreventOptimization)
                r1IsZero = false;
            if (r2.Category == RCategory.Argument || r2.PreventOptimization)
                r2IsZero = false;

            for (var prev = ins.PreviousOrDefault; prev != null && prev.Index >= bb.Entry.Index; prev=prev.PreviousOrDefault)
            {
                if(r1IsZero.HasValue && r2IsZero.HasValue)
                    break;
                if ((r1IsZero.HasValue && r1IsZero.Value) || (r2IsZero.HasValue && r2IsZero.Value))
                    break;

                if (r1IsZero == null)
                {
                    if (r1.IsDestinationIn(prev))
                    {
                        r1IsZero = prev.Code == RCode.Const && Convert.ToInt32(prev.Operand) == 0;
                        continue;
                    }
                }
                if (r2IsZero == null)
                {
                    if (r2.IsDestinationIn(prev))
                    {
                        r2IsZero = prev.Code == RCode.Const && Convert.ToInt32(prev.Operand) == 0;
                        continue;
                    }
                }
            }

            if (r2IsZero.HasValue && r2IsZero.Value)
            {
                ins.Code = ToComparisonWithZero(ins.Code);
                ins.Registers.Clear();
                ins.Registers.Add(r1);
                return true;
            }

            if (r1IsZero.HasValue && r1IsZero.Value)
            {
                // swap the registers before converting to zero-comparison.
                ins.Code = ToComparisonWithZero(SwapComparisonRegisters(ins.Code));
           

                ins.Registers.Clear();
                ins.Registers.Add(r2);
                return true;
            }
            

            return false;
        }
        /// <summary>
        /// Links the blocks.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="destination">The destination.</param>
        protected void LinkBlocks(BasicBlock source, BasicBlock destination)
        {
            if (!source.NextBlocks.Contains(destination))
                source.NextBlocks.Add(destination);

            if (!destination.PreviousBlocks.Contains(source))
                destination.PreviousBlocks.Add(source);
        }
 public IEnumerable<BasicBlock> GetSuccessors(BasicBlock source)
 {
     foreach (XRef xref in graph.GetReferencesFrom(source.Location))
     {
         // TODO: change Find to ExactMatch.
         yield return blocks.Find(xref.Target);
     }
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="context"></param>
 public void LinkBlockToClause(Context context, BasicBlock block)
 {
     foreach (EhClause clause in this.Clauses)
     {
         if (clause.LinkBlockToClause(context, block))
             return;
     }
 }
示例#11
0
 public BasicBlockEdge(CFG cfg, int fromName, int toName)
 {
     From = cfg.CreateNode(fromName);
     To = cfg.CreateNode(toName);
     From.OutEdges.Add(To);
     To.InEdges.Add(From);
     cfg.AddEdge(this);
 }
示例#12
0
        List<BasicBlock> IDominanceAnalysis.GetChildren(BasicBlock block)
        {
            List<BasicBlock> child;

            if (children.TryGetValue(block, out child))
                return child;
            else
                return new List<BasicBlock>(); // Empty List
        }
示例#13
0
        public BBLoop(BasicBlock head, BasicBlock tail, IMSet<BasicBlock> body, JST.Identifier label)
        {
            Head = head;
            Tail = tail;
            Body = body;
            Label = label;

            var headEscapes = false;
            var headbranchbb = head as BranchBasicBlock;
            foreach (var t in head.Targets)
            {
                if (!body.Contains(t))
                    headEscapes = true;
            }

            var tailEscapes = false;
            var tailbranchbb = tail as BranchBasicBlock;
            foreach (var t in tail.Targets)
            {
                if (!body.Contains(t))
                    tailEscapes = true;
            }

            if (!headEscapes && tailEscapes && tailbranchbb != null)
            {
                if (tailbranchbb.Target.Equals(head))
                    Flavor = LoopFlavor.DoWhile;
                else if (tailbranchbb.Fallthrough.Equals(head))
                    Flavor = LoopFlavor.FlippedDoWhile;
                else
                    throw new InvalidOperationException("invalid loop");
            }
            else if (headEscapes && !tailEscapes && headbranchbb != null)
            {
                if (body.Contains(headbranchbb.Target))
                    Flavor = LoopFlavor.WhileDo;
                else if (body.Contains(headbranchbb.Fallthrough))
                    Flavor = LoopFlavor.FlippedWhileDo;
                else
                    throw new InvalidOperationException("invalid loop");
            }
            else if (!headEscapes && !tailEscapes)
                Flavor = LoopFlavor.Loop;
            else if (headEscapes && tailEscapes && headbranchbb != null && tailbranchbb != null)
            {
                // Could encode as do-while with a break at start, or while-do with a break at end.
                if (body.Contains(headbranchbb.Target))
                    Flavor = LoopFlavor.WhileDo;
                else if (body.Contains(headbranchbb.Fallthrough))
                    Flavor = LoopFlavor.FlippedWhileDo;
                else
                    throw new InvalidOperationException("invalid loop");
            }
            else
                Flavor = LoopFlavor.Unknown;
        }
示例#14
0
 private static void Redirect(List<BasicBlock> blocks, BasicBlock oldBlock, BasicBlock newBlock)
 {
     foreach (BasicBlock b in blocks)
     {
         if (b.UnconditionalTarget == oldBlock)
             b.UnconditionalTarget = newBlock;
         if (b.ConditionalTarget == oldBlock)
             b.ConditionalTarget = newBlock;
     }
 }
 private Context GetFirstContext(BasicBlock block)
 {
     for (Context context = new Context(InstructionSet, block); !context.IsBlockEndInstruction; context.GotoNext())
     {
         if (context.IsBlockStartInstruction)
             continue;
         return context;
     }
     return null;
 }
        public BasicBlockEdge(CFG cfg, int fromName, int toName)
        {
            from = cfg.createNode(fromName);
            to = cfg.createNode(toName);

            from.addOutEdge(to);
            to.addInEdge(from);

            cfg.addEdge(this);
        }
示例#17
0
 public ExtendedBlock(BasicBlock basicBlock, int registerCount, int loopDepth)
 {
     this.BasicBlock = basicBlock;
     this.LiveGen = new BitArray(registerCount);
     this.LiveKill = new BitArray(registerCount);
     this.LiveOut = new BitArray(registerCount);
     this.LiveIn = new BitArray(registerCount);
     this.LiveKillNot = new BitArray(registerCount);
     this.LoopDepth = loopDepth;
 }
示例#18
0
 private void doInvoke(string id, BasicBlock<MilocInstruction> b, List<int> regLocs)
 {
     var fun = CSC431.Program.Stable.Value.getType(id);
     for (int i = 0; i < regLocs.Count; i++)
     {
         var t = fun.getArgs()[i];
         b.Add(new StoreoutargumentInstruction(regLocs[i], i) { Type = t });
     }
     b.Add(new CallInstruction(id));
 }
        protected void RemoveDeadBlock(BasicBlock block)
        {
            if (trace.Active) trace.Log("*** RemoveBlock: " + block.ToString());

            var nextBlocks = block.NextBlocks.ToArray();

            EmptyBlockOfAllInstructions(block);

            UpdatePhiList(block, nextBlocks);
        }
示例#20
0
        public MoveResolver(BasicBlock anchor, BasicBlock source, BasicBlock destination)
        {
            Debug.Assert(source != null);
            Debug.Assert(destination != null);
            Debug.Assert(anchor != null);

            this.Anchor = anchor;
            this.Source = source;
            this.Destination = destination;
            this.moves = new List<Move>();
        }
        private void SplitEdge(BasicBlock from, BasicBlock to)
        {
            // Create new block z
            var ctx = CreateNewBlockContext();

            InsertJumpInstruction(ctx, to);

            ctx.Label = -1;

            ReplaceBranchTargets(from, to, ctx.Block);
        }
示例#22
0
            public BasicBlock CreateNode(int name)
            {
                var node = BasicBlockMap.ContainsKey(name) ? BasicBlockMap[name] : null;
                if (node == null)
                {
                    node = new BasicBlock(name);
                    BasicBlockMap[name] = node;
                }

                if (StartNode == null) StartNode = node;
                return node;
            }
示例#23
0
        public IDominanceAnalysis GetDominanceAnalysis(BasicBlock headBlock)
        {
            IDominanceAnalysis analysis;

            if (!blockAnalysis.TryGetValue(headBlock, out analysis))
            {
                analysis = dominanceAnalysisFactory();
                analysis.PerformAnalysis(basicBlocks, headBlock);
                blockAnalysis.Add(headBlock, analysis);
            }

            return analysis;
        }
示例#24
0
        internal ILBuilder(ITokenDeferral module, LocalSlotManager localSlotManager, OptimizationLevel optimizations)
        {
            Debug.Assert(BitConverter.IsLittleEndian);

            this.module = module;
            this.LocalSlotManager = localSlotManager;
            _emitState = default(EmitState);
            _scopeManager = new LocalScopeManager();

            leaderBlock = _currentBlock = _scopeManager.CreateBlock(this);

            _labelInfos = new SmallDictionary<object, LabelInfo>(ReferenceEqualityComparer.Instance);
            _optimizations = optimizations;
        }
示例#25
0
        internal ILBuilder(ITokenDeferral module, LocalSlotManager localSlotManager, bool isOptimizing)
        {
            Debug.Assert(BitConverter.IsLittleEndian);

            this.module = module;
            this.LocalSlotManager = localSlotManager;
            this.emitState = default(EmitState);
            this.scopeManager = new LocalScopeManager();

            leaderBlock = currentBlock = this.scopeManager.CreateBlock(this);

            labelInfos = new SmallDictionary<object, LabelInfo>(ReferenceEqualityComparer.Instance);
            this.isOptimizing = isOptimizing;
        }
示例#26
0
 /// <summary>
 /// Default ctor.
 /// </summary>
 internal BlockSpillCodeGenerator(BasicBlock block, RegisterMapper mapper, List<Register> lowRegisters, List<Register> invokeFrame, List<Register> allRegisters)
 {
     this.block = block;
     this.mapper = mapper;
     this.lowRegisters = new LowRegisterState[lowRegisters.Count];
     LowRegisterState next = null;
     for (var i = lowRegisters.Count - 1; i >= 0; i--)
     {
         this.lowRegisters[i] = new LowRegisterState(lowRegisters[i], next);
         next = this.lowRegisters[i];
     }
     this.invokeFrame = invokeFrame;
     this.allRegisters = allRegisters;
 }
示例#27
0
        /// <summary>
        /// Adds the value.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="edge">The edge.</param>
        /// <param name="op">The op.</param>
        public static void AddValue(Context ctx, BasicBlock edge, StackOperand op)
        {
            PhiData phiData = ctx.Other as PhiData;

            if (phiData == null) {
                phiData = new PhiData();
                ctx.Other = phiData;
            }

            List<BasicBlock> blocks = phiData.Blocks as List<BasicBlock>;

            Debug.Assert(blocks.Count < 255, @"Maximum number of operands in PHI exceeded.");

            blocks.Add(edge);
            phiData.Operands.Add(op);
        }
示例#28
0
        private static int RefCount(List<BasicBlock> blocks, BasicBlock block)
        {
            int refcnt = 0;

            foreach (BasicBlock b in blocks)
            {
                if (b.UnconditionalTarget == block)
                    refcnt++;
                if (b.ConditionalTarget == block)
                    refcnt++;
                if (b.handlerTarget == block)
                    refcnt++;
            }

            return refcnt;
        }
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        void IMethodCompilerStage.Run()
        {
            if (methodCompiler.Compiler.PlugSystem.GetPlugMethod(methodCompiler.Method) != null)
                return;

            if (!methodCompiler.Method.HasCode)
                return;

            // Create the prologue block
            Context context = new Context(instructionSet);

            // Add a jump instruction to the first block from the prologue
            context.AppendInstruction(IRInstruction.Jmp);
            context.SetBranch(0);
            context.Label = BasicBlock.PrologueLabel;
            prologue = basicBlocks.CreateBlock(BasicBlock.PrologueLabel, context.Index);
            basicBlocks.AddHeaderBlock(prologue);

            SplitIntoBlocks(0);

            // Create the epilogue block
            context = new Context(instructionSet);

            // Add null instruction, necessary to generate a block index
            context.AppendInstruction(null);
            context.Label = BasicBlock.EpilogueLabel;
            epilogue = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel, context.Index);

            // Link all the blocks together
            BuildBlockLinks(prologue);

            foreach (ExceptionHandlingClause exceptionClause in methodCompiler.ExceptionClauseHeader.Clauses)
            {
                if (exceptionClause.HandlerOffset != 0)
                {
                    BasicBlock basicBlock = basicBlocks.GetByLabel(exceptionClause.HandlerOffset);
                    BuildBlockLinks(basicBlock);
                    basicBlocks.AddHeaderBlock(basicBlock);
                }
                if (exceptionClause.FilterOffset != 0)
                {
                    BasicBlock basicBlock = basicBlocks.GetByLabel(exceptionClause.FilterOffset);
                    BuildBlockLinks(basicBlock);
                    basicBlocks.AddHeaderBlock(basicBlock);
                }
            }
        }
示例#30
0
        /// <summary>
        /// Enters the SSA.
        /// </summary>
        /// <param name="headBlock">The head block.</param>
        private void EnterSSA(BasicBlock headBlock)
        {
            var analysis = MethodCompiler.DominanceAnalysis.GetDominanceAnalysis(headBlock);

            variables = new Dictionary<Operand, Stack<int>>();
            counts = new Dictionary<Operand, int>();

            foreach (var op in phiPlacementStage.Assignments.Keys)
            {
                AddToAssignments(op);
            }

            if (headBlock.NextBlocks.Count > 0)
            {
                RenameVariables(headBlock.NextBlocks[0], analysis);
            }
        }
        protected virtual void UpdateOutput(DataFlowAnalysisResultBuilder <TAnalysisData> builder, BasicBlock block, TAnalysisData newOutput)
        {
            var currentData = builder[block];
            var newData     = currentData.WithOutput(newOutput);

            builder.Update(block, newData);
        }
示例#32
0
 public Edge(BasicBlock fromNode, BasicBlock toNode)
 {
     From = fromNode;
     To   = toNode;
 }
示例#33
0
 /// <summary>
 /// Function to find out whether a basic block is in a loop body, or not.
 /// </summary>
 /// <param name="actual">The questioned basic block.</param>
 /// <returns>True if the basic block is in a loop, False if not.</returns>
 private static bool _isLoopBody(BasicBlock bb)
 {
     return(StartFromBB(bb, true));
 }
示例#34
0
 internal static ThrownExceptionInfo CreateDefaultInfoForExceptionsPathAnalysis(BasicBlock block, WellKnownTypeProvider wellKnownTypeProvider, ImmutableStack <IOperation> interproceduralCallStackOpt)
 {
     Debug.Assert(wellKnownTypeProvider.Exception != null);
     return(new ThrownExceptionInfo(block, wellKnownTypeProvider.Exception, interproceduralCallStackOpt, isDefaultExceptionForExceptionsPathAnalysis: true));
 }
 public TAnalysisResult this[BasicBlock block] => _basicBlockStateMap[block];
示例#36
0
 internal void Update(BasicBlock block, TAnalysisData newData)
 {
     _info[block] = newData;
 }
示例#37
0
 public TAnalysisData this[BasicBlock block] => _info[block];
 private TAnalysisData Flow(BasicBlock block, TAnalysisData data)
 {
     return(Flow(OperationVisitor, block, data));
 }
示例#39
0
 public LoopRegion(BasicBlock header, List <int> outputBlocks, BodyRegion body) : base(header, outputBlocks)
 {
     Body = body;
 }
 internal abstract TAnalysisResult ToResult(BasicBlock basicBlock, DataFlowAnalysisInfo <TAnalysisData> blockAnalysisData);
        public static TAnalysisData Flow(DataFlowOperationVisitor <TAnalysisData, TAbstractAnalysisValue> operationVisitor, BasicBlock block, TAnalysisData data)
        {
            if (block.Kind == BasicBlockKind.Entry)
            {
                operationVisitor.OnEntry(block, data);
            }
            else if (block.Kind == BasicBlockKind.Exit)
            {
                operationVisitor.OnExit(block, data);
            }

            foreach (var statement in block.Statements)
            {
                data = operationVisitor.Flow(statement, block, data);
            }

            return(data);
        }
示例#42
0
 public override void SetCurrentAnalysisData(BasicBlock basicBlock, BasicBlockAnalysisData data)
 => _analysisData.SetBlockAnalysisDataFrom(basicBlock, data);
示例#43
0
 public override BasicBlockAnalysisData GetCurrentAnalysisData(BasicBlock basicBlock)
 => _analysisData.GetBlockAnalysisData(basicBlock);
示例#44
0
 public override BasicBlockAnalysisData AnalyzeNonConditionalBranch(
     BasicBlock basicBlock,
     BasicBlockAnalysisData currentBlockAnalysisData,
     CancellationToken cancellationToken)
 => AnalyzeBranch(basicBlock, currentBlockAnalysisData, cancellationToken);
示例#45
0
 void SetProgramLocation(BasicBlock block)
 {
     _nextNodes      = new Queue <CSharpSyntaxNode>(block.Nodes);
     _nextTerminator = block.Terminator;
 }
示例#46
0
        public static string GetDump(ControlFlowGraph cfg)
        {
            StringBuilder sb = new StringBuilder();

            Dictionary <Operand, string> localNames = new Dictionary <Operand, string>();

            string indentation = string.Empty;

            void IncreaseIndentation()
            {
                indentation += Indentation;
            }

            void DecreaseIndentation()
            {
                indentation = indentation.Substring(0, indentation.Length - Indentation.Length);
            }

            void AppendLine(string text)
            {
                sb.AppendLine(indentation + text);
            }

            IncreaseIndentation();

            for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
            {
                string blockName = GetBlockName(block);

                if (block.Next != null)
                {
                    blockName += $" (next {GetBlockName(block.Next)})";
                }

                if (block.Branch != null)
                {
                    blockName += $" (branch {GetBlockName(block.Branch)})";
                }

                blockName += ":";

                AppendLine(blockName);

                IncreaseIndentation();

                for (Node node = block.Operations.First; node != null; node = node.ListNext)
                {
                    string[] sources = new string[node.SourcesCount];

                    string instName = string.Empty;

                    if (node is PhiNode phi)
                    {
                        for (int index = 0; index < sources.Length; index++)
                        {
                            string phiBlockName = GetBlockName(phi.GetBlock(index));

                            string operName = GetOperandName(phi.GetSource(index), localNames);

                            sources[index] = $"({phiBlockName}: {operName})";
                        }

                        instName = "Phi";
                    }
                    else if (node is Operation operation)
                    {
                        for (int index = 0; index < sources.Length; index++)
                        {
                            sources[index] = GetOperandName(operation.GetSource(index), localNames);
                        }

                        instName = operation.Instruction.ToString();
                    }

                    string allSources = string.Join(", ", sources);

                    string line = instName + " " + allSources;

                    if (node.Destination != null)
                    {
                        line = GetOperandName(node.Destination, localNames) + " = " + line;
                    }

                    AppendLine(line);
                }

                DecreaseIndentation();
            }

            return(sb.ToString());
        }
示例#47
0
 protected override ValueContentBlockAnalysisResult ToBlockResult(BasicBlock basicBlock, ValueContentAnalysisData blockAnalysisData)
 => new ValueContentBlockAnalysisResult(basicBlock, blockAnalysisData);
示例#48
0
 private static string GetBlockName(BasicBlock block)
 {
     return($"block{block.Index}");
 }
示例#49
0
 internal void Add(BasicBlock block)
 {
     _info.Add(block, null);
 }
示例#50
0
        private static void MarkReachableFromSwitch(ArrayBuilder <BasicBlock> reachableBlocks, BasicBlock block)
        {
            var switchBlock  = (SwitchBlock)block;
            var blockBuilder = ArrayBuilder <BasicBlock> .GetInstance();

            switchBlock.GetBranchBlocks(blockBuilder);

            foreach (var targetBlock in blockBuilder)
            {
                PushReachableBlockToProcess(reachableBlocks, targetBlock);
            }

            blockBuilder.Free();
        }
示例#51
0
 internal ThrownExceptionInfo With(BasicBlock block, ImmutableStack <IOperation> interproceduralCallStackOpt)
 {
     Debug.Assert(interproceduralCallStackOpt != InterproceduralCallStack);
     return(new ThrownExceptionInfo(block, ExceptionType, interproceduralCallStackOpt, IsDefaultExceptionForExceptionsPathAnalysis));
 }
示例#52
0
        private static void MarkReachableFromTry(ArrayBuilder <BasicBlock> reachableBlocks, BasicBlock block)
        {
            // Since the try block is reachable, associated
            // catch and finally blocks are also reachable.
            var handlerBlock = ((ExceptionHandlerLeaderBlock)block).NextExceptionHandler;

            Debug.Assert(handlerBlock != null);

            // Subsequent handlers are either one or more catch
            // blocks or a single finally block, but not both.
            if (handlerBlock.Type == BlockType.Finally)
            {
                Debug.Assert(handlerBlock.NextExceptionHandler == null);

                // Walk the finally block before walking the try block since we
                // need to determine whether the finally makes any code after
                // the try/finally unreachable (if the finally throws an exception).
                // (Note, the try block is walked in the outer loop.)
                if (handlerBlock.Reachability != Reachability.Reachable)
                {
                    // we have not processed Finally yet, reschedule block for processing
                    // but process the handler first.
                    block.Reachability = Reachability.NotReachable;
                    PushReachableBlockToProcess(reachableBlocks, block);
                    PushReachableBlockToProcess(reachableBlocks, handlerBlock);
                    return;
                }
            }
            else
            {
                // The order the try and handler blocks are walked is not important.
                // Here, we push the handler blocks, then the try block.
                while (handlerBlock != null)
                {
                    Debug.Assert(handlerBlock.Type == BlockType.Catch || handlerBlock.Type == BlockType.Fault || handlerBlock.Type == BlockType.Filter);
                    PushReachableBlockToProcess(reachableBlocks, handlerBlock);
                    handlerBlock = handlerBlock.NextExceptionHandler;
                }
            }

            MarkReachableFromBranch(reachableBlocks, block);
        }
示例#53
0
 internal static ThrownExceptionInfo Create(BasicBlock block, INamedTypeSymbol exceptionType, ImmutableStack <IOperation> interproceduralCallStackOpt)
 {
     return(new ThrownExceptionInfo(block, exceptionType, interproceduralCallStackOpt, isDefaultExceptionForExceptionsPathAnalysis: false));
 }
示例#54
0
        private static void MarkReachableFromBranch(ArrayBuilder <BasicBlock> reachableBlocks, BasicBlock block)
        {
            var branchBlock = block.BranchBlock;

            if (branchBlock != null)
            {
                // if branch is blocked by a finally, then should branch to corresponding
                // BlockedBranchDestination instead. Original label may not be reachable.
                // if there are no blocking finallys, then BlockedBranchDestination returns null
                // and we just visit the target.
                var blockedDest = BlockedBranchDestination(block, branchBlock);
                if (blockedDest == null)
                {
                    PushReachableBlockToProcess(reachableBlocks, branchBlock);
                }
                else
                {
                    // just redirect. No need to visit blocking destination
                    // it is a single block infinite loop.
                    RedirectBranchToBlockedDestination(block, blockedDest);
                }
            }
        }
示例#55
0
 protected override GlobalFlowStateBlockAnalysisResult ToBlockResult(BasicBlock basicBlock, GlobalFlowStateAnalysisData data)
 => new GlobalFlowStateBlockAnalysisResult(basicBlock, data);
示例#56
0
        /// <summary>
        /// Marks blocks that are recursively reachable from the given block.
        /// </summary>
        private static void MarkReachableFrom(ArrayBuilder <BasicBlock> reachableBlocks, BasicBlock block)
        {
tryAgain:

            if (block != null && block.Reachability == Reachability.NotReachable)
            {
                block.Reachability = Reachability.Reachable;

                var branchCode = block.BranchCode;
                if (branchCode == ILOpCode.Nop && block.Type == BlockType.Normal)
                {
                    block = block.NextBlock;
                    goto tryAgain;
                }

                if (branchCode.CanFallThrough())
                {
                    PushReachableBlockToProcess(reachableBlocks, block.NextBlock);
                }
                else
                {
                    // If this block is an "endfinally" block, then clear
                    // the reachability of the following special block.
                    if (branchCode == ILOpCode.Endfinally)
                    {
                        var enclosingFinally = block.EnclosingHandler;
                        if (enclosingFinally != null)
                        {
                            enclosingFinally.UnblockFinally();
                        }
                    }
                }

                switch (block.Type)
                {
                case BlockType.Switch:
                    MarkReachableFromSwitch(reachableBlocks, block);
                    break;

                case BlockType.Try:
                    MarkReachableFromTry(reachableBlocks, block);
                    break;

                default:
                    MarkReachableFromBranch(reachableBlocks, block);
                    break;
                }
            }
        }
示例#57
0
 /// <summary>
 /// Function to find out whether a basic block is in the main Control Flow, or not.
 /// </summary>
 /// <param name="bb">The questioned basic block.</param>
 /// <returns>True if the basic block is in the main Control Flow, False if not.</returns>
 private static bool _isMainRoute(BasicBlock bb)
 {
     return(!StartFromBB(bb, false));
 }
示例#58
0
 private static void PushReachableBlockToProcess(ArrayBuilder <BasicBlock> reachableBlocks, BasicBlock block)
 {
     if (block.Reachability == Reachability.NotReachable)
     {
         reachableBlocks.Push(block);
     }
 }
 protected virtual IEnumerable <BasicBlock> GetSuccessors(BasicBlock block) => block.Successors;
 protected virtual IEnumerable <BasicBlock> GetPredecessors(BasicBlock block) => block.Predecessors;