Пример #1
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);
            }
        }
Пример #2
0
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            Predicate predicate)
        {
            foreach (var(_, fieldAccess) in predicate.Type as StructureType)
            {
                // Build a new if predicate which might become dead in the future
                var trueValue = context.GetValue(
                    context.Block,
                    new FieldRef(predicate.TrueValue, fieldAccess));
                var falseValue = context.GetValue(
                    context.Block,
                    new FieldRef(predicate.FalseValue, fieldAccess));
                var newPredicate = context.Builder.CreatePredicate(
                    predicate.Location,
                    predicate.Condition,
                    trueValue,
                    falseValue);

                // Bind the new if predicate
                context.SetValue(
                    context.Block,
                    new FieldRef(predicate, fieldAccess),
                    newPredicate);
            }
        }
Пример #3
0
        /// <summary>
        /// Lowers structure store operations into distinct stores for each field.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            Store store)
        {
            var builder = context.Builder;

            foreach (var(_, fieldAccess) in store.Value.Type as StructureType)
            {
                // Update target address
                var address = builder.CreateLoadFieldAddress(
                    store.Location,
                    store.Target,
                    new FieldSpan(fieldAccess));

                // Load the currently registered SSA value and store it
                var value = context.GetValue(
                    context.Block,
                    new FieldRef(store.Value, fieldAccess));
                var loweredStore = builder.CreateStore(
                    store.Location,
                    address,
                    value);
                context.MarkConverted(loweredStore);
            }
            context.Remove(store);
        }
Пример #4
0
        /// <summary>
        /// Converts a store node into an SSA value.
        /// </summary>
        private static void Convert(
            SSARewriterContext <Value> context,
            ConstructionData data,
            Store store)
        {
            if (!data.TryGetConverted(store.Target, out var storeRef))
            {
                return;
            }

            Value ssaValue = store.Value;

            if (!storeRef.IsDirect)
            {
                ssaValue = context.GetValue(context.Block, storeRef.Source);
                ssaValue = context.Builder.CreateSetField(
                    store.Location,
                    ssaValue,
                    storeRef.FieldSpan,
                    store.Value);
            }

            context.SetValue(context.Block, storeRef.Source, ssaValue);
            context.Remove(store);
        }
Пример #5
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);
        }
Пример #6
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);
            }
        }
Пример #7
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);
        }