Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/machine-operator.h" | 5 #include "src/compiler/machine-operator.h" |
| 6 #include "src/compiler/opcodes.h" | 6 #include "src/compiler/opcodes.h" |
| 7 #include "src/compiler/operator.h" | 7 #include "src/compiler/operator.h" |
| 8 #include "src/compiler/operator-properties.h" | 8 #include "src/compiler/operator-properties.h" |
| 9 #include "test/unittests/test-utils.h" | 9 #include "test/unittests/test-utils.h" |
| 10 | 10 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 } | 142 } |
| 143 | 143 |
| 144 | 144 |
| 145 INSTANTIATE_TEST_CASE_P( | 145 INSTANTIATE_TEST_CASE_P( |
| 146 MachineOperatorTest, MachineStoreOperatorTest, | 146 MachineOperatorTest, MachineStoreOperatorTest, |
| 147 ::testing::Combine( | 147 ::testing::Combine( |
| 148 ::testing::ValuesIn(kMachineReps), | 148 ::testing::ValuesIn(kMachineReps), |
| 149 ::testing::Combine(::testing::ValuesIn(kMachineTypes), | 149 ::testing::Combine(::testing::ValuesIn(kMachineTypes), |
| 150 ::testing::Values(kNoWriteBarrier, | 150 ::testing::Values(kNoWriteBarrier, |
| 151 kFullWriteBarrier)))); | 151 kFullWriteBarrier)))); |
| 152 | 152 #endif |
| 153 | 153 |
| 154 // ----------------------------------------------------------------------------- | 154 // ----------------------------------------------------------------------------- |
| 155 // Pure operators. | 155 // Pure operators. |
| 156 | 156 |
| 157 | |
| 158 namespace { | 157 namespace { |
| 159 | 158 |
| 160 struct PureOperator { | 159 typedef const Operator* (MachineOperatorBuilder::*OperatorConstructor)(); |
| 161 const Operator* (MachineOperatorBuilder::*constructor)(); | 160 typedef const OptionalOperator ( |
| 162 IrOpcode::Value opcode; | 161 MachineOperatorBuilder::*OptionalOperatorConstructor)(); |
| 163 int value_input_count; | 162 } |
|
Benedikt Meurer
2015/05/07 04:48:38
Add // namespace comment after } and empty line be
| |
| 164 int control_input_count; | 163 |
| 165 int value_output_count; | 164 |
| 165 class MachinePureOperatorTest : public TestWithZone { | |
| 166 protected: | |
| 167 void CheckGlobalCaching(OperatorConstructor constructor) { | |
| 168 MachineOperatorBuilder machine1(zone(), word_type()); | |
| 169 MachineOperatorBuilder machine2(zone(), word_type()); | |
| 170 EXPECT_EQ((machine1.*constructor)(), (machine2.*constructor)()); | |
|
Benedikt Meurer
2015/05/07 04:48:38
Don't move test expectations into helper functions
titzer
2015/05/11 11:55:29
I can inline them directly into the MACRO.
| |
| 171 } | |
| 172 | |
| 173 void CheckCounts(OperatorConstructor constructor, int value_input_count, | |
| 174 int control_input_count, int value_output_count) { | |
| 175 MachineOperatorBuilder machine(zone(), word_type()); | |
| 176 const Operator* op = (machine.*constructor)(); | |
| 177 EXPECT_EQ(value_input_count, op->ValueInputCount()); | |
| 178 EXPECT_EQ(control_input_count, op->ControlInputCount()); | |
| 179 EXPECT_EQ(value_output_count, op->ValueOutputCount()); | |
| 180 } | |
| 181 | |
| 182 void CheckGlobalCaching(OptionalOperatorConstructor constructor, | |
| 183 MachineOperatorBuilder::Flag enabling_flag) { | |
| 184 MachineOperatorBuilder machine1(zone(), word_type(), enabling_flag); | |
| 185 MachineOperatorBuilder machine2(zone(), word_type(), enabling_flag); | |
| 186 EXPECT_EQ((machine1.*constructor)().op(), (machine2.*constructor)().op()); | |
| 187 } | |
| 188 | |
| 189 void CheckEnablingFlag(OptionalOperatorConstructor constructor, | |
| 190 MachineOperatorBuilder::Flag enabling_flag) { | |
| 191 MachineOperatorBuilder machine1(zone(), word_type(), enabling_flag); | |
| 192 MachineOperatorBuilder machine2(zone(), word_type()); | |
| 193 EXPECT_TRUE((machine1.*constructor)().supported()); | |
| 194 EXPECT_FALSE((machine2.*constructor)().supported()); | |
| 195 } | |
| 196 | |
| 197 private: | |
| 198 MachineType word_type() { return kMachPtr; } | |
| 166 }; | 199 }; |
| 167 | 200 |
| 168 | 201 |
| 169 std::ostream& operator<<(std::ostream& os, const PureOperator& pop) { | 202 TEST_F(MachinePureOperatorTest, PureOperators) { |
| 170 return os << IrOpcode::Mnemonic(pop.opcode); | 203 #define PURE(Name, value_input_count, control_input_count, value_output_count) \ |
| 204 CheckGlobalCaching(&MachineOperatorBuilder::Name); \ | |
| 205 CheckCounts(&MachineOperatorBuilder::Name, value_input_count, \ | |
| 206 control_input_count, value_output_count); | |
| 207 | |
| 208 PURE(Word32And, 2, 0, 1); | |
|
Benedikt Meurer
2015/05/07 04:48:38
This is a lot of boilerplate and macroism and indi
titzer
2015/05/11 11:55:29
I can inline the helper functions into the macro,
Benedikt Meurer
2015/05/12 05:15:41
What's the point of putting everything into the ma
| |
| 209 PURE(Word32Or, 2, 0, 1); | |
| 210 PURE(Word32Xor, 2, 0, 1); | |
| 211 PURE(Word32Shl, 2, 0, 1); | |
| 212 PURE(Word32Shr, 2, 0, 1); | |
| 213 PURE(Word32Sar, 2, 0, 1); | |
| 214 PURE(Word32Ror, 2, 0, 1); | |
| 215 PURE(Word32Equal, 2, 0, 1); | |
| 216 PURE(Word32Clz, 1, 0, 1); | |
| 217 PURE(Word64And, 2, 0, 1); | |
| 218 PURE(Word64Or, 2, 0, 1); | |
| 219 PURE(Word64Xor, 2, 0, 1); | |
| 220 PURE(Word64Shl, 2, 0, 1); | |
| 221 PURE(Word64Shr, 2, 0, 1); | |
| 222 PURE(Word64Sar, 2, 0, 1); | |
| 223 PURE(Word64Ror, 2, 0, 1); | |
| 224 PURE(Word64Equal, 2, 0, 1); | |
| 225 PURE(Int32Add, 2, 0, 1); | |
| 226 PURE(Int32AddWithOverflow, 2, 0, 2); | |
| 227 PURE(Int32Sub, 2, 0, 1); | |
| 228 PURE(Int32SubWithOverflow, 2, 0, 2); | |
| 229 PURE(Int32Mul, 2, 0, 1); | |
| 230 PURE(Int32MulHigh, 2, 0, 1); | |
| 231 PURE(Int32Div, 2, 1, 1); | |
| 232 PURE(Uint32Div, 2, 1, 1); | |
| 233 PURE(Int32Mod, 2, 1, 1); | |
| 234 PURE(Uint32Mod, 2, 1, 1); | |
| 235 PURE(Int32LessThan, 2, 0, 1); | |
| 236 PURE(Int32LessThanOrEqual, 2, 0, 1); | |
| 237 PURE(Uint32LessThan, 2, 0, 1); | |
| 238 PURE(Uint32LessThanOrEqual, 2, 0, 1); | |
| 239 PURE(Int64Add, 2, 0, 1); | |
| 240 PURE(Int64Sub, 2, 0, 1); | |
| 241 PURE(Int64Mul, 2, 0, 1); | |
| 242 PURE(Int64Div, 2, 0, 1); | |
| 243 PURE(Uint64Div, 2, 0, 1); | |
| 244 PURE(Int64Mod, 2, 0, 1); | |
| 245 PURE(Uint64Mod, 2, 0, 1); | |
| 246 PURE(Int64LessThan, 2, 0, 1); | |
| 247 PURE(Int64LessThanOrEqual, 2, 0, 1); | |
| 248 PURE(Uint64LessThan, 2, 0, 1); | |
| 249 PURE(ChangeFloat32ToFloat64, 1, 0, 1); | |
| 250 PURE(ChangeFloat64ToInt32, 1, 0, 1); | |
| 251 PURE(ChangeFloat64ToUint32, 1, 0, 1); | |
| 252 PURE(ChangeInt32ToInt64, 1, 0, 1); | |
| 253 PURE(ChangeUint32ToFloat64, 1, 0, 1); | |
| 254 PURE(ChangeUint32ToUint64, 1, 0, 1); | |
| 255 PURE(TruncateFloat64ToFloat32, 1, 0, 1); | |
| 256 PURE(TruncateFloat64ToInt32, 1, 0, 1); | |
| 257 PURE(TruncateInt64ToInt32, 1, 0, 1); | |
| 258 PURE(Float32Add, 2, 0, 1); | |
| 259 PURE(Float32Sub, 2, 0, 1); | |
| 260 PURE(Float32Mul, 2, 0, 1); | |
| 261 PURE(Float32Div, 2, 0, 1); | |
| 262 PURE(Float32Sqrt, 1, 0, 1); | |
| 263 PURE(Float32Equal, 2, 0, 1); | |
| 264 PURE(Float32LessThan, 2, 0, 1); | |
| 265 PURE(Float32LessThanOrEqual, 2, 0, 1); | |
| 266 PURE(Float64Add, 2, 0, 1); | |
| 267 PURE(Float64Sub, 2, 0, 1); | |
| 268 PURE(Float64Mul, 2, 0, 1); | |
| 269 PURE(Float64Div, 2, 0, 1); | |
| 270 PURE(Float64Mod, 2, 0, 1); | |
| 271 PURE(Float64Sqrt, 1, 0, 1); | |
| 272 PURE(Float64Equal, 2, 0, 1); | |
| 273 PURE(Float64LessThan, 2, 0, 1); | |
| 274 PURE(Float64LessThanOrEqual, 2, 0, 1); | |
| 275 PURE(LoadStackPointer, 0, 0, 1); | |
| 276 PURE(Float64ExtractLowWord32, 1, 0, 1); | |
| 277 PURE(Float64ExtractHighWord32, 1, 0, 1); | |
| 278 PURE(Float64InsertLowWord32, 2, 0, 1); | |
| 279 PURE(Float64InsertHighWord32, 2, 0, 1); | |
| 280 #undef PURE | |
| 171 } | 281 } |
| 172 | 282 |
| 173 | 283 |
| 174 const PureOperator kPureOperators[] = { | 284 TEST_F(MachinePureOperatorTest, PureOptionalOperators) { |
| 175 #define PURE(Name, value_input_count, control_input_count, value_output_count) \ | 285 #define OPTIONAL(Name, value_input_count, control_input_count, \ |
| 176 { \ | 286 value_output_count) \ |
| 177 &MachineOperatorBuilder::Name, IrOpcode::k##Name, value_input_count, \ | 287 CheckGlobalCaching(&MachineOperatorBuilder::Name, \ |
| 178 control_input_count, value_output_count \ | 288 MachineOperatorBuilder::k##Name); \ |
| 179 } | 289 CheckEnablingFlag(&MachineOperatorBuilder::Name, \ |
| 180 PURE(Word32And, 2, 0, 1), PURE(Word32Or, 2, 0, 1), PURE(Word32Xor, 2, 0, 1), | 290 MachineOperatorBuilder::k##Name); |
| 181 PURE(Word32Shl, 2, 0, 1), PURE(Word32Shr, 2, 0, 1), | |
| 182 PURE(Word32Sar, 2, 0, 1), PURE(Word32Ror, 2, 0, 1), | |
| 183 PURE(Word32Equal, 2, 0, 1), PURE(Word32Clz, 1, 0, 1), | |
| 184 PURE(Word64And, 2, 0, 1), PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1), | |
| 185 PURE(Word64Shl, 2, 0, 1), PURE(Word64Shr, 2, 0, 1), | |
| 186 PURE(Word64Sar, 2, 0, 1), PURE(Word64Ror, 2, 0, 1), | |
| 187 PURE(Word64Equal, 2, 0, 1), PURE(Int32Add, 2, 0, 1), | |
| 188 PURE(Int32AddWithOverflow, 2, 0, 2), PURE(Int32Sub, 2, 0, 1), | |
| 189 PURE(Int32SubWithOverflow, 2, 0, 2), PURE(Int32Mul, 2, 0, 1), | |
| 190 PURE(Int32MulHigh, 2, 0, 1), PURE(Int32Div, 2, 1, 1), | |
| 191 PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2, 1, 1), PURE(Uint32Mod, 2, 1, 1), | |
| 192 PURE(Int32LessThan, 2, 0, 1), PURE(Int32LessThanOrEqual, 2, 0, 1), | |
| 193 PURE(Uint32LessThan, 2, 0, 1), PURE(Uint32LessThanOrEqual, 2, 0, 1), | |
| 194 PURE(Int64Add, 2, 0, 1), PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1), | |
| 195 PURE(Int64Div, 2, 0, 1), PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1), | |
| 196 PURE(Uint64Mod, 2, 0, 1), PURE(Int64LessThan, 2, 0, 1), | |
| 197 PURE(Int64LessThanOrEqual, 2, 0, 1), PURE(Uint64LessThan, 2, 0, 1), | |
| 198 PURE(ChangeFloat32ToFloat64, 1, 0, 1), PURE(ChangeFloat64ToInt32, 1, 0, 1), | |
| 199 PURE(ChangeFloat64ToUint32, 1, 0, 1), PURE(ChangeInt32ToInt64, 1, 0, 1), | |
| 200 PURE(ChangeUint32ToFloat64, 1, 0, 1), PURE(ChangeUint32ToUint64, 1, 0, 1), | |
| 201 PURE(TruncateFloat64ToFloat32, 1, 0, 1), | |
| 202 PURE(TruncateFloat64ToInt32, 1, 0, 1), PURE(TruncateInt64ToInt32, 1, 0, 1), | |
| 203 PURE(Float32Add, 2, 0, 1), PURE(Float32Sub, 2, 0, 1), | |
| 204 PURE(Float32Mul, 2, 0, 1), PURE(Float32Div, 2, 0, 1), | |
| 205 PURE(Float32Abs, 1, 0, 1), PURE(Float32Sqrt, 1, 0, 1), | |
| 206 PURE(Float32Equal, 2, 0, 1), PURE(Float32LessThan, 2, 0, 1), | |
| 207 PURE(Float32LessThanOrEqual, 2, 0, 1), PURE(Float32Max, 2, 0, 1), | |
| 208 PURE(Float32Min, 2, 0, 1), PURE(Float64Add, 2, 0, 1), | |
| 209 PURE(Float64Sub, 2, 0, 1), PURE(Float64Mul, 2, 0, 1), | |
| 210 PURE(Float64Div, 2, 0, 1), PURE(Float64Mod, 2, 0, 1), | |
| 211 PURE(Float64Abs, 1, 0, 1), PURE(Float64Sqrt, 1, 0, 1), | |
| 212 PURE(Float64Equal, 2, 0, 1), PURE(Float64LessThan, 2, 0, 1), | |
| 213 PURE(Float64LessThanOrEqual, 2, 0, 1), PURE(Float64Max, 2, 0, 1), | |
| 214 PURE(Float64Min, 2, 0, 1), PURE(LoadStackPointer, 0, 0, 1), | |
| 215 PURE(Float64RoundDown, 1, 0, 1), PURE(Float64RoundTruncate, 1, 0, 1), | |
| 216 PURE(Float64RoundTiesAway, 1, 0, 1), PURE(Float64ExtractLowWord32, 1, 0, 1), | |
| 217 PURE(Float64ExtractHighWord32, 1, 0, 1), | |
| 218 PURE(Float64InsertLowWord32, 2, 0, 1), | |
| 219 PURE(Float64InsertHighWord32, 2, 0, 1) | |
| 220 #undef PURE | |
| 221 }; | |
| 222 | 291 |
| 223 | 292 OPTIONAL(Float32Max, 2, 0, 1); |
| 224 typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest; | 293 OPTIONAL(Float32Min, 2, 0, 1); |
| 225 | 294 OPTIONAL(Float32Abs, 1, 0, 1); |
| 226 } // namespace | 295 OPTIONAL(Float64Abs, 1, 0, 1); |
| 227 | 296 OPTIONAL(Float64Max, 2, 0, 1); |
| 228 | 297 OPTIONAL(Float64Min, 2, 0, 1); |
| 229 TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) { | 298 OPTIONAL(Float64RoundDown, 1, 0, 1); |
| 230 const PureOperator& pop = GetParam(); | 299 OPTIONAL(Float64RoundTruncate, 1, 0, 1); |
| 231 MachineOperatorBuilder machine1(zone(), type()); | 300 OPTIONAL(Float64RoundTiesAway, 1, 0, 1); |
| 232 MachineOperatorBuilder machine2(zone(), type()); | 301 #undef OPTIONAL |
| 233 EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)()); | |
| 234 } | 302 } |
| 235 | 303 |
| 236 | 304 |
| 237 TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) { | |
| 238 MachineOperatorBuilder machine(zone(), type()); | |
| 239 const PureOperator& pop = GetParam(); | |
| 240 const Operator* op = (machine.*pop.constructor)(); | |
| 241 | |
| 242 EXPECT_EQ(pop.value_input_count, op->ValueInputCount()); | |
| 243 EXPECT_EQ(0, op->EffectInputCount()); | |
| 244 EXPECT_EQ(pop.control_input_count, op->ControlInputCount()); | |
| 245 EXPECT_EQ(pop.value_input_count + pop.control_input_count, | |
| 246 OperatorProperties::GetTotalInputCount(op)); | |
| 247 | |
| 248 EXPECT_EQ(pop.value_output_count, op->ValueOutputCount()); | |
| 249 EXPECT_EQ(0, op->EffectOutputCount()); | |
| 250 EXPECT_EQ(0, op->ControlOutputCount()); | |
| 251 } | |
| 252 | |
| 253 | |
| 254 TEST_P(MachinePureOperatorTest, MarkedAsPure) { | |
| 255 MachineOperatorBuilder machine(zone(), type()); | |
| 256 const PureOperator& pop = GetParam(); | |
| 257 const Operator* op = (machine.*pop.constructor)(); | |
| 258 EXPECT_TRUE(op->HasProperty(Operator::kPure)); | |
| 259 } | |
| 260 | |
| 261 | |
| 262 TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) { | |
| 263 MachineOperatorBuilder machine(zone(), type()); | |
| 264 const PureOperator& pop = GetParam(); | |
| 265 const Operator* op = (machine.*pop.constructor)(); | |
| 266 EXPECT_EQ(pop.opcode, op->opcode()); | |
| 267 } | |
| 268 | |
| 269 | |
| 270 INSTANTIATE_TEST_CASE_P( | |
| 271 MachineOperatorTest, MachinePureOperatorTest, | |
| 272 ::testing::Combine(::testing::ValuesIn(kMachineReps), | |
| 273 ::testing::ValuesIn(kPureOperators))); | |
| 274 | |
| 275 #endif // GTEST_HAS_COMBINE | |
| 276 | |
| 277 | |
| 278 // ----------------------------------------------------------------------------- | 305 // ----------------------------------------------------------------------------- |
| 279 // Pseudo operators. | 306 // Pseudo operators. |
| 280 | 307 |
| 281 | 308 |
| 282 namespace { | 309 namespace { |
| 283 | 310 |
| 284 typedef TestWithZone MachineOperatorTest; | 311 typedef TestWithZone MachineOperatorTest; |
| 285 | 312 |
| 286 } // namespace | 313 } // namespace |
| 287 | 314 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 EXPECT_EQ(machine.Uint64Div(), machine.UintDiv()); | 352 EXPECT_EQ(machine.Uint64Div(), machine.UintDiv()); |
| 326 EXPECT_EQ(machine.Int64Mod(), machine.IntMod()); | 353 EXPECT_EQ(machine.Int64Mod(), machine.IntMod()); |
| 327 EXPECT_EQ(machine.Uint64Mod(), machine.UintMod()); | 354 EXPECT_EQ(machine.Uint64Mod(), machine.UintMod()); |
| 328 EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan()); | 355 EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan()); |
| 329 EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual()); | 356 EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual()); |
| 330 } | 357 } |
| 331 | 358 |
| 332 } // namespace compiler | 359 } // namespace compiler |
| 333 } // namespace internal | 360 } // namespace internal |
| 334 } // namespace v8 | 361 } // namespace v8 |
| OLD | NEW |