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

Side by Side Diff: src/compiler/arm/code-generator-arm.cc

Issue 1242303005: [turbofan]: Elide extra move when accessing stack or frame register (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: src/compiler/code-generator.cc Created 5 years, 5 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
« no previous file with comments | « src/arm64/interface-descriptors-arm64.cc ('k') | src/compiler/arm64/code-generator-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/arm/macro-assembler-arm.h" 7 #include "src/arm/macro-assembler-arm.h"
8 #include "src/compiler/code-generator-impl.h" 8 #include "src/compiler/code-generator-impl.h"
9 #include "src/compiler/gap-resolver.h" 9 #include "src/compiler/gap-resolver.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 UNREACHABLE(); 140 UNREACHABLE();
141 return MemOperand(r0); 141 return MemOperand(r0);
142 } 142 }
143 143
144 MemOperand InputOffset(size_t first_index = 0) { 144 MemOperand InputOffset(size_t first_index = 0) {
145 return InputOffset(&first_index); 145 return InputOffset(&first_index);
146 } 146 }
147 147
148 MemOperand ToMemOperand(InstructionOperand* op) const { 148 MemOperand ToMemOperand(InstructionOperand* op) const {
149 DCHECK(op != NULL); 149 DCHECK(op != NULL);
150 DCHECK(!op->IsRegister()); 150 DCHECK(!op->GeneratesRegister());
151 DCHECK(!op->IsDoubleRegister()); 151 DCHECK(!op->IsDoubleRegister());
152 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 152 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
153 // The linkage computes where all spill slots are located. 153 // The linkage computes where all spill slots are located.
154 FrameOffset offset = linkage()->GetFrameOffset( 154 FrameOffset offset = linkage()->GetFrameOffset(
155 AllocatedOperand::cast(op)->index(), frame(), 0); 155 AllocatedOperand::cast(op)->index(), frame(), 0);
156 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); 156 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
157 } 157 }
158 }; 158 };
159 159
160 160
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 return kNoCondition; 234 return kNoCondition;
235 } 235 }
236 236
237 } // namespace 237 } // namespace
238 238
239 239
240 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ 240 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \
241 do { \ 241 do { \
242 auto result = i.OutputFloat##width##Register(); \ 242 auto result = i.OutputFloat##width##Register(); \
243 auto offset = i.InputRegister(0); \ 243 auto offset = i.InputRegister(0); \
244 if (instr->InputAt(1)->IsRegister()) { \ 244 if (instr->InputAt(1)->GeneratesRegister()) { \
245 __ cmp(offset, i.InputRegister(1)); \ 245 __ cmp(offset, i.InputRegister(1)); \
246 } else { \ 246 } else { \
247 __ cmp(offset, i.InputImmediate(1)); \ 247 __ cmp(offset, i.InputImmediate(1)); \
248 } \ 248 } \
249 auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \ 249 auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \
250 __ b(hs, ool->entry()); \ 250 __ b(hs, ool->entry()); \
251 __ vldr(result, i.InputOffset(2)); \ 251 __ vldr(result, i.InputOffset(2)); \
252 __ bind(ool->exit()); \ 252 __ bind(ool->exit()); \
253 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ 253 DCHECK_EQ(LeaveCC, i.OutputSBit()); \
254 } while (0) 254 } while (0)
255 255
256 256
257 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ 257 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
258 do { \ 258 do { \
259 auto result = i.OutputRegister(); \ 259 auto result = i.OutputRegister(); \
260 auto offset = i.InputRegister(0); \ 260 auto offset = i.InputRegister(0); \
261 if (instr->InputAt(1)->IsRegister()) { \ 261 if (instr->InputAt(1)->GeneratesRegister()) { \
262 __ cmp(offset, i.InputRegister(1)); \ 262 __ cmp(offset, i.InputRegister(1)); \
263 } else { \ 263 } else { \
264 __ cmp(offset, i.InputImmediate(1)); \ 264 __ cmp(offset, i.InputImmediate(1)); \
265 } \ 265 } \
266 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ 266 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
267 __ b(hs, ool->entry()); \ 267 __ b(hs, ool->entry()); \
268 __ asm_instr(result, i.InputOffset(2)); \ 268 __ asm_instr(result, i.InputOffset(2)); \
269 __ bind(ool->exit()); \ 269 __ bind(ool->exit()); \
270 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ 270 DCHECK_EQ(LeaveCC, i.OutputSBit()); \
271 } while (0) 271 } while (0)
272 272
273 273
274 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \ 274 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \
275 do { \ 275 do { \
276 auto offset = i.InputRegister(0); \ 276 auto offset = i.InputRegister(0); \
277 if (instr->InputAt(1)->IsRegister()) { \ 277 if (instr->InputAt(1)->GeneratesRegister()) { \
278 __ cmp(offset, i.InputRegister(1)); \ 278 __ cmp(offset, i.InputRegister(1)); \
279 } else { \ 279 } else { \
280 __ cmp(offset, i.InputImmediate(1)); \ 280 __ cmp(offset, i.InputImmediate(1)); \
281 } \ 281 } \
282 auto value = i.InputFloat##width##Register(2); \ 282 auto value = i.InputFloat##width##Register(2); \
283 __ vstr(value, i.InputOffset(3), lo); \ 283 __ vstr(value, i.InputOffset(3), lo); \
284 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ 284 DCHECK_EQ(LeaveCC, i.OutputSBit()); \
285 } while (0) 285 } while (0)
286 286
287 287
288 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ 288 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
289 do { \ 289 do { \
290 auto offset = i.InputRegister(0); \ 290 auto offset = i.InputRegister(0); \
291 if (instr->InputAt(1)->IsRegister()) { \ 291 if (instr->InputAt(1)->GeneratesRegister()) { \
292 __ cmp(offset, i.InputRegister(1)); \ 292 __ cmp(offset, i.InputRegister(1)); \
293 } else { \ 293 } else { \
294 __ cmp(offset, i.InputImmediate(1)); \ 294 __ cmp(offset, i.InputImmediate(1)); \
295 } \ 295 } \
296 auto value = i.InputRegister(2); \ 296 auto value = i.InputRegister(2); \
297 __ asm_instr(value, i.InputOffset(3), lo); \ 297 __ asm_instr(value, i.InputOffset(3), lo); \
298 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ 298 DCHECK_EQ(LeaveCC, i.OutputSBit()); \
299 } while (0) 299 } while (0)
300 300
301 301
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 __ Ret(); 1063 __ Ret();
1064 } 1064 }
1065 } 1065 }
1066 1066
1067 1067
1068 void CodeGenerator::AssembleMove(InstructionOperand* source, 1068 void CodeGenerator::AssembleMove(InstructionOperand* source,
1069 InstructionOperand* destination) { 1069 InstructionOperand* destination) {
1070 ArmOperandConverter g(this, NULL); 1070 ArmOperandConverter g(this, NULL);
1071 // Dispatch on the source and destination operand kinds. Not all 1071 // Dispatch on the source and destination operand kinds. Not all
1072 // combinations are possible. 1072 // combinations are possible.
1073 if (source->IsRegister()) { 1073 if (source->GeneratesRegister()) {
1074 DCHECK(destination->IsRegister() || destination->IsStackSlot()); 1074 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot());
1075 Register src = g.ToRegister(source); 1075 Register src = g.ToRegister(source);
1076 if (destination->IsRegister()) { 1076 if (destination->GeneratesRegister()) {
1077 __ mov(g.ToRegister(destination), src); 1077 __ mov(g.ToRegister(destination), src);
1078 } else { 1078 } else {
1079 __ str(src, g.ToMemOperand(destination)); 1079 __ str(src, g.ToMemOperand(destination));
1080 } 1080 }
1081 } else if (source->IsStackSlot()) { 1081 } else if (source->IsStackSlot()) {
1082 DCHECK(destination->IsRegister() || destination->IsStackSlot()); 1082 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot());
1083 MemOperand src = g.ToMemOperand(source); 1083 MemOperand src = g.ToMemOperand(source);
1084 if (destination->IsRegister()) { 1084 if (destination->GeneratesRegister()) {
1085 __ ldr(g.ToRegister(destination), src); 1085 __ ldr(g.ToRegister(destination), src);
1086 } else { 1086 } else {
1087 Register temp = kScratchReg; 1087 Register temp = kScratchReg;
1088 __ ldr(temp, src); 1088 __ ldr(temp, src);
1089 __ str(temp, g.ToMemOperand(destination)); 1089 __ str(temp, g.ToMemOperand(destination));
1090 } 1090 }
1091 } else if (source->IsConstant()) { 1091 } else if (source->IsConstant()) {
1092 Constant src = g.ToConstant(source); 1092 Constant src = g.ToConstant(source);
1093 if (destination->IsRegister() || destination->IsStackSlot()) { 1093 if (destination->GeneratesRegister() || destination->IsStackSlot()) {
1094 Register dst = 1094 Register dst = destination->GeneratesRegister()
1095 destination->IsRegister() ? g.ToRegister(destination) : kScratchReg; 1095 ? g.ToRegister(destination)
1096 : kScratchReg;
1096 switch (src.type()) { 1097 switch (src.type()) {
1097 case Constant::kInt32: 1098 case Constant::kInt32:
1098 __ mov(dst, Operand(src.ToInt32())); 1099 __ mov(dst, Operand(src.ToInt32()));
1099 break; 1100 break;
1100 case Constant::kInt64: 1101 case Constant::kInt64:
1101 UNREACHABLE(); 1102 UNREACHABLE();
1102 break; 1103 break;
1103 case Constant::kFloat32: 1104 case Constant::kFloat32:
1104 __ Move(dst, 1105 __ Move(dst,
1105 isolate()->factory()->NewNumber(src.ToFloat32(), TENURED)); 1106 isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 UNREACHABLE(); 1172 UNREACHABLE();
1172 } 1173 }
1173 } 1174 }
1174 1175
1175 1176
1176 void CodeGenerator::AssembleSwap(InstructionOperand* source, 1177 void CodeGenerator::AssembleSwap(InstructionOperand* source,
1177 InstructionOperand* destination) { 1178 InstructionOperand* destination) {
1178 ArmOperandConverter g(this, NULL); 1179 ArmOperandConverter g(this, NULL);
1179 // Dispatch on the source and destination operand kinds. Not all 1180 // Dispatch on the source and destination operand kinds. Not all
1180 // combinations are possible. 1181 // combinations are possible.
1181 if (source->IsRegister()) { 1182 if (source->GeneratesRegister()) {
1182 // Register-register. 1183 // Register-register.
1183 Register temp = kScratchReg; 1184 Register temp = kScratchReg;
1184 Register src = g.ToRegister(source); 1185 Register src = g.ToRegister(source);
1185 if (destination->IsRegister()) { 1186 if (destination->GeneratesRegister()) {
1186 Register dst = g.ToRegister(destination); 1187 Register dst = g.ToRegister(destination);
1187 __ Move(temp, src); 1188 __ Move(temp, src);
1188 __ Move(src, dst); 1189 __ Move(src, dst);
1189 __ Move(dst, temp); 1190 __ Move(dst, temp);
1190 } else { 1191 } else {
1191 DCHECK(destination->IsStackSlot()); 1192 DCHECK(destination->IsStackSlot());
1192 MemOperand dst = g.ToMemOperand(destination); 1193 MemOperand dst = g.ToMemOperand(destination);
1193 __ mov(temp, src); 1194 __ mov(temp, src);
1194 __ ldr(src, dst); 1195 __ ldr(src, dst);
1195 __ str(temp, dst); 1196 __ str(temp, dst);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 } 1269 }
1269 } 1270 }
1270 } 1271 }
1271 } 1272 }
1272 1273
1273 #undef __ 1274 #undef __
1274 1275
1275 } // namespace compiler 1276 } // namespace compiler
1276 } // namespace internal 1277 } // namespace internal
1277 } // namespace v8 1278 } // namespace v8
OLDNEW
« no previous file with comments | « src/arm64/interface-descriptors-arm64.cc ('k') | src/compiler/arm64/code-generator-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698