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

Side by Side Diff: src/arm/assembler-arm.cc

Issue 2104006: Push/pop is just one peephole optimization. Puth them all... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 7 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
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/flag-definitions.h » ('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 (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 // ldr rd, [pc, #offset] 263 // ldr rd, [pc, #offset]
264 const Instr kLdrPCMask = CondMask | 15 * B24 | 7 * B20 | 15 * B16; 264 const Instr kLdrPCMask = CondMask | 15 * B24 | 7 * B20 | 15 * B16;
265 const Instr kLdrPCPattern = al | 5 * B24 | L | pc.code() * B16; 265 const Instr kLdrPCPattern = al | 5 * B24 | L | pc.code() * B16;
266 // blxcc rm 266 // blxcc rm
267 const Instr kBlxRegMask = 267 const Instr kBlxRegMask =
268 15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4; 268 15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4;
269 const Instr kBlxRegPattern = 269 const Instr kBlxRegPattern =
270 B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | 3 * B4; 270 B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | 3 * B4;
271 // A mask for the Rd register for push, pop, ldr, str instructions. 271 // A mask for the Rd register for push, pop, ldr, str instructions.
272 const Instr kRdMask = 0x0000f000; 272 const Instr kRdMask = 0x0000f000;
273 static const int kRdShift = 12;
273 static const Instr kLdrRegFpOffsetPattern = 274 static const Instr kLdrRegFpOffsetPattern =
274 al | B26 | L | Offset | fp.code() * B16; 275 al | B26 | L | Offset | fp.code() * B16;
275 static const Instr kStrRegFpOffsetPattern = 276 static const Instr kStrRegFpOffsetPattern =
276 al | B26 | Offset | fp.code() * B16; 277 al | B26 | Offset | fp.code() * B16;
277 static const Instr kLdrRegFpNegOffsetPattern = 278 static const Instr kLdrRegFpNegOffsetPattern =
278 al | B26 | L | NegOffset | fp.code() * B16; 279 al | B26 | L | NegOffset | fp.code() * B16;
279 static const Instr kStrRegFpNegOffsetPattern = 280 static const Instr kStrRegFpNegOffsetPattern =
280 al | B26 | NegOffset | fp.code() * B16; 281 al | B26 | NegOffset | fp.code() * B16;
281 static const Instr kLdrStrInstrTypeMask = 0xffff0000; 282 static const Instr kLdrStrInstrTypeMask = 0xffff0000;
282 static const Instr kLdrStrInstrArgumentMask = 0x0000ffff; 283 static const Instr kLdrStrInstrArgumentMask = 0x0000ffff;
283 static const Instr kLdrStrOffsetMask = 0x00000fff; 284 static const Instr kLdrStrOffsetMask = 0x00000fff;
284 static const int kRdShift = 12;
285 285
286 // Spare buffer. 286 // Spare buffer.
287 static const int kMinimalBufferSize = 4*KB; 287 static const int kMinimalBufferSize = 4*KB;
288 static byte* spare_buffer_ = NULL; 288 static byte* spare_buffer_ = NULL;
289 289
290 Assembler::Assembler(void* buffer, int buffer_size) { 290 Assembler::Assembler(void* buffer, int buffer_size) {
291 if (buffer == NULL) { 291 if (buffer == NULL) {
292 // Do our own buffer management. 292 // Do our own buffer management.
293 if (buffer_size <= kMinimalBufferSize) { 293 if (buffer_size <= kMinimalBufferSize) {
294 buffer_size = kMinimalBufferSize; 294 buffer_size = kMinimalBufferSize;
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 931
932 932
933 void Assembler::add(Register dst, Register src1, const Operand& src2, 933 void Assembler::add(Register dst, Register src1, const Operand& src2,
934 SBit s, Condition cond) { 934 SBit s, Condition cond) {
935 addrmod1(cond | 4*B21 | s, src1, dst, src2); 935 addrmod1(cond | 4*B21 | s, src1, dst, src2);
936 936
937 // Eliminate pattern: push(r), pop() 937 // Eliminate pattern: push(r), pop()
938 // str(src, MemOperand(sp, 4, NegPreIndex), al); 938 // str(src, MemOperand(sp, 4, NegPreIndex), al);
939 // add(sp, sp, Operand(kPointerSize)); 939 // add(sp, sp, Operand(kPointerSize));
940 // Both instructions can be eliminated. 940 // Both instructions can be eliminated.
941 int pattern_size = 2 * kInstrSize; 941 if (can_peephole_optimize(2) &&
942 if (FLAG_push_pop_elimination &&
943 last_bound_pos_ <= (pc_offset() - pattern_size) &&
944 reloc_info_writer.last_pc() <= (pc_ - pattern_size) &&
945 // Pattern. 942 // Pattern.
946 instr_at(pc_ - 1 * kInstrSize) == kPopInstruction && 943 instr_at(pc_ - 1 * kInstrSize) == kPopInstruction &&
947 (instr_at(pc_ - 2 * kInstrSize) & ~RdMask) == kPushRegPattern) { 944 (instr_at(pc_ - 2 * kInstrSize) & ~RdMask) == kPushRegPattern) {
948 pc_ -= 2 * kInstrSize; 945 pc_ -= 2 * kInstrSize;
949 if (FLAG_print_push_pop_elimination) { 946 if (FLAG_print_peephole_optimization) {
950 PrintF("%x push(reg)/pop() eliminated\n", pc_offset()); 947 PrintF("%x push(reg)/pop() eliminated\n", pc_offset());
951 } 948 }
952 } 949 }
953 } 950 }
954 951
955 952
956 void Assembler::adc(Register dst, Register src1, const Operand& src2, 953 void Assembler::adc(Register dst, Register src1, const Operand& src2,
957 SBit s, Condition cond) { 954 SBit s, Condition cond) {
958 addrmod1(cond | 5*B21 | s, src1, dst, src2); 955 addrmod1(cond | 5*B21 | s, src1, dst, src2);
959 } 956 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 WriteRecordedPositions(); 1133 WriteRecordedPositions();
1137 } 1134 }
1138 addrmod2(cond | B26 | L, dst, src); 1135 addrmod2(cond | B26 | L, dst, src);
1139 1136
1140 // Eliminate pattern: push(ry), pop(rx) 1137 // Eliminate pattern: push(ry), pop(rx)
1141 // str(ry, MemOperand(sp, 4, NegPreIndex), al) 1138 // str(ry, MemOperand(sp, 4, NegPreIndex), al)
1142 // ldr(rx, MemOperand(sp, 4, PostIndex), al) 1139 // ldr(rx, MemOperand(sp, 4, PostIndex), al)
1143 // Both instructions can be eliminated if ry = rx. 1140 // Both instructions can be eliminated if ry = rx.
1144 // If ry != rx, a register copy from ry to rx is inserted 1141 // If ry != rx, a register copy from ry to rx is inserted
1145 // after eliminating the push and the pop instructions. 1142 // after eliminating the push and the pop instructions.
1146 int pattern_size = 2 * kInstrSize;
1147 Instr push_instr = instr_at(pc_ - 2 * kInstrSize); 1143 Instr push_instr = instr_at(pc_ - 2 * kInstrSize);
1148 Instr pop_instr = instr_at(pc_ - 1 * kInstrSize); 1144 Instr pop_instr = instr_at(pc_ - 1 * kInstrSize);
1149 1145
1150 if (FLAG_push_pop_elimination && 1146 if (can_peephole_optimize(2) &&
1151 last_bound_pos_ <= (pc_offset() - pattern_size) && 1147 IsPush(push_instr) &&
1152 reloc_info_writer.last_pc() <= (pc_ - pattern_size) && 1148 IsPop(pop_instr)) {
1153 IsPush(push_instr) &&
1154 IsPop(pop_instr)) {
1155 if ((pop_instr & kRdMask) != (push_instr & kRdMask)) { 1149 if ((pop_instr & kRdMask) != (push_instr & kRdMask)) {
1156 // For consecutive push and pop on different registers, 1150 // For consecutive push and pop on different registers,
1157 // we delete both the push & pop and insert a register move. 1151 // we delete both the push & pop and insert a register move.
1158 // push ry, pop rx --> mov rx, ry 1152 // push ry, pop rx --> mov rx, ry
1159 Register reg_pushed, reg_popped; 1153 Register reg_pushed, reg_popped;
1160 reg_pushed = GetRd(push_instr); 1154 reg_pushed = GetRd(push_instr);
1161 reg_popped = GetRd(pop_instr); 1155 reg_popped = GetRd(pop_instr);
1162 pc_ -= 2 * kInstrSize; 1156 pc_ -= 2 * kInstrSize;
1163 // Insert a mov instruction, which is better than a pair of push & pop 1157 // Insert a mov instruction, which is better than a pair of push & pop
1164 mov(reg_popped, reg_pushed); 1158 mov(reg_popped, reg_pushed);
1165 if (FLAG_print_push_pop_elimination) { 1159 if (FLAG_print_peephole_optimization) {
1166 PrintF("%x push/pop (diff reg) replaced by a reg move\n", pc_offset()); 1160 PrintF("%x push/pop (diff reg) replaced by a reg move\n", pc_offset());
1167 } 1161 }
1168 } else { 1162 } else {
1169 // For consecutive push and pop on the same register, 1163 // For consecutive push and pop on the same register,
1170 // both the push and the pop can be deleted. 1164 // both the push and the pop can be deleted.
1171 pc_ -= 2 * kInstrSize; 1165 pc_ -= 2 * kInstrSize;
1172 if (FLAG_print_push_pop_elimination) { 1166 if (FLAG_print_peephole_optimization) {
1173 PrintF("%x push/pop (same reg) eliminated\n", pc_offset()); 1167 PrintF("%x push/pop (same reg) eliminated\n", pc_offset());
1174 } 1168 }
1175 } 1169 }
1176 } 1170 }
1177 1171
1178 pattern_size = 2 * kInstrSize; 1172 if (can_peephole_optimize(2)) {
1179 if (FLAG_peephole_optimization &&
1180 last_bound_pos_ <= (pc_offset() - pattern_size) &&
1181 reloc_info_writer.last_pc() <= (pc_ - pattern_size)) {
1182 Instr str_instr = instr_at(pc_ - 2 * kInstrSize); 1173 Instr str_instr = instr_at(pc_ - 2 * kInstrSize);
1183 Instr ldr_instr = instr_at(pc_ - 1 * kInstrSize); 1174 Instr ldr_instr = instr_at(pc_ - 1 * kInstrSize);
1184 1175
1185 if ((IsStrRegFpOffset(str_instr) && 1176 if ((IsStrRegFpOffset(str_instr) &&
1186 IsLdrRegFpOffset(ldr_instr)) || 1177 IsLdrRegFpOffset(ldr_instr)) ||
1187 (IsStrRegFpNegOffset(str_instr) && 1178 (IsStrRegFpNegOffset(str_instr) &&
1188 IsLdrRegFpNegOffset(ldr_instr))) { 1179 IsLdrRegFpNegOffset(ldr_instr))) {
1189 if ((ldr_instr & kLdrStrInstrArgumentMask) == 1180 if ((ldr_instr & kLdrStrInstrArgumentMask) ==
1190 (str_instr & kLdrStrInstrArgumentMask)) { 1181 (str_instr & kLdrStrInstrArgumentMask)) {
1191 // Pattern: Ldr/str same fp+offset, same register. 1182 // Pattern: Ldr/str same fp+offset, same register.
(...skipping 27 matching lines...) Expand all
1219 pc_ -= 1 * kInstrSize; 1210 pc_ -= 1 * kInstrSize;
1220 // Insert a mov instruction, which is better than ldr. 1211 // Insert a mov instruction, which is better than ldr.
1221 mov(reg_loaded, reg_stored); 1212 mov(reg_loaded, reg_stored);
1222 if (FLAG_print_peephole_optimization) { 1213 if (FLAG_print_peephole_optimization) {
1223 PrintF("%x str/ldr (fp + same offset), diff reg \n", pc_offset()); 1214 PrintF("%x str/ldr (fp + same offset), diff reg \n", pc_offset());
1224 } 1215 }
1225 } 1216 }
1226 } 1217 }
1227 } 1218 }
1228 1219
1229 pattern_size = 3 * kInstrSize; 1220 if (can_peephole_optimize(3)) {
1230 if (FLAG_push_pop_elimination &&
1231 last_bound_pos_ <= (pc_offset() - pattern_size) &&
1232 reloc_info_writer.last_pc() <= (pc_ - pattern_size)) {
1233 Instr mem_write_instr = instr_at(pc_ - 3 * kInstrSize); 1221 Instr mem_write_instr = instr_at(pc_ - 3 * kInstrSize);
1234 Instr ldr_instr = instr_at(pc_ - 2 * kInstrSize); 1222 Instr ldr_instr = instr_at(pc_ - 2 * kInstrSize);
1235 Instr mem_read_instr = instr_at(pc_ - 1 * kInstrSize); 1223 Instr mem_read_instr = instr_at(pc_ - 1 * kInstrSize);
1236 if (IsPush(mem_write_instr) && 1224 if (IsPush(mem_write_instr) &&
1237 IsPop(mem_read_instr)) { 1225 IsPop(mem_read_instr)) {
1238 if ((IsLdrRegFpOffset(ldr_instr) || 1226 if ((IsLdrRegFpOffset(ldr_instr) ||
1239 IsLdrRegFpNegOffset(ldr_instr))) { 1227 IsLdrRegFpNegOffset(ldr_instr))) {
1240 if ((mem_write_instr & kRdMask) == 1228 if ((mem_write_instr & kRdMask) ==
1241 (mem_read_instr & kRdMask)) { 1229 (mem_read_instr & kRdMask)) {
1242 // Pattern: push & pop from/to same register, 1230 // Pattern: push & pop from/to same register,
(...skipping 10 matching lines...) Expand all
1253 // else 1241 // else
1254 // ldr rz, [fp, #-24] 1242 // ldr rz, [fp, #-24]
1255 1243
1256 if ((mem_write_instr & kRdMask) == (ldr_instr & kRdMask)) { 1244 if ((mem_write_instr & kRdMask) == (ldr_instr & kRdMask)) {
1257 pc_ -= 3 * kInstrSize; 1245 pc_ -= 3 * kInstrSize;
1258 } else { 1246 } else {
1259 pc_ -= 3 * kInstrSize; 1247 pc_ -= 3 * kInstrSize;
1260 // Reinsert back the ldr rz. 1248 // Reinsert back the ldr rz.
1261 emit(ldr_instr); 1249 emit(ldr_instr);
1262 } 1250 }
1263 if (FLAG_print_push_pop_elimination) { 1251 if (FLAG_print_peephole_optimization) {
1264 PrintF("%x push/pop -dead ldr fp+offset in middle\n", pc_offset()); 1252 PrintF("%x push/pop -dead ldr fp+offset in middle\n", pc_offset());
1265 } 1253 }
1266 } else { 1254 } else {
1267 // Pattern: push & pop from/to different registers 1255 // Pattern: push & pop from/to different registers
1268 // with a fp+offset ldr in between 1256 // with a fp+offset ldr in between
1269 // 1257 //
1270 // The following: 1258 // The following:
1271 // str rx, [sp, #-4]! 1259 // str rx, [sp, #-4]!
1272 // ldr rz, [fp, #-24] 1260 // ldr rz, [fp, #-24]
1273 // ldr ry, [sp], #+4 1261 // ldr ry, [sp], #+4
(...skipping 24 matching lines...) Expand all
1298 } else if (((mem_read_instr & kRdMask) 1286 } else if (((mem_read_instr & kRdMask)
1299 != (ldr_instr & kRdMask)) || 1287 != (ldr_instr & kRdMask)) ||
1300 ((mem_write_instr & kRdMask) 1288 ((mem_write_instr & kRdMask)
1301 == (ldr_instr & kRdMask)) ) { 1289 == (ldr_instr & kRdMask)) ) {
1302 reg_pushed = GetRd(mem_write_instr); 1290 reg_pushed = GetRd(mem_write_instr);
1303 reg_popped = GetRd(mem_read_instr); 1291 reg_popped = GetRd(mem_read_instr);
1304 pc_ -= 3 * kInstrSize; 1292 pc_ -= 3 * kInstrSize;
1305 mov(reg_popped, reg_pushed); 1293 mov(reg_popped, reg_pushed);
1306 emit(ldr_instr); 1294 emit(ldr_instr);
1307 } 1295 }
1308 if (FLAG_print_push_pop_elimination) { 1296 if (FLAG_print_peephole_optimization) {
1309 PrintF("%x push/pop (ldr fp+off in middle)\n", pc_offset()); 1297 PrintF("%x push/pop (ldr fp+off in middle)\n", pc_offset());
1310 } 1298 }
1311 } 1299 }
1312 } 1300 }
1313 } 1301 }
1314 } 1302 }
1315 } 1303 }
1316 1304
1317 1305
1318 void Assembler::str(Register src, const MemOperand& dst, Condition cond) { 1306 void Assembler::str(Register src, const MemOperand& dst, Condition cond) {
1319 addrmod2(cond | B26, src, dst); 1307 addrmod2(cond | B26, src, dst);
1320 1308
1321 // Eliminate pattern: pop(), push(r) 1309 // Eliminate pattern: pop(), push(r)
1322 // add sp, sp, #4 LeaveCC, al; str r, [sp, #-4], al 1310 // add sp, sp, #4 LeaveCC, al; str r, [sp, #-4], al
1323 // -> str r, [sp, 0], al 1311 // -> str r, [sp, 0], al
1324 int pattern_size = 2 * kInstrSize; 1312 if (can_peephole_optimize(2) &&
1325 if (FLAG_push_pop_elimination &&
1326 last_bound_pos_ <= (pc_offset() - pattern_size) &&
1327 reloc_info_writer.last_pc() <= (pc_ - pattern_size) &&
1328 // Pattern. 1313 // Pattern.
1329 instr_at(pc_ - 1 * kInstrSize) == (kPushRegPattern | src.code() * B12) && 1314 instr_at(pc_ - 1 * kInstrSize) == (kPushRegPattern | src.code() * B12) &&
1330 instr_at(pc_ - 2 * kInstrSize) == kPopInstruction) { 1315 instr_at(pc_ - 2 * kInstrSize) == kPopInstruction) {
1331 pc_ -= 2 * kInstrSize; 1316 pc_ -= 2 * kInstrSize;
1332 emit(al | B26 | 0 | Offset | sp.code() * B16 | src.code() * B12); 1317 emit(al | B26 | 0 | Offset | sp.code() * B16 | src.code() * B12);
1333 if (FLAG_print_push_pop_elimination) { 1318 if (FLAG_print_peephole_optimization) {
1334 PrintF("%x pop()/push(reg) eliminated\n", pc_offset()); 1319 PrintF("%x pop()/push(reg) eliminated\n", pc_offset());
1335 } 1320 }
1336 } 1321 }
1337 } 1322 }
1338 1323
1339 1324
1340 void Assembler::ldrb(Register dst, const MemOperand& src, Condition cond) { 1325 void Assembler::ldrb(Register dst, const MemOperand& src, Condition cond) {
1341 addrmod2(cond | B26 | B | L, dst, src); 1326 addrmod2(cond | B26 | B | L, dst, src);
1342 } 1327 }
1343 1328
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after
2265 bind(&after_pool); 2250 bind(&after_pool);
2266 } 2251 }
2267 2252
2268 // Since a constant pool was just emitted, move the check offset forward by 2253 // Since a constant pool was just emitted, move the check offset forward by
2269 // the standard interval. 2254 // the standard interval.
2270 next_buffer_check_ = pc_offset() + kCheckConstInterval; 2255 next_buffer_check_ = pc_offset() + kCheckConstInterval;
2271 } 2256 }
2272 2257
2273 2258
2274 } } // namespace v8::internal 2259 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698