Chromium Code Reviews| Index: runtime/vm/flow_graph_compiler.h |
| diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h |
| index 57208fb20ff272eddb58057e65cb7b347984823e..83bf50dc4d9d057fcc1a2a2cab29e6272ef68798 100644 |
| --- a/runtime/vm/flow_graph_compiler.h |
| +++ b/runtime/vm/flow_graph_compiler.h |
| @@ -5,6 +5,97 @@ |
| #ifndef VM_FLOW_GRAPH_COMPILER_H_ |
| #define VM_FLOW_GRAPH_COMPILER_H_ |
| +#include "vm/allocation.h" |
| +#include "vm/assembler.h" |
| +#include "vm/assembler_macros.h" |
| +#include "vm/code_descriptors.h" |
| +#include "vm/code_generator.h" |
| +#include "vm/intermediate_language.h" |
| + |
| +namespace dart { |
| + |
| +// Forward declarations. |
| +class FlowGraphCompiler; |
| +class DeoptimizationStub; |
| + |
| + |
| +// FrameRegisterAllocator is a simple local register allocator that tries to |
| +// keep values in registers by delaying pushing them to the stack after they |
| +// were produced by Bind instruction. FrameRegisterAllocator relies on the |
| +// fact that IR is stack based and a value produced by a bind instruction |
| +// will be used only once. For the register allocator every Bind is a push and |
| +// every UseVal of a bind is a pop. |
| +// It can also operate in a non-optimizing mode when every value is pushed |
| +// to the stack immediately after it is produced. |
| +// TODO(vegorov): replace with a linear scan register allocator once SSA is |
| +// available. |
| +class FrameRegisterAllocator : public ValueObject { |
| + public: |
| + explicit FrameRegisterAllocator(FlowGraphCompiler* compiler, |
| + bool keep_values_in_registers) |
|
srdjan
2012/06/18 16:33:20
remove explicit
Vyacheslav Egorov (Google)
2012/06/18 17:51:16
Done.
|
| + : compiler_(compiler), |
| + stack_(kNumberOfCpuRegisters), |
| + registers_(), |
| + keep_values_in_registers_(keep_values_in_registers) { |
| + for (int i = 0; i < kNumberOfCpuRegisters; i++) { |
| + registers_[i] = NULL; |
| + } |
| + } |
| + |
| + // Notify register allocator that given instruction produced a value |
| + // in the given register. |
| + void Push(Register reg, Instruction* val); |
| + |
| + // Perform a greedy local register allocation. Consider all register free. |
| + void AllocateRegisters(Instruction* instr); |
| + |
| + // Spill all live registers to the stack in order from oldest to newest. |
| + void Spill(); |
| + |
| + // Returns true if all live values are stored on the stack. |
| + // Code generator expects no live values in registers at call sites and |
| + // branches. |
| + bool IsSpilled() const { return stack_.length() == 0; } |
| + |
| + // Popuplate deoptimization stub with live registers to ensure |
| + // that they will be pushed to the stack when deoptimization happens. |
| + void SpillInDeoptStub(DeoptimizationStub* stub); |
| + |
| + private: |
| + // Pop a value from the place where it is currently stored (either register |
| + // or top of the stack) into a given register. If value is in the register |
| + // verify that passed use corresponds to the instruction that produced the |
| + // value. |
| + void Pop(Register reg, Value* use); |
| + |
| + // Allocate a register that is not explicitly blocked. |
| + // Spills a value if all non-blocked registers contain values. |
| + Register AllocateFreeRegister(bool* blocked_registers); |
| + |
| + // Ensure that given register is free for allocation. |
| + void SpillRegister(Register reg); |
| + |
| + // Spill the oldest live value from register to the stack. |
| + Register SpillFirst(); |
| + |
| + FlowGraphCompiler* compiler() { return compiler_; } |
| + |
| + FlowGraphCompiler* compiler_; |
| + |
| + // List of registers with live values in order from oldest to newest. |
| + GrowableArray<Register> stack_; |
| + |
| + // Mapping between live registers and instructions that produced values |
| + // in them. Contains NULL for registers do not have corresponding live value. |
| + Instruction* registers_[kNumberOfCpuRegisters]; |
|
srdjan
2012/06/18 16:33:20
Consider renaming registers_to_instructions_, or j
Florian Schneider
2012/06/18 16:50:55
Can it even be BindInstr*?
Vyacheslav Egorov (Google)
2012/06/18 17:51:16
Done.
Vyacheslav Egorov (Google)
2012/06/18 17:51:16
I am not sure instructions_ reflects the purpose:
|
| + |
| + bool keep_values_in_registers_; |
|
srdjan
2012/06/18 16:33:20
const?
Vyacheslav Egorov (Google)
2012/06/18 17:51:16
Done.
Vyacheslav Egorov (Google)
2012/06/18 17:51:16
Done.
|
| + |
| + DISALLOW_COPY_AND_ASSIGN(FrameRegisterAllocator); |
| +}; |
| + |
| +} // namespace dart |
| + |
| #if defined(TARGET_ARCH_IA32) |
| #include "vm/flow_graph_compiler_ia32.h" |
| #elif defined(TARGET_ARCH_X64) |