Ejemplo n.º 1
0
        public void Allocate(BasicBlock <IRInstrList> block)
        {
            var blockLiveness = liveness[block];
            var instrLiveness = LivenessAnalysis.ComputeLiveness(block, blockLiveness);
            var pool          = RegisterPool.Create(baseOffset, globalVars);

            for (var i = 0; i < block.Content.Count; i++)
            {
                var instr = block.Content[i];
                pool.CheckLiveness(instrLiveness[instr]);

                // Allocates
                if (instr.Operand1 != null)
                {
                    instr.Operand1 = AllocateOperand(instr.Operand1, pool);
                }
                if (instr.Operand2 != null)
                {
                    instr.Operand2 = AllocateOperand(instr.Operand2, pool);
                }
            }
            if (pool.SpillOffset - 1 > LocalSize)
            {
                LocalSize = pool.SpillOffset - 1;
            }
            baseOffset = pool.SpillOffset;
        }
Ejemplo n.º 2
0
        public void Initialize()
        {
            var blocks = transformer.RootScope.GetBasicBlocks().Cast <BasicBlock <IRInstrList> >().ToList();

            liveness = LivenessAnalysis.ComputeLiveness(blocks);

            var stackVars = new HashSet <IRVariable>();

            foreach (var blockLiveness in liveness)
            {
                foreach (var instr in blockLiveness.Key.Content)
                {
                    if (instr.OpCode != IROpCode.__LEA)
                    {
                        continue;
                    }

                    var variable = (IRVariable)instr.Operand2;
                    if (variable.VariableType != IRVariableType.Argument)
                    {
                        stackVars.Add(variable);
                    }
                }
                stackVars.UnionWith(blockLiveness.Value.OutLive);
            }

            // [BP - 2] = last argument
            // [BP - 1] = return address
            // [BP    ] = old BP
            // [BP + 1] = first local

            var offset = 1;

            globalVars = stackVars.ToDictionary(var => var, var => new StackSlot(offset++, var));
            baseOffset = offset;
            LocalSize  = baseOffset - 1;

            offset = -2;
            var parameters = transformer.Context.GetParameters();

            for (var i = parameters.Length - 1; i >= 0; i--)
            {
                var paramVar = parameters[i];
                globalVars[paramVar] = new StackSlot(offset--, paramVar);
            }

            allocation = globalVars.ToDictionary(pair => pair.Key, pair => (object)pair.Value);
        }