Beispiel #1
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);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Lowers structure load operations into distinct loads for each field.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData _,
            Load load)
        {
            var builder = context.Builder;

            foreach (var(_, fieldAccess) in load.Type as StructureType)
            {
                // Update source address
                var address = builder.CreateLoadFieldAddress(
                    load.Location,
                    load.Source,
                    new FieldSpan(fieldAccess));

                // Load value and store its reference in the current block
                var loweredLoad = builder.CreateLoad(load.Location, address);
                context.SetValue(
                    context.Block,
                    new FieldRef(load, fieldAccess),
                    loweredLoad);
                context.MarkConverted(loweredLoad);
            }
            context.Remove(load);
        }
Beispiel #3
0
        /// <summary>
        /// Lowers phi values.
        /// </summary>
        private static void Lower(
            SSARewriterContext <FieldRef> context,
            LoweringData data,
            PhiValue phi)
        {
            foreach (var(fieldType, fieldAccess) in phi.Type as StructureType)
            {
                // Build a new phi which might become dead in the future
                var phiBuilder = context.Builder.CreatePhi(
                    phi.Location,
                    fieldType);

                // Register the lowered phi
                data.AddPhi(new LoweredPhi(
                                phi,
                                fieldAccess,
                                phiBuilder));

                // Bind the new phi value
                context.SetValue(
                    context.Block,
                    new FieldRef(phi, fieldAccess),
                    phiBuilder.PhiValue);
            }
            context.Remove(phi);
        }
Beispiel #4
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);
            }
        }
Beispiel #5
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);
        }
Beispiel #6
0
        protected static void ConvertAlloca <TConstructionData>(
            SSARewriterContext <Value> context,
            TConstructionData data,
            Alloca alloca,
            Value initValue)
            where TConstructionData : IConstructionData
        {
            alloca.Assert(data.ContainsAlloca(alloca));

            // Bind the init value and remove the allocation from the block
            context.SetValue(context.Block, alloca, initValue);
            data.AddConverted(alloca, new FieldRef(alloca));
            context.Remove(alloca);
        }
Beispiel #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);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Converts an alloca node to its initial SSA value.
        /// </summary>
        private static void Convert(
            SSARewriterContext <Value> context,
            ConstructionData data,
            Alloca alloca)
        {
            if (!data.ContainsAlloca(alloca))
            {
                return;
            }

            var initValue = context.Builder.CreateNull(
                alloca.Location,
                alloca.AllocaType);

            context.SetValue(context.Block, alloca, initValue);

            data.AddConverted(alloca, new FieldRef(alloca));
            context.Remove(alloca);
        }
Beispiel #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);
            }
        }
Beispiel #10
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);
        }