Exemplo n.º 1
0
 private static void ToReductionList(
     IEnumerable <ValueTag> arguments,
     InstructionPrototype prototype,
     List <ValueTag> reductionArgs,
     HashSet <ValueTag> reductionOps,
     ValueUses uses,
     FlowGraph graph)
 {
     foreach (var arg in arguments)
     {
         NamedInstruction insn;
         if (graph.TryGetInstruction(arg, out insn))
         {
             ToReductionList(
                 insn,
                 prototype,
                 reductionArgs,
                 reductionOps,
                 uses);
         }
         else
         {
             reductionArgs.Add(arg);
         }
     }
 }
Exemplo n.º 2
0
        private static bool TrySimplifyReduction(
            ref List <ValueTag> args,
            InstructionPrototype prototype,
            NamedInstructionBuilder insertionPoint)
        {
            bool changed = false;
            var  newArgs = new List <ValueTag>();

            foreach (var operand in args)
            {
                if (newArgs.Count > 0)
                {
                    var prevOperand = newArgs[newArgs.Count - 1];
                    var folded      = ConstantFold(prevOperand, operand, prototype, insertionPoint);
                    if (folded == null)
                    {
                        newArgs.Add(operand);
                    }
                    else
                    {
                        newArgs[newArgs.Count - 1] = folded;
                        changed = true;
                    }
                }
                else
                {
                    newArgs.Add(operand);
                }
            }
            args = newArgs;
            return(changed);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Tests if an instruction prototype is a intrinsic prototype
        /// with a particular name defined in the current namespace.
        /// </summary>
        /// <param name="prototype">
        /// The prototype to examine.
        /// </param>
        /// <param name="name">
        /// The prototype name to expect.
        /// </param>
        /// <returns>
        /// <c>true</c> if the prototype is a namespaced intrinsic prototype
        /// with a name equal to <paramref name="name"/>; otherwise, <c>false</c>.
        /// </returns>
        public bool IsIntrinsicPrototype(InstructionPrototype prototype, string name)
        {
            string opName;

            return(prototype is IntrinsicPrototype &&
                   TryParseIntrinsicName(((IntrinsicPrototype)prototype).Name, out opName) &&
                   name == opName);
        }
Exemplo n.º 4
0
 /// <summary>
 /// Tells if a particular instruction prototype is a recursive call.
 /// </summary>
 /// <param name="prototype">The instruction prototype to inspect.</param>
 /// <returns>
 /// <c>true</c> if <paramref name="prototype"/> describes a recursive call;
 /// otherwise, <c>false</c>.
 /// </returns>
 private bool IsSelfCallPrototype(InstructionPrototype prototype)
 {
     if (prototype is CallPrototype)
     {
         var callProto = (CallPrototype)prototype;
         return(callProto.Lookup == MethodLookup.Static &&
                callProto.Callee.Equals(Method));
     }
     else
     {
         return(false);
     }
 }
 /// <inheritdoc/>
 public override bool CanDelayExceptions(InstructionPrototype prototype)
 {
     if (prototype is UnboxPrototype ||
         prototype is GetFieldPointerPrototype ||
         prototype is NewDelegatePrototype)
     {
         return(true);
     }
     else if (prototype is IntrinsicPrototype)
     {
         var intrinsicProto = (IntrinsicPrototype)prototype;
         return(delayableIntrinsics.Contains(intrinsicProto.Name));
     }
     else
     {
         return(false);
     }
 }
Exemplo n.º 6
0
 /// <summary>
 /// Tells if syntactically equivalent instances of a particular prototype
 /// are semantically equivalent.
 /// </summary>
 /// <param name="prototype">A prototype to consider.</param>
 /// <returns>
 /// <c>true</c> if syntactically equivalent instances of
 /// <paramref name="prototype"/> are semantically equivalent;
 /// otherwise, <c>false</c>.
 /// </returns>
 private static bool IsCopyablePrototype(InstructionPrototype prototype)
 {
     if (prototype is IntrinsicPrototype)
     {
         return(IsCopyableIntrinsic((IntrinsicPrototype)prototype));
     }
     else
     {
         return(prototype is ConstantPrototype ||
                prototype is CopyPrototype ||
                prototype is DynamicCastPrototype ||
                prototype is GetFieldPointerPrototype ||
                prototype is GetStaticFieldPointerPrototype ||
                prototype is NewDelegatePrototype ||
                prototype is ReinterpretCastPrototype ||
                prototype is UnboxPrototype);
     }
 }
Exemplo n.º 7
0
        /// <summary>
        /// The default constant instruction evaluation function.
        /// </summary>
        /// <param name="prototype">
        /// The prorotype of the instruction to evaluate.
        /// </param>
        /// <param name="arguments">
        /// A list of arguments to the instruction, all of which
        /// must be constants.
        /// </param>
        /// <returns>
        /// <c>null</c> if the instruction cannot be evaluated; otherwise, the constant
        /// to which the instruction evaluates.
        /// </returns>
        public static Constant EvaluateDefault(
            InstructionPrototype prototype,
            IReadOnlyList <Constant> arguments)
        {
            if (prototype is CopyPrototype ||
                prototype is ReinterpretCastPrototype)
            {
                return(arguments[0]);
            }
            else if (prototype is ConstantPrototype)
            {
                var constProto = (ConstantPrototype)prototype;
                if (constProto.Value is DefaultConstant)
                {
                    // Try to specialize 'default' constants.
                    var intSpec = constProto.ResultType.GetIntegerSpecOrNull();
                    if (intSpec != null)
                    {
                        return(new IntegerConstant(0, intSpec));
                    }
                }
                return(constProto.Value);
            }
            else if (prototype is IntrinsicPrototype)
            {
                string   arithOp;
                Constant result;

                if (ArithmeticIntrinsics.TryParseArithmeticIntrinsicName(
                        ((IntrinsicPrototype)prototype).Name,
                        out arithOp) &&
                    ArithmeticIntrinsics.TryEvaluate(
                        arithOp,
                        prototype.ResultType,
                        arguments,
                        out result))
                {
                    return(result);
                }
            }
            return(null);
        }
Exemplo n.º 8
0
        private static void MaterializeReduction(
            IReadOnlyList <ValueTag> args,
            InstructionPrototype prototype,
            NamedInstructionBuilder result)
        {
            if (args.Count == 1)
            {
                result.Instruction = Instruction.CreateCopy(result.ResultType, args[0]);
                return;
            }

            var accumulator = args[0];

            for (int i = 1; i < args.Count - 1; i++)
            {
                accumulator = result.InsertBefore(
                    prototype.Instantiate(new[] { accumulator, args[i] }));
            }
            result.Instruction = prototype.Instantiate(new[] { accumulator, args[args.Count - 1] });
        }
Exemplo n.º 9
0
        public TSpec GetSpecification(InstructionPrototype prototype)
        {
            if (prototype is IntrinsicPrototype)
            {
                var intrinsic = (IntrinsicPrototype)prototype;
                Func <IntrinsicPrototype, TSpec> getIntrinsicSpec;
                if (intrinsicSpecs.TryGetValue(intrinsic.Name, out getIntrinsicSpec))
                {
                    return(getIntrinsicSpec(intrinsic));
                }
            }

            Func <InstructionPrototype, TSpec> getInstructionSpec;

            if (instructionSpecs.TryGetValue(prototype.GetType(), out getInstructionSpec))
            {
                return(getInstructionSpec(prototype));
            }

            return(DefaultSpec);
        }
        /// <inheritdoc/>
        public override ExceptionSpecification GetExceptionSpecification(InstructionPrototype prototype)
        {
            if (prototype is IntrinsicPrototype)
            {
                var intrinsic = (IntrinsicPrototype)prototype;
                Func <IntrinsicPrototype, ExceptionSpecification> getIntrinsicSpec;
                if (intrinsicSpecs.TryGetValue(intrinsic.Name, out getIntrinsicSpec))
                {
                    return(getIntrinsicSpec(intrinsic));
                }
            }

            Func <InstructionPrototype, ExceptionSpecification> getInstructionSpec;

            if (instructionSpecs.TryGetValue(prototype.GetType(), out getInstructionSpec))
            {
                return(getInstructionSpec(prototype));
            }

            return(ExceptionSpecification.ThrowAny);
        }
Exemplo n.º 11
0
        private static bool IsDereferenceable(InstructionPrototype prototype)
        {
            // * Allocas always produce non-null pointers that
            //   are dereferenceable.
            //
            // * Unbox instructions that succeed always produce
            //   non-null pointers that are dereferenceable. If
            //   they don't succeed, then an exception is thrown
            //   and the result can't be used.
            //
            // * Get-field-pointer instructions that succeed
            //   always produce non-null pointers that are
            //   dereferenceable. If they don't succeed, then
            //   an exception is thrown and the result can't be used.
            //
            // * Ditto for get-static-field-pointer instructions.

            return(prototype is AllocaPrototype ||
                   prototype is UnboxPrototype ||
                   prototype is GetFieldPointerPrototype ||
                   prototype is GetStaticFieldPointerPrototype ||
                   prototype is NewObjectPrototype);
        }
Exemplo n.º 12
0
        private static NamedInstructionBuilder ConstantFold(
            ValueTag first,
            ValueTag second,
            InstructionPrototype prototype,
            NamedInstructionBuilder insertionPoint)
        {
            var      graph = insertionPoint.Graph;
            Constant firstConstant;
            Constant secondConstant;

            if (IsConstant(first, insertionPoint.Graph.ToImmutable(), out firstConstant) &&
                IsConstant(second, insertionPoint.Graph.ToImmutable(), out secondConstant))
            {
                var newConstant = ConstantPropagation.EvaluateDefault(
                    prototype,
                    new[] { firstConstant, secondConstant });
                if (newConstant != null)
                {
                    return(insertionPoint.InsertBefore(
                               Instruction.CreateConstant(newConstant, prototype.ResultType)));
                }
            }
            return(null);
        }
Exemplo n.º 13
0
 private static void ToReductionList(
     NamedInstruction instruction,
     InstructionPrototype prototype,
     List <ValueTag> reductionArgs,
     HashSet <ValueTag> reductionOps,
     ValueUses uses)
 {
     if (uses.GetUseCount(instruction) == 1 &&
         instruction.Prototype == prototype)
     {
         ToReductionList(
             instruction.Instruction.Arguments,
             prototype,
             reductionArgs,
             reductionOps,
             uses,
             instruction.Block.Graph);
         reductionOps.Add(instruction);
     }
     else
     {
         reductionArgs.Add(instruction);
     }
 }
Exemplo n.º 14
0
 internal static bool IsDereferenceableOrNull(InstructionPrototype prototype)
 {
     return(IsDereferenceable(prototype));
 }
Exemplo n.º 15
0
 public static void Add(this IList <Instruction> source, InstructionPrototype prototype, int[] args = null)
 {
     source.Add(new Instruction(prototype, args));
 }
Exemplo n.º 16
0
 /// <summary>
 /// Tests if an instruction prototype is a intrinsic prototype
 /// defined in the current namespace.
 /// </summary>
 /// <param name="prototype">
 /// The prototype to examine.
 /// </param>
 /// <returns>
 /// <c>true</c> if the prototype is a namespaced intrinsic prototype;
 /// otherwise, <c>false</c>.
 /// </returns>
 public bool IsIntrinsicPrototype(InstructionPrototype prototype)
 {
     return(prototype is IntrinsicPrototype &&
            IsIntrinsicName(((IntrinsicPrototype)prototype).Name));
 }
Exemplo n.º 17
0
 /// <summary>
 /// Gets the memory access specification for a particular instruction
 /// prototype.
 /// </summary>
 /// <param name="prototype">The prototype to examine.</param>
 /// <returns>A memory specification for <paramref name="prototype"/>.</returns>
 public abstract MemorySpecification GetMemorySpecification(InstructionPrototype prototype);
Exemplo n.º 18
0
 /// <summary>
 /// Tells if it is permissible to delay exceptions thrown by a
 /// particular instruction until the instruction's result is used
 /// by an effectful instruction.
 /// If the instruction's result is never used that way,
 /// the exception may even be deleted altogether.
 /// </summary>
 /// <param name="prototype">
 /// An instruction prototype to examine.
 /// </param>
 /// <returns>
 /// <c>true</c> if exceptions thrown by instances of <paramref name="prototype"/>
 /// may be delayed until the instances' values are used by effectful instructions;
 /// otherwise, <c>false</c>.
 /// </returns>
 public abstract bool CanDelayExceptions(InstructionPrototype prototype);
Exemplo n.º 19
0
 /// <inheritdoc/>
 public override MemorySpecification GetMemorySpecification(InstructionPrototype prototype)
 {
     return(store.GetSpecification(prototype));
 }
Exemplo n.º 20
0
 /// <inheritdoc/>
 public override bool CanDelayExceptions(InstructionPrototype prototype)
 {
     return(false);
 }
Exemplo n.º 21
0
 /// <summary>
 /// Encodes an instruction prototype.
 /// </summary>
 /// <param name="prototype">The instruction prototype to encode.</param>
 /// <returns>
 /// An encoded instruction prototype.
 /// </returns>
 public LNode Encode(InstructionPrototype prototype)
 {
     return(Codec.Instructions.Encode(prototype, this));
 }
Exemplo n.º 22
0
 private static bool IsJump(InstructionPrototype proto)
 => proto == Jump || proto == JumpIf || proto == Invoke || proto == Return;
Exemplo n.º 23
0
 /// <summary>
 /// Gets the exception specification for a particular instruction
 /// prototype.
 /// </summary>
 /// <param name="prototype">The prototype to examine.</param>
 /// <returns>An exception specification for <paramref name="prototype"/>.</returns>
 public abstract ExceptionSpecification GetExceptionSpecification(InstructionPrototype prototype);
Exemplo n.º 24
0
 private static bool IsLabel(InstructionPrototype proto)
 => proto == Label;
Exemplo n.º 25
0
 /// <inheritdoc/>
 public override ExceptionSpecification GetExceptionSpecification(InstructionPrototype prototype)
 {
     return(store.GetSpecification(prototype));
 }
Exemplo n.º 26
0
 protected Instruction Insn(InstructionPrototype proto, params int[] args)
 => new Instruction(proto, args);