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; }
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); }