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

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

Issue 1320073004: MIPS:[turbofan] Improve boolean materialization compares. Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: remove the 'predicate' use from Tst, Ovf, Cmp cases Created 5 years, 3 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 | « no previous file | src/compiler/mips/instruction-selector-mips.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 #include "src/compiler/code-generator-impl.h" 6 #include "src/compiler/code-generator-impl.h"
7 #include "src/compiler/gap-resolver.h" 7 #include "src/compiler/gap-resolver.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/osr.h" 9 #include "src/compiler/osr.h"
10 #include "src/mips/macro-assembler-mips.h" 10 #include "src/mips/macro-assembler-mips.h"
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 }; 194 };
195 195
196 196
197 class OutOfLineCeil final : public OutOfLineRound { 197 class OutOfLineCeil final : public OutOfLineRound {
198 public: 198 public:
199 OutOfLineCeil(CodeGenerator* gen, DoubleRegister result) 199 OutOfLineCeil(CodeGenerator* gen, DoubleRegister result)
200 : OutOfLineRound(gen, result) {} 200 : OutOfLineRound(gen, result) {}
201 }; 201 };
202 202
203 203
204 Condition FlagsConditionToConditionCmp(FlagsCondition condition) { 204 Condition FlagsConditionToConditionCmp(bool& predicate,
205 FlagsCondition condition) {
205 switch (condition) { 206 switch (condition) {
206 case kEqual: 207 case kEqual:
208 predicate = true;
207 return eq; 209 return eq;
208 case kNotEqual: 210 case kNotEqual:
211 predicate = false;
209 return ne; 212 return ne;
210 case kSignedLessThan: 213 case kSignedLessThan:
214 predicate = true;
211 return lt; 215 return lt;
212 case kSignedGreaterThanOrEqual: 216 case kSignedGreaterThanOrEqual:
217 predicate = false;
213 return ge; 218 return ge;
214 case kSignedLessThanOrEqual: 219 case kSignedLessThanOrEqual:
220 predicate = false;
215 return le; 221 return le;
216 case kSignedGreaterThan: 222 case kSignedGreaterThan:
223 predicate = true;
217 return gt; 224 return gt;
218 case kUnsignedLessThan: 225 case kUnsignedLessThan:
226 predicate = true;
219 return lo; 227 return lo;
220 case kUnsignedGreaterThanOrEqual: 228 case kUnsignedGreaterThanOrEqual:
229 predicate = false;
221 return hs; 230 return hs;
222 case kUnsignedLessThanOrEqual: 231 case kUnsignedLessThanOrEqual:
232 predicate = false;
223 return ls; 233 return ls;
224 case kUnsignedGreaterThan: 234 case kUnsignedGreaterThan:
235 predicate = true;
225 return hi; 236 return hi;
226 case kUnorderedEqual: 237 case kUnorderedEqual:
227 case kUnorderedNotEqual: 238 case kUnorderedNotEqual:
239 predicate = true;
228 break; 240 break;
229 default: 241 default:
242 predicate = true;
230 break; 243 break;
231 } 244 }
232 UNREACHABLE(); 245 UNREACHABLE();
233 return kNoCondition; 246 return kNoCondition;
234 } 247 }
235 248
236 249
237 Condition FlagsConditionToConditionTst(FlagsCondition condition) { 250 Condition FlagsConditionToConditionTst(bool& predicate,
251 FlagsCondition condition) {
238 switch (condition) { 252 switch (condition) {
239 case kNotEqual: 253 case kNotEqual:
254 predicate = false;
240 return ne; 255 return ne;
241 case kEqual: 256 case kEqual:
257 predicate = true;
242 return eq; 258 return eq;
243 default: 259 default:
260 predicate = true;
244 break; 261 break;
245 } 262 }
246 UNREACHABLE(); 263 UNREACHABLE();
247 return kNoCondition; 264 return kNoCondition;
248 } 265 }
249 266
250 267
251 Condition FlagsConditionToConditionOvf(FlagsCondition condition) { 268 Condition FlagsConditionToConditionOvf(bool& predicate,
269 FlagsCondition condition) {
252 switch (condition) { 270 switch (condition) {
253 case kOverflow: 271 case kOverflow:
272 predicate = true;
254 return lt; 273 return lt;
255 case kNotOverflow: 274 case kNotOverflow:
275 predicate = false;
256 return ge; 276 return ge;
257 default: 277 default:
278 predicate = true;
258 break; 279 break;
259 } 280 }
260 UNREACHABLE(); 281 UNREACHABLE();
261 return kNoCondition; 282 return kNoCondition;
262 } 283 }
263 284
264 FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate, 285 FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
265 FlagsCondition condition) { 286 FlagsCondition condition) {
266 switch (condition) { 287 switch (condition) {
267 case kEqual: 288 case kEqual:
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 return false; 918 return false;
898 } 919 }
899 920
900 921
901 // Assembles branches after an instruction. 922 // Assembles branches after an instruction.
902 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 923 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
903 MipsOperandConverter i(this, instr); 924 MipsOperandConverter i(this, instr);
904 Label* tlabel = branch->true_label; 925 Label* tlabel = branch->true_label;
905 Label* flabel = branch->false_label; 926 Label* flabel = branch->false_label;
906 Condition cc = kNoCondition; 927 Condition cc = kNoCondition;
907 928 bool predicate;
908 // MIPS does not have condition code flags, so compare and branch are 929 // MIPS does not have condition code flags, so compare and branch are
909 // implemented differently than on the other arch's. The compare operations 930 // implemented differently than on the other arch's. The compare operations
910 // emit mips pseudo-instructions, which are handled here by branch 931 // emit mips pseudo-instructions, which are handled here by branch
911 // instructions that do the actual comparison. Essential that the input 932 // instructions that do the actual comparison. Essential that the input
912 // registers to compare pseudo-op are not modified before this branch op, as 933 // registers to compare pseudo-op are not modified before this branch op, as
913 // they are tested here. 934 // they are tested here.
914 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were 935 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
915 // not separated by other instructions. 936 // not separated by other instructions.
916 937
917 if (instr->arch_opcode() == kMipsTst) { 938 if (instr->arch_opcode() == kMipsTst) {
918 cc = FlagsConditionToConditionTst(branch->condition); 939 cc = FlagsConditionToConditionTst(predicate, branch->condition);
919 __ And(at, i.InputRegister(0), i.InputOperand(1)); 940 __ And(at, i.InputRegister(0), i.InputOperand(1));
920 __ Branch(tlabel, cc, at, Operand(zero_reg)); 941 __ Branch(tlabel, cc, at, Operand(zero_reg));
921 } else if (instr->arch_opcode() == kMipsAddOvf || 942 } else if (instr->arch_opcode() == kMipsAddOvf ||
922 instr->arch_opcode() == kMipsSubOvf) { 943 instr->arch_opcode() == kMipsSubOvf) {
923 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow. 944 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow.
924 cc = FlagsConditionToConditionOvf(branch->condition); 945 cc = FlagsConditionToConditionOvf(predicate, branch->condition);
925 __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg)); 946 __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg));
926 } else if (instr->arch_opcode() == kMipsCmp) { 947 } else if (instr->arch_opcode() == kMipsCmp) {
927 cc = FlagsConditionToConditionCmp(branch->condition); 948 cc = FlagsConditionToConditionCmp(predicate, branch->condition);
928 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); 949 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
929 } else if (instr->arch_opcode() == kMipsCmpS) { 950 } else if (instr->arch_opcode() == kMipsCmpS) {
930 if (!convertCondition(branch->condition, cc)) { 951 if (!convertCondition(branch->condition, cc)) {
931 UNSUPPORTED_COND(kMips64CmpS, branch->condition); 952 UNSUPPORTED_COND(kMips64CmpS, branch->condition);
932 } 953 }
933 __ BranchF32(tlabel, NULL, cc, i.InputSingleRegister(0), 954 __ BranchF32(tlabel, NULL, cc, i.InputSingleRegister(0),
934 i.InputSingleRegister(1)); 955 i.InputSingleRegister(1));
935 } else if (instr->arch_opcode() == kMipsCmpD) { 956 } else if (instr->arch_opcode() == kMipsCmpD) {
936 if (!convertCondition(branch->condition, cc)) { 957 if (!convertCondition(branch->condition, cc)) {
937 UNSUPPORTED_COND(kMips64CmpD, branch->condition); 958 UNSUPPORTED_COND(kMips64CmpD, branch->condition);
(...skipping 19 matching lines...) Expand all
957 FlagsCondition condition) { 978 FlagsCondition condition) {
958 MipsOperandConverter i(this, instr); 979 MipsOperandConverter i(this, instr);
959 Label done; 980 Label done;
960 981
961 // Materialize a full 32-bit 1 or 0 value. The result register is always the 982 // Materialize a full 32-bit 1 or 0 value. The result register is always the
962 // last output of the instruction. 983 // last output of the instruction.
963 Label false_value; 984 Label false_value;
964 DCHECK_NE(0u, instr->OutputCount()); 985 DCHECK_NE(0u, instr->OutputCount());
965 Register result = i.OutputRegister(instr->OutputCount() - 1); 986 Register result = i.OutputRegister(instr->OutputCount() - 1);
966 Condition cc = kNoCondition; 987 Condition cc = kNoCondition;
967 988 bool predicate;
968 // MIPS does not have condition code flags, so compare and branch are 989 // MIPS does not have condition code flags, so compare and branch are
969 // implemented differently than on the other arch's. The compare operations 990 // implemented differently than on the other arch's. The compare operations
970 // emit mips psuedo-instructions, which are checked and handled here. 991 // emit mips psuedo-instructions, which are checked and handled here.
971 992
972 // For materializations, we use delay slot to set the result true, and
973 // in the false case, where we fall thru the branch, we reset the result
974 // false.
975
976 if (instr->arch_opcode() == kMipsTst) { 993 if (instr->arch_opcode() == kMipsTst) {
977 cc = FlagsConditionToConditionTst(condition); 994 cc = FlagsConditionToConditionTst(predicate, condition);
978 __ And(at, i.InputRegister(0), i.InputOperand(1)); 995 __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1));
979 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); 996 if (IsMipsArchVariant(kMips32r6)) {
980 __ li(result, Operand(1)); // In delay slot. 997 __ li(kScratchReg2, 1); // Create 1 for true.
981 998 if (cc == eq) {
999 __ seleqz(result, kScratchReg2, kScratchReg);
1000 } else {
1001 __ selnez(result, kScratchReg2, kScratchReg);
1002 }
1003 } else {
1004 __ li(result, 1);
1005 if (cc == eq) {
1006 __ Movn(result, zero_reg, kScratchReg);
1007 } else {
1008 __ Movz(result, zero_reg, kScratchReg);
1009 }
1010 }
1011 return;
982 } else if (instr->arch_opcode() == kMipsAddOvf || 1012 } else if (instr->arch_opcode() == kMipsAddOvf ||
983 instr->arch_opcode() == kMipsSubOvf) { 1013 instr->arch_opcode() == kMipsSubOvf) {
984 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. 1014 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow.
985 cc = FlagsConditionToConditionOvf(condition); 1015 cc = FlagsConditionToConditionOvf(predicate, condition);
986 __ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg)); 1016 // Return 1 on overflow.
987 __ li(result, Operand(1)); // In delay slot. 1017 __ Slt(result, kCompareReg, Operand(zero_reg));
988 1018 if (cc == ne) // Invert result on not overflow.
1019 __ xori(result, result, 1);
1020 return;
989 } else if (instr->arch_opcode() == kMipsCmp) { 1021 } else if (instr->arch_opcode() == kMipsCmp) {
990 Register left = i.InputRegister(0); 1022 cc = FlagsConditionToConditionCmp(predicate, condition);
991 Operand right = i.InputOperand(1); 1023 switch (cc) {
992 cc = FlagsConditionToConditionCmp(condition); 1024 case eq:
993 __ Branch(USE_DELAY_SLOT, &done, cc, left, right); 1025 case ne: {
994 __ li(result, Operand(1)); // In delay slot. 1026 Register left = i.InputRegister(0);
995 1027 Operand right = i.InputOperand(1);
1028 __ Subu(kScratchReg, left, right);
1029 if (IsMipsArchVariant(kMips32r6)) {
1030 __ li(kScratchReg2, 1);
1031 if (cc == eq) {
1032 __ seleqz(result, kScratchReg2, kScratchReg);
1033 } else {
1034 __ selnez(result, kScratchReg2, kScratchReg);
1035 }
1036 } else {
1037 __ li(result, 1);
1038 if (cc == eq) {
1039 __ Movn(result, zero_reg, kScratchReg);
1040 } else {
1041 __ Movz(result, zero_reg, kScratchReg);
1042 }
1043 }
1044 } break;
1045 case lt:
1046 case ge: {
1047 Register left = i.InputRegister(0);
1048 Operand right = i.InputOperand(1);
1049 __ Slt(result, left, right);
1050 if (cc == ge) {
1051 __ xori(result, result, 1);
1052 }
1053 } break;
1054 case gt:
1055 case le: {
1056 Register left = i.InputRegister(1);
1057 Operand right = i.InputOperand(0);
1058 __ Slt(result, left, right);
1059 if (cc == le) {
1060 __ xori(result, result, 1);
1061 }
1062 } break;
1063 case lo:
1064 case hs: {
1065 Register left = i.InputRegister(0);
1066 Operand right = i.InputOperand(1);
1067 __ Sltu(result, left, right);
1068 if (cc == hs) {
1069 __ xori(result, result, 1);
1070 }
1071 } break;
1072 case hi:
1073 case ls: {
1074 Register left = i.InputRegister(1);
1075 Operand right = i.InputOperand(0);
1076 __ Sltu(result, left, right);
1077 if (cc == ls) {
1078 __ xori(result, result, 1);
1079 }
1080 } break;
1081 default:
1082 UNREACHABLE();
1083 }
1084 return;
996 } else if (instr->arch_opcode() == kMipsCmpD || 1085 } else if (instr->arch_opcode() == kMipsCmpD ||
997 instr->arch_opcode() == kMipsCmpS) { 1086 instr->arch_opcode() == kMipsCmpS) {
998 FPURegister left = i.InputDoubleRegister(0); 1087 FPURegister left = i.InputDoubleRegister(0);
999 FPURegister right = i.InputDoubleRegister(1); 1088 FPURegister right = i.InputDoubleRegister(1);
1000 1089
1001 bool predicate;
1002 FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition); 1090 FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition);
1003 if (!IsMipsArchVariant(kMips32r6)) { 1091 if (!IsMipsArchVariant(kMips32r6)) {
1004 __ li(result, Operand(1)); 1092 __ li(result, Operand(1));
1005 if (instr->arch_opcode() == kMipsCmpD) { 1093 if (instr->arch_opcode() == kMipsCmpD) {
1006 __ c(cc, D, left, right); 1094 __ c(cc, D, left, right);
1007 } else { 1095 } else {
1008 DCHECK(instr->arch_opcode() == kMipsCmpS); 1096 DCHECK(instr->arch_opcode() == kMipsCmpS);
1009 __ c(cc, S, left, right); 1097 __ c(cc, S, left, right);
1010 } 1098 }
1011 if (predicate) { 1099 if (predicate) {
(...skipping 13 matching lines...) Expand all
1025 if (!predicate) // Toggle result for not equal. 1113 if (!predicate) // Toggle result for not equal.
1026 __ xori(result, result, 1); 1114 __ xori(result, result, 1);
1027 } 1115 }
1028 return; 1116 return;
1029 } else { 1117 } else {
1030 PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n", 1118 PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
1031 instr->arch_opcode()); 1119 instr->arch_opcode());
1032 TRACE_UNIMPL(); 1120 TRACE_UNIMPL();
1033 UNIMPLEMENTED(); 1121 UNIMPLEMENTED();
1034 } 1122 }
1035
1036 // Fallthrough case is the false materialization.
1037 __ bind(&false_value);
1038 __ li(result, Operand(0));
1039 __ bind(&done);
1040 } 1123 }
1041 1124
1042 1125
1043 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { 1126 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
1044 MipsOperandConverter i(this, instr); 1127 MipsOperandConverter i(this, instr);
1045 Register input = i.InputRegister(0); 1128 Register input = i.InputRegister(0);
1046 for (size_t index = 2; index < instr->InputCount(); index += 2) { 1129 for (size_t index = 2; index < instr->InputCount(); index += 2) {
1047 __ li(at, Operand(i.InputInt32(index + 0))); 1130 __ li(at, Operand(i.InputInt32(index + 0)));
1048 __ beq(input, at, GetLabel(i.InputRpo(index + 1))); 1131 __ beq(input, at, GetLabel(i.InputRpo(index + 1)));
1049 } 1132 }
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 padding_size -= v8::internal::Assembler::kInstrSize; 1467 padding_size -= v8::internal::Assembler::kInstrSize;
1385 } 1468 }
1386 } 1469 }
1387 } 1470 }
1388 1471
1389 #undef __ 1472 #undef __
1390 1473
1391 } // namespace compiler 1474 } // namespace compiler
1392 } // namespace internal 1475 } // namespace internal
1393 } // namespace v8 1476 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/mips/instruction-selector-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698