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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_FLOW_GRAPH_COMPILER_H_ 5 #ifndef VM_FLOW_GRAPH_COMPILER_H_
6 #define VM_FLOW_GRAPH_COMPILER_H_ 6 #define VM_FLOW_GRAPH_COMPILER_H_
7 7
8 #include "vm/allocation.h"
9 #include "vm/assembler.h"
10 #include "vm/assembler_macros.h"
11 #include "vm/code_descriptors.h"
12 #include "vm/code_generator.h"
13 #include "vm/intermediate_language.h"
14
15 namespace dart {
16
17 // Forward declarations.
18 class FlowGraphCompiler;
19 class DeoptimizationStub;
20
21
22 // FrameRegisterAllocator is a simple local register allocator that tries to
23 // keep values in registers by delaying pushing them to the stack after they
24 // were produced by Bind instruction. FrameRegisterAllocator relies on the
25 // fact that IR is stack based and a value produced by a bind instruction
26 // will be used only once. For the register allocator every Bind is a push and
27 // every UseVal of a bind is a pop.
28 // It can also operate in a non-optimizing mode when every value is pushed
29 // to the stack immediately after it is produced.
30 // TODO(vegorov): replace with a linear scan register allocator once SSA is
31 // available.
32 class FrameRegisterAllocator : public ValueObject {
33 public:
34 explicit FrameRegisterAllocator(FlowGraphCompiler* compiler,
35 bool keep_values_in_registers)
srdjan 2012/06/18 16:33:20 remove explicit
Vyacheslav Egorov (Google) 2012/06/18 17:51:16 Done.
36 : compiler_(compiler),
37 stack_(kNumberOfCpuRegisters),
38 registers_(),
39 keep_values_in_registers_(keep_values_in_registers) {
40 for (int i = 0; i < kNumberOfCpuRegisters; i++) {
41 registers_[i] = NULL;
42 }
43 }
44
45 // Notify register allocator that given instruction produced a value
46 // in the given register.
47 void Push(Register reg, Instruction* val);
48
49 // Perform a greedy local register allocation. Consider all register free.
50 void AllocateRegisters(Instruction* instr);
51
52 // Spill all live registers to the stack in order from oldest to newest.
53 void Spill();
54
55 // Returns true if all live values are stored on the stack.
56 // Code generator expects no live values in registers at call sites and
57 // branches.
58 bool IsSpilled() const { return stack_.length() == 0; }
59
60 // Popuplate deoptimization stub with live registers to ensure
61 // that they will be pushed to the stack when deoptimization happens.
62 void SpillInDeoptStub(DeoptimizationStub* stub);
63
64 private:
65 // Pop a value from the place where it is currently stored (either register
66 // or top of the stack) into a given register. If value is in the register
67 // verify that passed use corresponds to the instruction that produced the
68 // value.
69 void Pop(Register reg, Value* use);
70
71 // Allocate a register that is not explicitly blocked.
72 // Spills a value if all non-blocked registers contain values.
73 Register AllocateFreeRegister(bool* blocked_registers);
74
75 // Ensure that given register is free for allocation.
76 void SpillRegister(Register reg);
77
78 // Spill the oldest live value from register to the stack.
79 Register SpillFirst();
80
81 FlowGraphCompiler* compiler() { return compiler_; }
82
83 FlowGraphCompiler* compiler_;
84
85 // List of registers with live values in order from oldest to newest.
86 GrowableArray<Register> stack_;
87
88 // Mapping between live registers and instructions that produced values
89 // in them. Contains NULL for registers do not have corresponding live value.
90 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:
91
92 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.
93
94 DISALLOW_COPY_AND_ASSIGN(FrameRegisterAllocator);
95 };
96
97 } // namespace dart
98
8 #if defined(TARGET_ARCH_IA32) 99 #if defined(TARGET_ARCH_IA32)
9 #include "vm/flow_graph_compiler_ia32.h" 100 #include "vm/flow_graph_compiler_ia32.h"
10 #elif defined(TARGET_ARCH_X64) 101 #elif defined(TARGET_ARCH_X64)
11 #include "vm/flow_graph_compiler_x64.h" 102 #include "vm/flow_graph_compiler_x64.h"
12 #elif defined(TARGET_ARCH_ARM) 103 #elif defined(TARGET_ARCH_ARM)
13 #include "vm/flow_graph_compiler_arm.h" 104 #include "vm/flow_graph_compiler_arm.h"
14 #else 105 #else
15 #error Unknown architecture. 106 #error Unknown architecture.
16 #endif 107 #endif
17 108
18 #endif // VM_FLOW_GRAPH_COMPILER_H_ 109 #endif // VM_FLOW_GRAPH_COMPILER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698