Exemplo n.º 1
0
        private static void GenerateCandidateForEnabledness(GPUVerifier verifier, Implementation impl, IRegion region)
        {
            Block header = region.Header();

            if (verifier.UniformityAnalyser.IsUniform(impl.Name, header))
            {
                return;
            }

            var cfg = Program.GraphFromImpl(impl);
            Dictionary <Block, HashSet <Block> > controlDependence = cfg.ControlDependence();

            controlDependence.TransitiveClosure();
            cfg.ComputeLoops();
            var loopNodes = cfg.BackEdgeNodes(header).Select(item => cfg.NaturalLoops(header, item)).SelectMany(item => item);

            Expr guardEnclosingLoop = null;

            foreach (var b in controlDependence.Keys.Where(item => controlDependence[item].Contains(region.Header())))
            {
                foreach (var succ in cfg.Successors(b).Where(item => cfg.DominatorMap.DominatedBy(header, item)))
                {
                    var guard = MaybeExtractGuard(verifier, impl, succ);
                    if (guard != null)
                    {
                        guardEnclosingLoop = guardEnclosingLoop == null ? guard : Expr.And(guardEnclosingLoop, guard);
                        break;
                    }
                }
            }

            if (guardEnclosingLoop != null)
            {
                verifier.AddCandidateInvariant(
                    region,
                    Expr.Imp(Expr.Ident(verifier.FindOrCreateEnabledVariable()), guardEnclosingLoop),
                    "conditionsImpliedByEnabledness");
            }

            var   cfgDual = cfg.Dual(new Block());
            Block loopConditionDominator = header;

            // The dominator might have multiple successors
            while (cfg.Successors(loopConditionDominator).Count(item => loopNodes.Contains(item)) > 1)
            {
                // Find the immediate post-dominator of the successors
                Block block = null;
                foreach (var succ in cfg.Successors(loopConditionDominator).Where(item => loopNodes.Contains(item)))
                {
                    if (block == null)
                    {
                        block = succ;
                    }
                    else
                    {
                        block = cfgDual.DominatorMap.LeastCommonAncestor(block, succ);
                    }
                }

                // Use the immediate post-dominator
                loopConditionDominator = block;
            }

            Expr guardIncludingLoopCondition = null;

            foreach (var succ in cfg.Successors(loopConditionDominator).Where(item => loopNodes.Contains(item)))
            {
                var guard = MaybeExtractGuard(verifier, impl, succ);
                if (guard != null)
                {
                    // There is at most one successor, so it's safe not use GuardIncludingLoopCondition on the rhs
                    guardIncludingLoopCondition = guardEnclosingLoop == null ? guard : Expr.And(guardEnclosingLoop, guard);
                    break;
                }
            }

            if (guardIncludingLoopCondition != null)
            {
                verifier.AddCandidateInvariant(
                    region, Expr.Imp(guardIncludingLoopCondition, Expr.Ident(verifier.FindOrCreateEnabledVariable())), "conditionsImplyingEnabledness", "do_not_predicate");
            }
        }