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

Unified Diff: src/compiler/representation-change.h

Issue 1480433003: [turbofan] Introduce representation-change.cc, move stuff there, minus dead code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: src/compiler/representation-change.h
diff --git a/src/compiler/representation-change.h b/src/compiler/representation-change.h
index dfb82960a02317431005d6190d5a8a7eb443abc5..5503b76cc4e94f2cab515baed20a21bd98e1c5bd 100644
--- a/src/compiler/representation-change.h
+++ b/src/compiler/representation-change.h
@@ -5,11 +5,7 @@
#ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_
#define V8_COMPILER_REPRESENTATION_CHANGE_H_
-#include <sstream>
-
-#include "src/base/bits.h"
#include "src/compiler/js-graph.h"
-#include "src/compiler/machine-operator.h"
#include "src/compiler/simplified-operator.h"
namespace v8 {
@@ -35,12 +31,10 @@ class Truncation final {
bool TruncatesToWord32() const {
return LessGeneral(kind_, TruncationKind::kWord32);
}
-
bool TruncatesNaNToZero() {
return LessGeneral(kind_, TruncationKind::kWord32) ||
LessGeneral(kind_, TruncationKind::kBool);
}
-
bool TruncatesUndefinedToZeroOrNaN() {
return LessGeneral(kind_, TruncationKind::kFloat64) ||
LessGeneral(kind_, TruncationKind::kWord64);
@@ -51,26 +45,7 @@ class Truncation final {
bool operator!=(Truncation other) const { return !(*this == other); }
// Debug utilities.
- const char* description() {
- switch (kind()) {
- case TruncationKind::kNone:
- return "no-value-use";
- case TruncationKind::kBool:
- return "truncate-to-bool";
- case TruncationKind::kWord32:
- return "truncate-to-word32";
- case TruncationKind::kWord64:
- return "truncate-to-word64";
- case TruncationKind::kFloat32:
- return "truncate-to-float32";
- case TruncationKind::kFloat64:
- return "truncate-to-float64";
- case TruncationKind::kAny:
- return "no-truncation";
- }
- UNREACHABLE();
- return nullptr;
- }
+ const char* description() const;
private:
enum class TruncationKind : uint8_t {
@@ -88,58 +63,8 @@ class Truncation final {
TruncationKind kind_;
- // Partial order for truncations:
- //
- // kWord64 kAny
- // ^ ^
- // \ |
- // \ kFloat64 <--+
- // \ ^ ^ |
- // \ / | |
- // kWord32 kFloat32 kBool
- // ^ ^ ^
- // \ | /
- // \ | /
- // \ | /
- // \ | /
- // \ | /
- // kNone
- static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2) {
- if (LessGeneral(rep1, rep2)) return rep2;
- if (LessGeneral(rep2, rep1)) return rep1;
- // Handle the generalization of float64-representable values.
- if (LessGeneral(rep1, TruncationKind::kFloat64) &&
- LessGeneral(rep2, TruncationKind::kFloat64)) {
- return TruncationKind::kFloat64;
- }
- // All other combinations are illegal.
- FATAL("Tried to combine incompatible representations");
- return TruncationKind::kNone;
- }
-
- static bool LessGeneral(TruncationKind rep1, TruncationKind rep2) {
- switch (rep1) {
- case TruncationKind::kNone:
- return true;
- case TruncationKind::kBool:
- return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
- case TruncationKind::kWord32:
- return rep2 == TruncationKind::kWord32 ||
- rep2 == TruncationKind::kWord64 ||
- rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
- case TruncationKind::kWord64:
- return rep2 == TruncationKind::kWord64;
- case TruncationKind::kFloat32:
- return rep2 == TruncationKind::kFloat32 ||
- rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
- case TruncationKind::kFloat64:
- return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
- case TruncationKind::kAny:
- return rep2 == TruncationKind::kAny;
- }
- UNREACHABLE();
- return false;
- }
+ static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2);
+ static bool LessGeneral(TruncationKind rep1, TruncationKind rep2);
};
@@ -154,388 +79,17 @@ class RepresentationChanger final {
testing_type_errors_(false),
type_error_(false) {}
- // TODO(titzer): should Word64 also be implicitly convertable to others?
- static bool IsWord(MachineTypeUnion type) {
- return (type & (kRepWord8 | kRepWord16 | kRepWord32)) != 0;
- }
-
// Changes representation from {output_type} to {use_rep}. The {truncation}
// parameter is only used for sanity checking - if the changer cannot figure
// out signedness for the word32->float64 conversion, then we check that the
// uses truncate to word32 (so they do not care about signedness).
Node* GetRepresentationFor(Node* node, MachineTypeUnion output_type,
MachineTypeUnion use_rep,
- Truncation truncation = Truncation::None()) {
- DCHECK((use_rep & kRepMask) == use_rep);
- if (!base::bits::IsPowerOfTwo32(output_type & kRepMask)) {
- // There should be only one output representation.
- return TypeError(node, output_type, use_rep);
- }
- if (use_rep == (output_type & kRepMask)) {
- // Representations are the same. That's a no-op.
- return node;
- }
- if (IsWord(use_rep) && IsWord(output_type)) {
- // Both are words less than or equal to 32-bits.
- // Since loads of integers from memory implicitly sign or zero extend the
- // value to the full machine word size and stores implicitly truncate,
- // no representation change is necessary.
- return node;
- }
- if (use_rep & kRepTagged) {
- return GetTaggedRepresentationFor(node, output_type);
- } else if (use_rep & kRepFloat32) {
- return GetFloat32RepresentationFor(node, output_type, truncation);
- } else if (use_rep & kRepFloat64) {
- return GetFloat64RepresentationFor(node, output_type, truncation);
- } else if (use_rep & kRepBit) {
- return GetBitRepresentationFor(node, output_type);
- } else if (IsWord(use_rep)) {
- return GetWord32RepresentationFor(node, output_type);
- } else if (use_rep & kRepWord64) {
- return GetWord64RepresentationFor(node, output_type);
- } else {
- return node;
- }
- }
-
- Node* GetTaggedRepresentationFor(Node* node, MachineTypeUnion output_type) {
- // Eagerly fold representation changes for constants.
- switch (node->opcode()) {
- case IrOpcode::kNumberConstant:
- case IrOpcode::kHeapConstant:
- return node; // No change necessary.
- case IrOpcode::kInt32Constant:
- if (output_type & kTypeUint32) {
- uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
- return jsgraph()->Constant(static_cast<double>(value));
- } else if (output_type & kTypeInt32) {
- int32_t value = OpParameter<int32_t>(node);
- return jsgraph()->Constant(value);
- } else if (output_type & kRepBit) {
- return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
- : jsgraph()->TrueConstant();
- } else {
- return TypeError(node, output_type, kRepTagged);
- }
- case IrOpcode::kFloat64Constant:
- return jsgraph()->Constant(OpParameter<double>(node));
- case IrOpcode::kFloat32Constant:
- return jsgraph()->Constant(OpParameter<float>(node));
- default:
- break;
- }
- // Select the correct X -> Tagged operator.
- const Operator* op;
- if (output_type & kRepBit) {
- op = simplified()->ChangeBitToBool();
- } else if (IsWord(output_type)) {
- if (output_type & kTypeUint32) {
- op = simplified()->ChangeUint32ToTagged();
- } else if (output_type & kTypeInt32) {
- op = simplified()->ChangeInt32ToTagged();
- } else {
- return TypeError(node, output_type, kRepTagged);
- }
- } else if (output_type & kRepFloat32) { // float32 -> float64 -> tagged
- node = InsertChangeFloat32ToFloat64(node);
- op = simplified()->ChangeFloat64ToTagged();
- } else if (output_type & kRepFloat64) {
- op = simplified()->ChangeFloat64ToTagged();
- } else {
- return TypeError(node, output_type, kRepTagged);
- }
- return jsgraph()->graph()->NewNode(op, node);
- }
-
- Node* GetFloat32RepresentationFor(Node* node, MachineTypeUnion output_type,
- Truncation truncation) {
- // Eagerly fold representation changes for constants.
- switch (node->opcode()) {
- case IrOpcode::kFloat64Constant:
- case IrOpcode::kNumberConstant:
- return jsgraph()->Float32Constant(
- DoubleToFloat32(OpParameter<double>(node)));
- case IrOpcode::kInt32Constant:
- if (output_type & kTypeUint32) {
- uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
- return jsgraph()->Float32Constant(static_cast<float>(value));
- } else {
- int32_t value = OpParameter<int32_t>(node);
- return jsgraph()->Float32Constant(static_cast<float>(value));
- }
- case IrOpcode::kFloat32Constant:
- return node; // No change necessary.
- default:
- break;
- }
- // Select the correct X -> Float32 operator.
- const Operator* op;
- if (output_type & kRepBit) {
- return TypeError(node, output_type, kRepFloat32);
- } else if (IsWord(output_type)) {
- if (output_type & kTypeUint32) {
- op = machine()->ChangeUint32ToFloat64();
- } else {
- // Either the output is int32 or the uses only care about the
- // low 32 bits (so we can pick int32 safely).
- DCHECK(output_type & kTypeInt32 || truncation.TruncatesToWord32());
- op = machine()->ChangeInt32ToFloat64();
- }
- // int32 -> float64 -> float32
- node = jsgraph()->graph()->NewNode(op, node);
- op = machine()->TruncateFloat64ToFloat32();
- } else if (output_type & kRepTagged) {
- op = simplified()
- ->ChangeTaggedToFloat64(); // tagged -> float64 -> float32
- node = jsgraph()->graph()->NewNode(op, node);
- op = machine()->TruncateFloat64ToFloat32();
- } else if (output_type & kRepFloat64) {
- op = machine()->TruncateFloat64ToFloat32();
- } else {
- return TypeError(node, output_type, kRepFloat32);
- }
- return jsgraph()->graph()->NewNode(op, node);
- }
-
- Node* GetFloat64RepresentationFor(Node* node, MachineTypeUnion output_type,
- Truncation truncation) {
- // Eagerly fold representation changes for constants.
- switch (node->opcode()) {
- case IrOpcode::kNumberConstant:
- return jsgraph()->Float64Constant(OpParameter<double>(node));
- case IrOpcode::kInt32Constant:
- if (output_type & kTypeUint32) {
- uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
- return jsgraph()->Float64Constant(static_cast<double>(value));
- } else {
- int32_t value = OpParameter<int32_t>(node);
- return jsgraph()->Float64Constant(value);
- }
- case IrOpcode::kFloat64Constant:
- return node; // No change necessary.
- case IrOpcode::kFloat32Constant:
- return jsgraph()->Float64Constant(OpParameter<float>(node));
- default:
- break;
- }
- // Select the correct X -> Float64 operator.
- const Operator* op;
- if (output_type & kRepBit) {
- return TypeError(node, output_type, kRepFloat64);
- } else if (IsWord(output_type)) {
- if (output_type & kTypeUint32) {
- op = machine()->ChangeUint32ToFloat64();
- } else {
- // Either the output is int32 or the uses only care about the
- // low 32 bits (so we can pick int32 safely).
- DCHECK(output_type & kTypeInt32 || truncation.TruncatesToWord32());
- op = machine()->ChangeInt32ToFloat64();
- }
- } else if (output_type & kRepTagged) {
- op = simplified()->ChangeTaggedToFloat64();
- } else if (output_type & kRepFloat32) {
- op = machine()->ChangeFloat32ToFloat64();
- } else {
- return TypeError(node, output_type, kRepFloat64);
- }
- return jsgraph()->graph()->NewNode(op, node);
- }
-
- Node* MakeTruncatedInt32Constant(double value) {
- return jsgraph()->Int32Constant(DoubleToInt32(value));
- }
-
- Node* GetTruncatedWord32For(Node* node, MachineTypeUnion output_type) {
- // Eagerly fold truncations for constants.
- switch (node->opcode()) {
- case IrOpcode::kInt32Constant:
- return node; // No change necessary.
- case IrOpcode::kFloat32Constant:
- return jsgraph()->Int32Constant(
- DoubleToInt32(OpParameter<float>(node)));
- case IrOpcode::kNumberConstant:
- case IrOpcode::kFloat64Constant:
- return jsgraph()->Int32Constant(
- DoubleToInt32(OpParameter<double>(node)));
- default:
- break;
- }
- // Select the correct X -> Word32 truncation operator.
- const Operator* op = NULL;
- if (output_type & kRepFloat64) {
- op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
- } else if (output_type & kRepFloat32) {
- node = InsertChangeFloat32ToFloat64(node);
- op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
- } else if (output_type & kRepTagged) {
- node = InsertChangeTaggedToFloat64(node);
- op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
- } else {
- return TypeError(node, output_type, kRepWord32);
- }
- return jsgraph()->graph()->NewNode(op, node);
- }
-
- Node* GetWord32RepresentationFor(Node* node, MachineTypeUnion output_type) {
- // Eagerly fold representation changes for constants.
- switch (node->opcode()) {
- case IrOpcode::kInt32Constant:
- return node; // No change necessary.
- case IrOpcode::kFloat32Constant:
- return MakeTruncatedInt32Constant(OpParameter<float>(node));
- case IrOpcode::kNumberConstant:
- case IrOpcode::kFloat64Constant:
- return MakeTruncatedInt32Constant(OpParameter<double>(node));
- default:
- break;
- }
- // Select the correct X -> Word32 operator.
- const Operator* op;
- Type* type = NodeProperties::GetType(node);
-
- if (output_type & kRepBit) {
- return node; // Sloppy comparison -> word32
- } else if (output_type & kRepFloat64) {
- if (output_type & kTypeUint32 || type->Is(Type::Unsigned32())) {
- op = machine()->ChangeFloat64ToUint32();
- } else if (output_type & kTypeInt32 || type->Is(Type::Signed32())) {
- op = machine()->ChangeFloat64ToInt32();
- } else {
- op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
- }
- } else if (output_type & kRepFloat32) {
- node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32
- if (output_type & kTypeUint32 || type->Is(Type::Unsigned32())) {
- op = machine()->ChangeFloat64ToUint32();
- } else if (output_type & kTypeInt32 || type->Is(Type::Signed32())) {
- op = machine()->ChangeFloat64ToInt32();
- } else {
- op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
- }
- } else if (output_type & kRepTagged) {
- if (output_type & kTypeUint32 || type->Is(Type::Unsigned32())) {
- op = simplified()->ChangeTaggedToUint32();
- } else if (output_type & kTypeInt32 || type->Is(Type::Signed32())) {
- op = simplified()->ChangeTaggedToInt32();
- } else {
- node = InsertChangeTaggedToFloat64(node);
- op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
- }
- } else {
- return TypeError(node, output_type, kRepWord32);
- }
- return jsgraph()->graph()->NewNode(op, node);
- }
-
- Node* GetBitRepresentationFor(Node* node, MachineTypeUnion output_type) {
- // Eagerly fold representation changes for constants.
- switch (node->opcode()) {
- case IrOpcode::kHeapConstant: {
- Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node);
- DCHECK(value.is_identical_to(factory()->true_value()) ||
- value.is_identical_to(factory()->false_value()));
- return jsgraph()->Int32Constant(
- value.is_identical_to(factory()->true_value()) ? 1 : 0);
- }
- default:
- break;
- }
- // Select the correct X -> Bit operator.
- const Operator* op;
- if (output_type & kRepTagged) {
- op = simplified()->ChangeBoolToBit();
- } else {
- return TypeError(node, output_type, kRepBit);
- }
- return jsgraph()->graph()->NewNode(op, node);
- }
-
- Node* GetWord64RepresentationFor(Node* node, MachineTypeUnion output_type) {
- if (output_type & kRepBit) {
- return node; // Sloppy comparison -> word64
- }
- // Can't really convert Word64 to anything else. Purported to be internal.
- return TypeError(node, output_type, kRepWord64);
- }
-
- const Operator* Int32OperatorFor(IrOpcode::Value opcode) {
- switch (opcode) {
- case IrOpcode::kNumberAdd:
- return machine()->Int32Add();
- case IrOpcode::kNumberSubtract:
- return machine()->Int32Sub();
- case IrOpcode::kNumberMultiply:
- return machine()->Int32Mul();
- case IrOpcode::kNumberDivide:
- return machine()->Int32Div();
- case IrOpcode::kNumberModulus:
- return machine()->Int32Mod();
- case IrOpcode::kNumberBitwiseOr:
- return machine()->Word32Or();
- case IrOpcode::kNumberBitwiseXor:
- return machine()->Word32Xor();
- case IrOpcode::kNumberBitwiseAnd:
- return machine()->Word32And();
- case IrOpcode::kNumberEqual:
- return machine()->Word32Equal();
- case IrOpcode::kNumberLessThan:
- return machine()->Int32LessThan();
- case IrOpcode::kNumberLessThanOrEqual:
- return machine()->Int32LessThanOrEqual();
- default:
- UNREACHABLE();
- return NULL;
- }
- }
-
- const Operator* Uint32OperatorFor(IrOpcode::Value opcode) {
- switch (opcode) {
- case IrOpcode::kNumberAdd:
- return machine()->Int32Add();
- case IrOpcode::kNumberSubtract:
- return machine()->Int32Sub();
- case IrOpcode::kNumberMultiply:
- return machine()->Int32Mul();
- case IrOpcode::kNumberDivide:
- return machine()->Uint32Div();
- case IrOpcode::kNumberModulus:
- return machine()->Uint32Mod();
- case IrOpcode::kNumberEqual:
- return machine()->Word32Equal();
- case IrOpcode::kNumberLessThan:
- return machine()->Uint32LessThan();
- case IrOpcode::kNumberLessThanOrEqual:
- return machine()->Uint32LessThanOrEqual();
- default:
- UNREACHABLE();
- return NULL;
- }
- }
-
- const Operator* Float64OperatorFor(IrOpcode::Value opcode) {
- switch (opcode) {
- case IrOpcode::kNumberAdd:
- return machine()->Float64Add();
- case IrOpcode::kNumberSubtract:
- return machine()->Float64Sub();
- case IrOpcode::kNumberMultiply:
- return machine()->Float64Mul();
- case IrOpcode::kNumberDivide:
- return machine()->Float64Div();
- case IrOpcode::kNumberModulus:
- return machine()->Float64Mod();
- case IrOpcode::kNumberEqual:
- return machine()->Float64Equal();
- case IrOpcode::kNumberLessThan:
- return machine()->Float64LessThan();
- case IrOpcode::kNumberLessThanOrEqual:
- return machine()->Float64LessThanOrEqual();
- default:
- UNREACHABLE();
- return NULL;
- }
- }
+ Truncation truncation = Truncation::None());
+ const Operator* Int32OperatorFor(IrOpcode::Value opcode);
+ const Operator* Uint32OperatorFor(IrOpcode::Value opcode);
+ const Operator* Float64OperatorFor(IrOpcode::Value opcode);
+ MachineType TypeFromUpperBound(Type* type);
MachineType TypeForBasePointer(const FieldAccess& access) {
return access.tag() != 0 ? kMachAnyTagged : kMachPtr;
@@ -545,16 +99,6 @@ class RepresentationChanger final {
return access.tag() != 0 ? kMachAnyTagged : kMachPtr;
}
- MachineType TypeFromUpperBound(Type* type) {
- if (type->Is(Type::None()))
- return kTypeAny; // TODO(titzer): should be an error
- if (type->Is(Type::Signed32())) return kTypeInt32;
- if (type->Is(Type::Unsigned32())) return kTypeUint32;
- if (type->Is(Type::Number())) return kTypeNumber;
- if (type->Is(Type::Boolean())) return kTypeBool;
- return kTypeAny;
- }
-
private:
JSGraph* jsgraph_;
Isolate* isolate_;
@@ -564,34 +108,19 @@ class RepresentationChanger final {
bool testing_type_errors_; // If {true}, don't abort on a type error.
bool type_error_; // Set when a type error is detected.
+ Node* GetTaggedRepresentationFor(Node* node, MachineTypeUnion output_type);
+ Node* GetFloat32RepresentationFor(Node* node, MachineTypeUnion output_type,
+ Truncation truncation);
+ Node* GetFloat64RepresentationFor(Node* node, MachineTypeUnion output_type,
+ Truncation truncation);
+ Node* GetWord32RepresentationFor(Node* node, MachineTypeUnion output_type);
+ Node* GetBitRepresentationFor(Node* node, MachineTypeUnion output_type);
+ Node* GetWord64RepresentationFor(Node* node, MachineTypeUnion output_type);
Node* TypeError(Node* node, MachineTypeUnion output_type,
- MachineTypeUnion use) {
- type_error_ = true;
- if (!testing_type_errors_) {
- std::ostringstream out_str;
- out_str << static_cast<MachineType>(output_type);
-
- std::ostringstream use_str;
- use_str << static_cast<MachineType>(use);
-
- V8_Fatal(__FILE__, __LINE__,
- "RepresentationChangerError: node #%d:%s of "
- "%s cannot be changed to %s",
- node->id(), node->op()->mnemonic(), out_str.str().c_str(),
- use_str.str().c_str());
- }
- return node;
- }
-
- Node* InsertChangeFloat32ToFloat64(Node* node) {
- return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(),
- node);
- }
-
- Node* InsertChangeTaggedToFloat64(Node* node) {
- return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
- node);
- }
+ MachineTypeUnion use);
+ Node* MakeTruncatedInt32Constant(double value);
+ Node* InsertChangeFloat32ToFloat64(Node* node);
+ Node* InsertChangeTaggedToFloat64(Node* node);
JSGraph* jsgraph() const { return jsgraph_; }
Isolate* isolate() const { return isolate_; }

Powered by Google App Engine
This is Rietveld 408576698