Ejemplo n.º 1
0
        /// <summary>
        /// Lowers a thread value.
        /// </summary>
        private static void LowerThreadValue <TValue, TLoweringImplementation>(
            SSARewriterContext <FieldRef> context,
            StructureType structureType,
            TValue value)
            where TValue : ThreadValue
            where TLoweringImplementation :
        LowerThreadIntrinsics.ILoweringImplementation <TValue>
        {
            // We require a single input
            var variable = AssembleStructure(
                context,
                structureType,
                value.Variable);

            // Build a new thread value using the assembled structure
            TLoweringImplementation implementation = default;
            var newValue = implementation.Lower(
                context.Builder,
                value,
                variable).ResolveAs <TValue>();

            // Disassemble the resulting structure value
            DisassembleStructure(context, structureType, newValue);

            // Replace old value with new value
            context.ReplaceAndRemove(value, newValue);
        }
Ejemplo n.º 2
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 callBuilder = context.Builder.CreateCall(call.Location, call.Target);

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

            // Create new call node
            var newCall = callBuilder.Seal();

            context.ReplaceAndRemove(call, newCall);

            // Convert the return value
            if (call.Type is StructureType callType)
            {
                DisassembleStructure(
                    context,
                    callType,
                    newCall);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Lowers get field operations into separate SSA values.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            GetField getField)
        {
            if (getField.Type is StructureType structureType)
            {
                foreach (var(_, fieldAccess) in structureType)
                {
                    // Get the source value
                    var value = context.GetValue(
                        context.Block,
                        new FieldRef(
                            getField.ObjectValue,
                            new FieldSpan(
                                getField.FieldSpan.Index + fieldAccess.Index)));

                    // Bind the mapped SSA value
                    context.SetValue(
                        context.Block,
                        new FieldRef(getField, fieldAccess),
                        value);
                }
                context.Remove(getField);
            }
            else
            {
                var getFieldValue = context.GetValue(
                    context.Block,
                    new FieldRef(getField.ObjectValue, getField.FieldSpan));
                context.ReplaceAndRemove(getField, getFieldValue);
            }
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Converts a load node into an SSA value.
        /// </summary>
        private static void Convert(
            SSARewriterContext <Value> context,
            ConstructionData data,
            Load load)
        {
            if (data.TryGetConverted(load.Source, out var loadRef))
            {
                var ssaValue = context.GetValue(context.Block, loadRef.Source);
                if (!loadRef.IsDirect)
                {
                    ssaValue = context.Builder.CreateGetField(
                        load.Location,
                        ssaValue,
                        loadRef.FieldSpan);
                }

                context.ReplaceAndRemove(load, ssaValue);
            }
            else if (!load.Uses.HasAny)
            {
                context.Remove(load);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Converts a new get length node into an SSA value.
        /// </summary>
        private static void Convert <TConstructionData>(
            SSARewriterContext <Value> context,
            TConstructionData data,
            GetViewLength getViewLength)
            where TConstructionData : IConstructionData
        {
            if (!data.TryGetConverted(getViewLength.View, out var getRef))
            {
                return;
            }

            // Get the SSA structure value
            var ssaValue = context.GetValue(context.Block, getRef.Source);

            // Get the view length from the first field (index 0) of the wrapped
            // array structure
            ssaValue = context.Builder.CreateGetField(
                getViewLength.Location,
                ssaValue,
                new FieldSpan(new FieldAccess(0)));

            context.ReplaceAndRemove(getViewLength, ssaValue);
        }