Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(667)

Unified Diff: runtime/vm/flow_graph_compiler.h

Issue 10559035: Implement a simple register allocator that tries to keep instruction results in registers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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)

Powered by Google App Engine
This is Rietveld 408576698