| Index: src/compiler/simplified-lowering.cc
|
| diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
|
| index cf76002872e8d3e20f676f499ec5ab2e2c04f64e..a541161f88706a81fc862468f638b8d1101672eb 100644
|
| --- a/src/compiler/simplified-lowering.cc
|
| +++ b/src/compiler/simplified-lowering.cc
|
| @@ -72,67 +72,57 @@ namespace {
|
| // need the signedness information to produce the correct value.
|
| class UseInfo {
|
| public:
|
| - // Constructors
|
| - // ================================================================
|
| -
|
| - // Uses truncating to the preferred representation.
|
| + UseInfo(MachineType preferred, Truncation truncation)
|
| + : preferred_(preferred), truncation_(truncation) {
|
| + DCHECK(preferred == (preferred & kRepMask));
|
| + }
|
| static UseInfo TruncatingWord32() {
|
| - return UseInfo(kTypeInt32 | kTypeUint32 | kRepWord32);
|
| + return UseInfo(kRepWord32, Truncation::Word32());
|
| }
|
| static UseInfo TruncatingWord64() {
|
| - return UseInfo(kTypeInt64 | kTypeUint64 | kRepWord64);
|
| + return UseInfo(kRepWord64, Truncation::Word64());
|
| + }
|
| + static UseInfo Bool() { return UseInfo(kRepBit, Truncation::Bool()); }
|
| + static UseInfo Float32() {
|
| + return UseInfo(kRepFloat32, Truncation::Float32());
|
| + }
|
| + static UseInfo Float64() {
|
| + return UseInfo(kRepFloat64, Truncation::Float64());
|
| }
|
| - static UseInfo Bool() { return UseInfo(kMachBool); }
|
| - static UseInfo Float32() { return UseInfo(kMachFloat32); }
|
| - static UseInfo Float64() { return UseInfo(kMachFloat64); }
|
| static UseInfo PointerInt() {
|
| return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64();
|
| }
|
| + static UseInfo AnyTagged() { return UseInfo(kRepTagged, Truncation::Any()); }
|
|
|
| - // Non-truncating uses.
|
| - static UseInfo AnyTagged() { return UseInfo(kMachAnyTagged); }
|
| - static UseInfo Any() { return UseInfo(kTypeAny); }
|
| + // Undetermined representation.
|
| + static UseInfo Any() { return UseInfo(kMachNone, Truncation::Any()); }
|
| + static UseInfo None() { return UseInfo(kMachNone, Truncation::None()); }
|
|
|
| - // Ignored-value 'use'.
|
| - static UseInfo None() { return UseInfo(kMachNone); }
|
| -
|
| - // Truncating to a representation that is smaller than the preferred
|
| + // Truncation to a representation that is smaller than the preferred
|
| // one.
|
| static UseInfo Float64TruncatingToWord32() {
|
| - return UseInfo(kRepFloat64 | kTypeInt32 | kTypeUint32);
|
| + return UseInfo(kRepFloat64, Truncation::Word32());
|
| }
|
| static UseInfo Word64TruncatingToWord32() {
|
| - return UseInfo(kRepWord64 | kTypeInt32 | kTypeUint32);
|
| - }
|
| - static UseInfo AnyTruncatingToBool() { return UseInfo(kTypeBool); }
|
| -
|
| - UseInfo(MachineTypeUnion representation, MachineTypeUnion truncation)
|
| - : type_(representation | truncation) {
|
| - DCHECK(base::bits::CountPopulation32(representation & kRepMask) == 1);
|
| - DCHECK((representation & kTypeMask) == 0);
|
| - DCHECK((truncation & kRepMask) == 0);
|
| - // TODO(jarin) Check/normalize truncation?
|
| + return UseInfo(kRepWord64, Truncation::Word32());
|
| }
|
| -
|
| - // Queries
|
| - // ================================================================
|
| - MachineType GetRepresentation() const {
|
| - return static_cast<MachineType>(type_ & kRepMask);
|
| + static UseInfo AnyTruncatingToBool() {
|
| + return UseInfo(kMachNone, Truncation::Bool());
|
| }
|
|
|
| - // This should only be used by the Enqueue method.
|
| - MachineTypeUnion machine_type() const { return type_; }
|
| + MachineType preferred() const { return preferred_; }
|
| + Truncation truncation() const { return truncation_; }
|
|
|
| private:
|
| - explicit UseInfo(MachineTypeUnion type) : type_(type) {}
|
| -
|
| - MachineTypeUnion type_;
|
| + MachineType preferred_;
|
| + Truncation truncation_;
|
| };
|
|
|
|
|
| UseInfo UseInfoFromMachineType(MachineType type) {
|
| MachineTypeUnion rep = RepresentationOf(type);
|
| DCHECK((rep & kTypeMask) == 0);
|
| +
|
| if (rep & kRepTagged) return UseInfo::AnyTagged();
|
| if (rep & kRepFloat64) {
|
| DCHECK((rep & kRepWord64) == 0);
|
| @@ -169,11 +159,29 @@ UseInfo UseInfoForBasePointer(const ElementAccess& access) {
|
| class RepresentationSelector {
|
| public:
|
| // Information for each node tracked during the fixpoint.
|
| - struct NodeInfo {
|
| - MachineTypeUnion use : 15; // Union of all usages for the node.
|
| - bool queued : 1; // Bookkeeping for the traversal.
|
| - bool visited : 1; // Bookkeeping for the traversal.
|
| - MachineTypeUnion output : 15; // Output type of the node.
|
| + class NodeInfo {
|
| + public:
|
| + // Adds new use to the node. Returns true if something has changed
|
| + // and the node has to be requeued.
|
| + bool AddUse(UseInfo info) {
|
| + Truncation old_truncation = truncation_;
|
| + truncation_ = Truncation::Generalize(truncation_, info.truncation());
|
| + return truncation_ != old_truncation;
|
| + }
|
| +
|
| + void set_queued(bool value) { queued_ = value; }
|
| + bool queued() const { return queued_; }
|
| + void set_visited() { visited_ = true; }
|
| + bool visited() const { return visited_; }
|
| + Truncation truncation() const { return truncation_; }
|
| + void set_output_type(MachineTypeUnion type) { output_ = type; }
|
| + MachineTypeUnion output_type() const { return output_; }
|
| +
|
| + private:
|
| + bool queued_ = false; // Bookkeeping for the traversal.
|
| + bool visited_ = false; // Bookkeeping for the traversal.
|
| + MachineTypeUnion output_ = kMachNone; // Output type of the node.
|
| + Truncation truncation_ = Truncation::None(); // Information about uses.
|
| };
|
|
|
| RepresentationSelector(JSGraph* jsgraph, Zone* zone,
|
| @@ -181,15 +189,13 @@ class RepresentationSelector {
|
| SourcePositionTable* source_positions)
|
| : jsgraph_(jsgraph),
|
| count_(jsgraph->graph()->NodeCount()),
|
| - info_(zone->NewArray<NodeInfo>(count_)),
|
| + info_(count_, zone),
|
| nodes_(zone),
|
| replacements_(zone),
|
| phase_(PROPAGATE),
|
| changer_(changer),
|
| queue_(zone),
|
| source_positions_(source_positions) {
|
| - memset(info_, 0, sizeof(NodeInfo) * count_);
|
| -
|
| safe_int_additive_range_ =
|
| Type::Range(-std::pow(2.0, 52.0), std::pow(2.0, 52.0), zone);
|
| }
|
| @@ -204,11 +210,11 @@ class RepresentationSelector {
|
| Node* node = queue_.front();
|
| NodeInfo* info = GetInfo(node);
|
| queue_.pop();
|
| - info->queued = false;
|
| + info->set_queued(false);
|
| TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
|
| - VisitNode(node, info->use, NULL);
|
| + VisitNode(node, info->truncation(), NULL);
|
| TRACE(" ==> output ");
|
| - PrintInfo(info->output);
|
| + PrintInfo(info->output_type());
|
| TRACE("\n");
|
| }
|
|
|
| @@ -218,11 +224,12 @@ class RepresentationSelector {
|
| // Process nodes from the collected {nodes_} vector.
|
| for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) {
|
| Node* node = *i;
|
| + NodeInfo* info = GetInfo(node);
|
| TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
|
| // Reuse {VisitNode()} so the representation rules are in one place.
|
| SourcePositionTable::Scope scope(
|
| source_positions_, source_positions_->GetSourcePosition(node));
|
| - VisitNode(node, GetUseInfo(node), lowering);
|
| + VisitNode(node, info->truncation(), lowering);
|
| }
|
|
|
| // Perform the final replacements.
|
| @@ -242,34 +249,31 @@ class RepresentationSelector {
|
| // Enqueue {node} if the {use} contains new information for that node.
|
| // Add {node} to {nodes_} if this is the first time it's been visited.
|
| void Enqueue(Node* node, UseInfo use_info = UseInfo::None()) {
|
| - MachineTypeUnion use = use_info.machine_type();
|
| -
|
| if (phase_ != PROPAGATE) return;
|
| NodeInfo* info = GetInfo(node);
|
| - if (!info->visited) {
|
| + if (!info->visited()) {
|
| // First visit of this node.
|
| - info->visited = true;
|
| - info->queued = true;
|
| + info->set_visited();
|
| + info->set_queued(true);
|
| nodes_.push_back(node);
|
| queue_.push(node);
|
| TRACE(" initial: ");
|
| - info->use |= use;
|
| - PrintUseInfo(node);
|
| + info->AddUse(use_info);
|
| + PrintTruncation(info->truncation());
|
| return;
|
| }
|
| TRACE(" queue?: ");
|
| - PrintUseInfo(node);
|
| - if ((info->use & use) != use) {
|
| + PrintTruncation(info->truncation());
|
| + if (info->AddUse(use_info)) {
|
| // New usage information for the node is available.
|
| - if (!info->queued) {
|
| + if (!info->queued()) {
|
| queue_.push(node);
|
| - info->queued = true;
|
| + info->set_queued(true);
|
| TRACE(" added: ");
|
| } else {
|
| TRACE(" inqueue: ");
|
| }
|
| - info->use |= use;
|
| - PrintUseInfo(node);
|
| + PrintTruncation(info->truncation());
|
| }
|
| }
|
|
|
| @@ -281,7 +285,7 @@ class RepresentationSelector {
|
| // instruction.
|
| DCHECK((output & kRepMask) == 0 ||
|
| base::bits::IsPowerOfTwo32(output & kRepMask));
|
| - GetInfo(node)->output = output;
|
| + GetInfo(node)->set_output_type(output);
|
| }
|
|
|
| bool BothInputsAre(Node* node, Type* type) {
|
| @@ -297,7 +301,7 @@ class RepresentationSelector {
|
| Enqueue(input, UseInfo::TruncatingWord32());
|
| } else {
|
| // In the change phase, insert a change before the use if necessary.
|
| - MachineTypeUnion output = GetInfo(input)->output;
|
| + MachineTypeUnion output = GetInfo(input)->output_type();
|
| if ((output & (kRepBit | kRepWord8 | kRepWord16 | kRepWord32)) == 0) {
|
| // Output representation doesn't match usage.
|
| TRACE(" truncate-to-int32: #%d:%s(@%d #%d:%s) ", node->id(),
|
| @@ -319,10 +323,10 @@ class RepresentationSelector {
|
| void ConvertInput(Node* node, int index, UseInfo use) {
|
| Node* input = node->InputAt(index);
|
| // In the change phase, insert a change before the use if necessary.
|
| - if (use.GetRepresentation() == kMachNone)
|
| + if (use.preferred() == kMachNone)
|
| return; // No input requirement on the use.
|
| - MachineTypeUnion output = GetInfo(input)->output;
|
| - if ((output & kRepMask) != use.GetRepresentation()) {
|
| + MachineTypeUnion output = GetInfo(input)->output_type();
|
| + if ((output & kRepMask) != use.preferred()) {
|
| // Output representation doesn't match usage.
|
| TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
|
| index, input->id(), input->op()->mnemonic());
|
| @@ -331,8 +335,8 @@ class RepresentationSelector {
|
| TRACE(" to ");
|
| PrintUseInfo(use);
|
| TRACE("\n");
|
| - Node* n =
|
| - changer_->GetRepresentationFor(input, output, use.machine_type());
|
| + Node* n = changer_->GetRepresentationFor(input, output, use.preferred(),
|
| + use.truncation());
|
| node->ReplaceInput(index, n);
|
| }
|
| }
|
| @@ -440,13 +444,13 @@ class RepresentationSelector {
|
| }
|
|
|
| // Infer representation for phi-like nodes.
|
| - static MachineType GetRepresentationForPhi(Node* node, MachineTypeUnion use) {
|
| + static MachineType GetRepresentationForPhi(Node* node, Truncation use) {
|
| // Phis adapt to the output representation their uses demand.
|
| Type* upper = NodeProperties::GetType(node);
|
| if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
|
| // We are within 32 bits range => pick kRepWord32.
|
| return kRepWord32;
|
| - } else if (!CanObserveNonWord32(use)) {
|
| + } else if (use.TruncatesToWord32()) {
|
| // We only use 32 bits.
|
| return kRepWord32;
|
| } else if (upper->Is(Type::Boolean())) {
|
| @@ -462,10 +466,10 @@ class RepresentationSelector {
|
| }
|
|
|
| // Helper for handling selects.
|
| - void VisitSelect(Node* node, MachineTypeUnion use,
|
| + void VisitSelect(Node* node, Truncation truncation,
|
| SimplifiedLowering* lowering) {
|
| ProcessInput(node, 0, UseInfo::Bool());
|
| - MachineType output = GetRepresentationForPhi(node, use);
|
| + MachineType output = GetRepresentationForPhi(node, truncation);
|
|
|
| Type* upper = NodeProperties::GetType(node);
|
| MachineType output_type =
|
| @@ -482,16 +486,16 @@ class RepresentationSelector {
|
| }
|
| }
|
| // Convert inputs to the output representation of this phi, pass the
|
| - // use truncation along.
|
| - UseInfo input_use(output, use & kTypeMask);
|
| + // truncation truncation along.
|
| + UseInfo input_use(output, truncation);
|
| ProcessInput(node, 1, input_use);
|
| ProcessInput(node, 2, input_use);
|
| }
|
|
|
| // Helper for handling phis.
|
| - void VisitPhi(Node* node, MachineTypeUnion use,
|
| + void VisitPhi(Node* node, Truncation truncation,
|
| SimplifiedLowering* lowering) {
|
| - MachineType output = GetRepresentationForPhi(node, use);
|
| + MachineType output = GetRepresentationForPhi(node, truncation);
|
|
|
| Type* upper = NodeProperties::GetType(node);
|
| MachineType output_type =
|
| @@ -509,8 +513,8 @@ class RepresentationSelector {
|
| }
|
|
|
| // Convert inputs to the output representation of this phi, pass the
|
| - // use truncation along.
|
| - UseInfo input_use(output, use & kTypeMask);
|
| + // truncation truncation along.
|
| + UseInfo input_use(output, truncation);
|
| for (int i = 0; i < node->InputCount(); i++) {
|
| ProcessInput(node, i, i < values ? input_use : UseInfo::None());
|
| }
|
| @@ -550,7 +554,7 @@ class RepresentationSelector {
|
| new (zone->New(sizeof(ZoneVector<MachineType>)))
|
| ZoneVector<MachineType>(node->InputCount(), zone);
|
| for (int i = 0; i < node->InputCount(); i++) {
|
| - MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output;
|
| + MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output_type();
|
| (*types)[i] = static_cast<MachineType>(input_type);
|
| }
|
| NodeProperties::ChangeOp(node,
|
| @@ -571,34 +575,20 @@ class RepresentationSelector {
|
| return changer_->Float64OperatorFor(node->opcode());
|
| }
|
|
|
| - bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) {
|
| + bool CanLowerToInt32Binop(Node* node, Truncation use) {
|
| return BothInputsAre(node, Type::Signed32()) &&
|
| - (!CanObserveNonWord32(use) ||
|
| + (use.TruncatesToWord32() ||
|
| NodeProperties::GetType(node)->Is(Type::Signed32()));
|
| }
|
|
|
| - bool CanLowerToWord32AdditiveBinop(Node* node, MachineTypeUnion use) {
|
| + bool CanLowerToWord32AdditiveBinop(Node* node, Truncation use) {
|
| return BothInputsAre(node, safe_int_additive_range_) &&
|
| - !CanObserveNonWord32(use);
|
| - }
|
| -
|
| - bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) {
|
| - return BothInputsAre(node, Type::Unsigned32()) &&
|
| - (!CanObserveNonWord32(use) ||
|
| - NodeProperties::GetType(node)->Is(Type::Unsigned32()));
|
| - }
|
| -
|
| - static bool CanObserveNonWord32(MachineTypeUnion use) {
|
| - return (use & kTypeMask & ~(kTypeInt32 | kTypeUint32)) != 0;
|
| - }
|
| -
|
| - static bool CanObserveNaN(MachineTypeUnion use) {
|
| - return (use & (kTypeNumber | kTypeAny)) != 0;
|
| + use.TruncatesToWord32();
|
| }
|
|
|
| // Dispatching routine for visiting the node {node} with the usage {use}.
|
| // Depending on the operator, propagate new usage info to the inputs.
|
| - void VisitNode(Node* node, MachineTypeUnion use,
|
| + void VisitNode(Node* node, Truncation truncation,
|
| SimplifiedLowering* lowering) {
|
| switch (node->opcode()) {
|
| //------------------------------------------------------------------
|
| @@ -638,9 +628,9 @@ class RepresentationSelector {
|
| Enqueue(NodeProperties::GetControlInput(node, 0));
|
| break;
|
| case IrOpcode::kSelect:
|
| - return VisitSelect(node, use, lowering);
|
| + return VisitSelect(node, truncation, lowering);
|
| case IrOpcode::kPhi:
|
| - return VisitPhi(node, use, lowering);
|
| + return VisitPhi(node, truncation, lowering);
|
| case IrOpcode::kCall:
|
| return VisitCall(node, lowering);
|
|
|
| @@ -663,7 +653,7 @@ class RepresentationSelector {
|
| //------------------------------------------------------------------
|
| case IrOpcode::kBooleanNot: {
|
| if (lower()) {
|
| - MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
|
| + MachineTypeUnion input = GetInfo(node->InputAt(0))->output_type();
|
| if (input & kRepBit) {
|
| // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
|
| node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
|
| @@ -682,7 +672,7 @@ class RepresentationSelector {
|
| }
|
| case IrOpcode::kBooleanToNumber: {
|
| if (lower()) {
|
| - MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
|
| + MachineTypeUnion input = GetInfo(node->InputAt(0))->output_type();
|
| if (input & kRepBit) {
|
| // BooleanToNumber(x: kRepBit) => x
|
| DeferReplacement(node, node->InputAt(0));
|
| @@ -721,7 +711,7 @@ class RepresentationSelector {
|
| case IrOpcode::kNumberSubtract: {
|
| // Add and subtract reduce to Int32Add/Sub if the inputs
|
| // are already integers and all uses are truncating.
|
| - if (CanLowerToWord32AdditiveBinop(node, use)) {
|
| + if (CanLowerToWord32AdditiveBinop(node, truncation)) {
|
| // => signed Int32Add/Sub
|
| VisitInt32Binop(node);
|
| if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
|
| @@ -735,7 +725,7 @@ class RepresentationSelector {
|
| case IrOpcode::kNumberMultiply: {
|
| NumberMatcher right(node->InputAt(1));
|
| if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa.
|
| - if (CanLowerToInt32Binop(node, use)) {
|
| + if (CanLowerToInt32Binop(node, truncation)) {
|
| // => signed Int32Mul
|
| VisitInt32Binop(node);
|
| if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
|
| @@ -748,13 +738,14 @@ class RepresentationSelector {
|
| break;
|
| }
|
| case IrOpcode::kNumberDivide: {
|
| - if (CanLowerToInt32Binop(node, use)) {
|
| + if (CanLowerToInt32Binop(node, truncation)) {
|
| // => signed Int32Div
|
| VisitInt32Binop(node);
|
| if (lower()) DeferReplacement(node, lowering->Int32Div(node));
|
| break;
|
| }
|
| - if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) {
|
| + if (BothInputsAre(node, Type::Unsigned32()) &&
|
| + truncation.TruncatesNaNToZero()) {
|
| // => unsigned Uint32Div
|
| VisitUint32Binop(node);
|
| if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
|
| @@ -766,13 +757,14 @@ class RepresentationSelector {
|
| break;
|
| }
|
| case IrOpcode::kNumberModulus: {
|
| - if (CanLowerToInt32Binop(node, use)) {
|
| + if (CanLowerToInt32Binop(node, truncation)) {
|
| // => signed Int32Mod
|
| VisitInt32Binop(node);
|
| if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
|
| break;
|
| }
|
| - if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) {
|
| + if (BothInputsAre(node, Type::Unsigned32()) &&
|
| + truncation.TruncatesNaNToZero()) {
|
| // => unsigned Uint32Mod
|
| VisitUint32Binop(node);
|
| if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
|
| @@ -901,21 +893,27 @@ class RepresentationSelector {
|
| ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset
|
| ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length
|
| ProcessRemainingInputs(node, 3);
|
| - // Tagged overrides everything if we have to do a typed array bounds
|
| - // check, because we may need to return undefined then.
|
| +
|
| MachineType output_type;
|
| - if (use & kRepTagged) {
|
| - output_type = kMachAnyTagged;
|
| - } else if (use & kRepFloat64) {
|
| - if (access.machine_type() & kRepFloat32) {
|
| + if (truncation.TruncatesUndefinedToZeroOrNaN()) {
|
| + if (truncation.TruncatesNaNToZero()) {
|
| + // If undefined is truncated to a non-NaN number, we can use
|
| + // the load's representation.
|
| output_type = access.machine_type();
|
| } else {
|
| - output_type = kMachFloat64;
|
| + // If undefined is truncated to a number, but the use can
|
| + // observe NaN, we need to output at least the float32
|
| + // representation.
|
| + if (access.machine_type() & kRepFloat32) {
|
| + output_type = access.machine_type();
|
| + } else {
|
| + output_type = kMachFloat64;
|
| + }
|
| }
|
| - } else if (use & kRepFloat32) {
|
| - output_type = kMachFloat32;
|
| } else {
|
| - output_type = access.machine_type();
|
| + // If undefined is not truncated away, we need to have the tagged
|
| + // representation.
|
| + output_type = kMachAnyTagged;
|
| }
|
| SetOutput(node, output_type);
|
| if (lower()) lowering->DoLoadBuffer(node, output_type, changer_);
|
| @@ -1125,7 +1123,7 @@ class RepresentationSelector {
|
| replacement->op()->mnemonic());
|
|
|
| if (replacement->id() < count_ &&
|
| - GetInfo(replacement)->output == GetInfo(node)->output) {
|
| + GetInfo(replacement)->output_type() == GetInfo(node)->output_type()) {
|
| // Replace with a previously existing node eagerly only if the type is the
|
| // same.
|
| node->ReplaceUses(replacement);
|
| @@ -1140,12 +1138,6 @@ class RepresentationSelector {
|
| node->NullAllInputs(); // Node is now dead.
|
| }
|
|
|
| - void PrintUseInfo(Node* node) {
|
| - TRACE("#%d:%-20s ", node->id(), node->op()->mnemonic());
|
| - PrintInfo(GetUseInfo(node));
|
| - TRACE("\n");
|
| - }
|
| -
|
| void PrintInfo(MachineTypeUnion info) {
|
| if (FLAG_trace_representation) {
|
| OFStream os(stdout);
|
| @@ -1153,17 +1145,24 @@ class RepresentationSelector {
|
| }
|
| }
|
|
|
| + void PrintTruncation(Truncation truncation) {
|
| + if (FLAG_trace_representation) {
|
| + OFStream os(stdout);
|
| + os << truncation.description();
|
| + }
|
| + }
|
| +
|
| void PrintUseInfo(UseInfo info) {
|
| if (FLAG_trace_representation) {
|
| OFStream os(stdout);
|
| - os << static_cast<MachineType>(info.machine_type());
|
| + os << info.preferred() << ":" << info.truncation().description();
|
| }
|
| }
|
|
|
| private:
|
| JSGraph* jsgraph_;
|
| size_t const count_; // number of nodes in the graph
|
| - NodeInfo* info_; // node id -> usage information
|
| + ZoneVector<NodeInfo> info_; // node id -> usage information
|
| NodeVector nodes_; // collected nodes
|
| NodeVector replacements_; // replacements to be done after lowering
|
| Phase phase_; // current phase of algorithm
|
| @@ -1182,8 +1181,6 @@ class RepresentationSelector {
|
| DCHECK(node->id() < count_);
|
| return &info_[node->id()];
|
| }
|
| -
|
| - MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; }
|
| };
|
|
|
|
|
| @@ -1226,7 +1223,8 @@ void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type,
|
| Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
| Node* etrue =
|
| graph()->NewNode(machine()->Load(type), buffer, index, effect, if_true);
|
| - Node* vtrue = changer->GetRepresentationFor(etrue, type, output_type);
|
| + Node* vtrue = changer->GetRepresentationFor(
|
| + etrue, type, RepresentationOf(output_type), Truncation::None());
|
|
|
| Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
|
| Node* efalse = effect;
|
|
|