1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29 #include "lithium.h"
30
31 namespace v8 {
32 namespace internal {
33
34
PrintTo(StringStream * stream)35 void LOperand::PrintTo(StringStream* stream) {
36 LUnallocated* unalloc = NULL;
37 switch (kind()) {
38 case INVALID:
39 break;
40 case UNALLOCATED:
41 unalloc = LUnallocated::cast(this);
42 stream->Add("v%d", unalloc->virtual_register());
43 switch (unalloc->policy()) {
44 case LUnallocated::NONE:
45 break;
46 case LUnallocated::FIXED_REGISTER: {
47 const char* register_name =
48 Register::AllocationIndexToString(unalloc->fixed_index());
49 stream->Add("(=%s)", register_name);
50 break;
51 }
52 case LUnallocated::FIXED_DOUBLE_REGISTER: {
53 const char* double_register_name =
54 DoubleRegister::AllocationIndexToString(unalloc->fixed_index());
55 stream->Add("(=%s)", double_register_name);
56 break;
57 }
58 case LUnallocated::FIXED_SLOT:
59 stream->Add("(=%dS)", unalloc->fixed_index());
60 break;
61 case LUnallocated::MUST_HAVE_REGISTER:
62 stream->Add("(R)");
63 break;
64 case LUnallocated::WRITABLE_REGISTER:
65 stream->Add("(WR)");
66 break;
67 case LUnallocated::SAME_AS_FIRST_INPUT:
68 stream->Add("(1)");
69 break;
70 case LUnallocated::ANY:
71 stream->Add("(-)");
72 break;
73 case LUnallocated::IGNORE:
74 stream->Add("(0)");
75 break;
76 }
77 break;
78 case CONSTANT_OPERAND:
79 stream->Add("[constant:%d]", index());
80 break;
81 case STACK_SLOT:
82 stream->Add("[stack:%d]", index());
83 break;
84 case DOUBLE_STACK_SLOT:
85 stream->Add("[double_stack:%d]", index());
86 break;
87 case REGISTER:
88 stream->Add("[%s|R]", Register::AllocationIndexToString(index()));
89 break;
90 case DOUBLE_REGISTER:
91 stream->Add("[%s|R]", DoubleRegister::AllocationIndexToString(index()));
92 break;
93 case ARGUMENT:
94 stream->Add("[arg:%d]", index());
95 break;
96 }
97 }
98
99
VirtualRegister()100 int LOperand::VirtualRegister() {
101 LUnallocated* unalloc = LUnallocated::cast(this);
102 return unalloc->virtual_register();
103 }
104
105
IsRedundant() const106 bool LParallelMove::IsRedundant() const {
107 for (int i = 0; i < move_operands_.length(); ++i) {
108 if (!move_operands_[i].IsRedundant()) return false;
109 }
110 return true;
111 }
112
113
PrintDataTo(StringStream * stream) const114 void LParallelMove::PrintDataTo(StringStream* stream) const {
115 bool first = true;
116 for (int i = 0; i < move_operands_.length(); ++i) {
117 if (!move_operands_[i].IsEliminated()) {
118 LOperand* source = move_operands_[i].source();
119 LOperand* destination = move_operands_[i].destination();
120 if (!first) stream->Add(" ");
121 first = false;
122 if (source->Equals(destination)) {
123 destination->PrintTo(stream);
124 } else {
125 destination->PrintTo(stream);
126 stream->Add(" = ");
127 source->PrintTo(stream);
128 }
129 stream->Add(";");
130 }
131 }
132 }
133
134
PrintTo(StringStream * stream)135 void LEnvironment::PrintTo(StringStream* stream) {
136 stream->Add("[id=%d|", ast_id());
137 stream->Add("[parameters=%d|", parameter_count());
138 stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
139 for (int i = 0; i < values_.length(); ++i) {
140 if (i != 0) stream->Add(";");
141 if (values_[i] == NULL) {
142 stream->Add("[hole]");
143 } else {
144 values_[i]->PrintTo(stream);
145 }
146 }
147 stream->Add("]");
148 }
149
150
RecordPointer(LOperand * op)151 void LPointerMap::RecordPointer(LOperand* op) {
152 // Do not record arguments as pointers.
153 if (op->IsStackSlot() && op->index() < 0) return;
154 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
155 pointer_operands_.Add(op);
156 }
157
158
PrintTo(StringStream * stream)159 void LPointerMap::PrintTo(StringStream* stream) {
160 stream->Add("{");
161 for (int i = 0; i < pointer_operands_.length(); ++i) {
162 if (i != 0) stream->Add(";");
163 pointer_operands_[i]->PrintTo(stream);
164 }
165 stream->Add("} @%d", position());
166 }
167
168
169 } } // namespace v8::internal
170