Example #1
0
 /// <summary>
 /// Lowers generic values containing structure types that cannot be rewritten.
 /// </summary>
 private static void Keep(
     SSARewriterContext <FieldRef> context,
     LoweringData _,
     Value value) =>
 DisassembleStructure(
     context,
     value.Type.As <StructureType>(value),
     value);
Example #2
0
 /// <summary>
 /// Keeps structure load operations.
 /// </summary>
 private static void Keep(
     SSARewriterContext <FieldRef> context,
     LoweringData _,
     Load load) =>
 DisassembleStructure(
     context,
     load.Type as StructureType,
     load);
Example #3
0
 /// <summary>
 /// Lowers parameter values containing structure values.
 /// </summary>
 private static void Lower(
     SSARewriterContext <FieldRef> context,
     LoweringData _,
     Parameter value) =>
 DisassembleStructure(
     context,
     value.Type as StructureType,
     value);
Example #4
0
 /// <summary>
 /// Lowers sub-warp shuffles.
 /// </summary>
 private static void Lower(
     SSARewriterContext <FieldRef> context,
     LoweringData _,
     SubWarpShuffle value) =>
 LowerThreadValue <
     SubWarpShuffle,
     LowerThreadIntrinsics.SubWarpShuffleLowering>(
     context,
     value.Type as StructureType,
     value);
Example #5
0
 /// <summary>
 /// Lowers warp shuffles.
 /// </summary>
 private static void Lower(
     SSARewriterContext <FieldRef> context,
     LoweringData _,
     Broadcast value) =>
 LowerThreadValue <
     Broadcast,
     LowerThreadIntrinsics.BroadcastLowering>(
     context,
     value.Type as StructureType,
     value);
Example #6
0
        /// <summary>
        /// Keeps structure store operations.
        /// </summary>
        private static void Keep(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            Store store)
        {
            var newValue = AssembleStructure(
                context,
                store.Value.Type as StructureType,
                store.Value);
            var newStore = context.Builder.CreateStore(
                store.Location,
                store.Target,
                newValue);

            context.ReplaceAndRemove(store, newStore);
        }
Example #7
0
        /// <summary>
        /// Lowers structure values into separate SSA values.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            StructureValue structureValue)
        {
            foreach (var(_, fieldAccess) in structureValue.StructureType)
            {
                // Build the new target value
                var value = structureValue[fieldAccess.Index];

                // Bind the new SSA value
                context.SetValue(
                    context.Block,
                    new FieldRef(structureValue, fieldAccess),
                    value);
            }
        }
Example #8
0
        /// <summary>
        /// Applies the structure lowering transformation.
        /// </summary>
        protected override bool PerformTransformation(Method.Builder builder)
        {
            var ssaBuilder = SSABuilder <FieldRef> .Create(builder);

            var loweredPhis  = new List <LoweredPhi>();
            var loweringData = new LoweringData(loweredPhis);

            bool applied = LowerLoadStores
                ? LoadStoreRewriter.Rewrite(ssaBuilder, loweringData)
                : Rewriter.Rewrite(ssaBuilder, loweringData);

            // Seal all lowered phis
            foreach (var phi in loweredPhis)
            {
                var phiValue = phi.Seal(ssaBuilder);
                phiValue.TryRemoveTrivialPhi(builder);
            }

            return(applied);
        }
Example #9
0
        /// <summary>
        /// Lowers null values into separate SSA values.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            NullValue nullValue)
        {
            foreach (var(fieldType, fieldAccess) in nullValue.Type as StructureType)
            {
                // Build the new target value
                var value = context.Builder.CreateNull(
                    nullValue.Location,
                    fieldType);
                context.MarkConverted(value);

                // Bind the new SSA value
                context.SetValue(
                    context.Block,
                    new FieldRef(nullValue, fieldAccess),
                    value);
            }
        }
Example #10
0
        /// <summary>
        /// Lowers method calls involving structure types.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            MethodCall call)
        {
            // Check for structure arguments that need to be rebuilt
            var newArgs = ImmutableArray.CreateBuilder <ValueReference>(
                call.NumArguments);

            foreach (Value argument in call)
            {
                Value newArgument = argument;
                if (argument.Type is StructureType argumentType)
                {
                    newArgument = AssembleStructure(
                        context,
                        argumentType,
                        argument);
                }
                newArgs.Add(newArgument);
            }

            // Create new call node
            var newCall = context.Builder.CreateCall(
                call.Location,
                call.Target,
                newArgs.MoveToImmutable());

            context.ReplaceAndRemove(call, newCall);

            // Convert the return value
            if (call.Type is StructureType callType)
            {
                DisassembleStructure(
                    context,
                    callType,
                    newCall);
            }
        }
Example #11
0
        /// <summary>
        /// Lowers return terminators returning structure values.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            ReturnTerminator value)
        {
            // Move the block builder to a valid insert position in the source block
            var blockBuilder = context.GetMethodBuilder()[value.BasicBlock];

            blockBuilder.SetupInsertPositionToEnd();

            // Assemble return value
            Value returnValue    = value.ReturnValue;
            var   returnType     = returnValue.Type.As <StructureType>(value);
            var   newReturnValue = AssembleStructure(
                context.SpecializeBuilder(blockBuilder),
                returnType,
                returnValue);

            // Replace return terminator with a new terminator
            context.Builder.Terminator = context.Builder.CreateReturn(
                value.Location,
                newReturnValue);
        }
Example #12
0
        /// <summary>
        /// Lowers return terminators returning structure values.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            ReturnTerminator value)
        {
            Value returnValue = value.ReturnValue;
            var   returnType  = returnValue.Type as StructureType;

            Debug.Assert(returnType != null, "Invalid structure type");

            // Assemble a new structure that can be returned
            var blockBuilder = context.GetMethodBuilder()[value.BasicBlock];

            blockBuilder.SetupInsertPosition(returnValue);

            var newReturnValue = AssembleStructure(
                context.SpecializeBuilder(blockBuilder),
                returnType,
                returnValue);

            // Replace return and remove return value
            returnValue.Replace(newReturnValue);
        }
Example #13
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            SetField setField)
        {
            foreach (var(_, fieldAccess) in setField.Type as StructureType)
            {
                Value value;
                if (setField.FieldSpan.Contains(fieldAccess))
                {
                    // Get value from the source value
                    value = setField.Value;
                    if (value.Type is StructureType)
                    {
                        var getFieldAccess = fieldAccess.Subtract(
                            setField.FieldSpan.Index);
                        value = context.GetValue(
                            context.Block,
                            new FieldRef(value, getFieldAccess));
                    }
                }
                else
                {
                    // Load the currently registered SSA value
                    value = context.GetValue(
                        context.Block,
                        new FieldRef(setField.ObjectValue, fieldAccess));
                }

                // Bind the mapped SSA value
                context.SetValue(
                    context.Block,
                    new FieldRef(setField, fieldAccess),
                    value);
            }
            context.Remove(setField);
        }