Commit feb93dd6 authored by bgeron's avatar bgeron Committed by Commit bot

[turbolizer] Show a label with a shorter parameter for some opcodes.

With this patch, every node in turbo-*.json has an opcode, a title, and
a label. The label field is new; the opcode and title were already
there. The title is for the mouseover text. The label is what will be
displayed in the graph view, unless it's too long, in which case only
the opcode will be displayed. (This is similar to the preexisting
behaviour of putting titles in labels, except that the titles were
rarely short enough to fit in a label.)

With this patch, the labels generated are in practice the same as the
titles we had before, except for LoadField and StoreField, which will be
rendered as LoadField[[+432]] and StoreField[[+432]] (if 432 was the
offset).

This diff adds an overloadable method

    virtual void Operator1<T>::PrintParameter(ostream&, PrintVerbosity)

for each type T to Operator1. Its default implementation just uses
operator<<(ostream&, T const&) and adds square brackets around it, but
it is overridden for FieldAccess to print "[+432]" in the example case.

BUG=
R=jarin,danno

Review-Url: https://codereview.chromium.org/2093013002
Cr-Commit-Position: refs/heads/master@{#37795}
parent 0e20ae6d
......@@ -881,7 +881,7 @@ const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
Operator::ZeroIfPure(descriptor->properties()),
Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
void PrintParameter(std::ostream& os) const override {
void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
os << "[" << *parameter() << "]";
}
};
......@@ -899,7 +899,7 @@ const Operator* CommonOperatorBuilder::TailCall(
descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
0, 1, descriptor) {}
void PrintParameter(std::ostream& os) const override {
void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
os << "[" << *parameter() << "]";
}
};
......
......@@ -124,10 +124,12 @@ class JSONGraphNodeWriter {
} else {
os_ << ",\n";
}
std::ostringstream label;
label << *node->op();
std::ostringstream label, title;
node->op()->PrintTo(label, Operator::PrintVerbosity::kSilent);
node->op()->PrintTo(title, Operator::PrintVerbosity::kVerbose);
os_ << "{\"id\":" << SafeId(node) << ",\"label\":\"" << Escaped(label, "\"")
<< "\"";
<< "\""
<< ",\"title\":\"" << Escaped(title, "\"") << "\"";
IrOpcode::Value opcode = node->opcode();
if (IrOpcode::IsPhiOpcode(opcode)) {
os_ << ",\"rankInputs\":[0," << NodeProperties::FirstControlIndex(node)
......
......@@ -44,8 +44,9 @@ std::ostream& operator<<(std::ostream& os, const Operator& op) {
return os;
}
void Operator::PrintTo(std::ostream& os) const { os << mnemonic(); }
void Operator::PrintToImpl(std::ostream& os, PrintVerbosity verbose) const {
os << mnemonic();
}
} // namespace compiler
} // namespace internal
......
......@@ -50,6 +50,7 @@ class Operator : public ZoneObject {
kPure = kNoDeopt | kNoRead | kNoWrite | kNoThrow | kIdempotent
};
typedef base::Flags<Property, uint8_t> Properties;
enum class PrintVerbosity { kVerbose, kSilent };
// Constructor.
Operator(Opcode opcode, Properties properties, const char* mnemonic,
......@@ -111,11 +112,18 @@ class Operator : public ZoneObject {
}
// TODO(titzer): API for input and output types, for typechecking graph.
protected:
// Print the full operator into the given stream, including any
// static parameters. Useful for debugging and visualizing the IR.
virtual void PrintTo(std::ostream& os) const;
friend std::ostream& operator<<(std::ostream& os, const Operator& op);
void PrintTo(std::ostream& os,
PrintVerbosity verbose = PrintVerbosity::kVerbose) const {
// We cannot make PrintTo virtual, because default arguments to virtual
// methods are banned in the style guide.
return PrintToImpl(os, verbose);
}
protected:
virtual void PrintToImpl(std::ostream& os, PrintVerbosity verbose) const;
private:
Opcode opcode_;
......@@ -172,14 +180,19 @@ class Operator1 : public Operator {
size_t HashCode() const final {
return base::hash_combine(this->opcode(), this->hash_(this->parameter()));
}
virtual void PrintParameter(std::ostream& os) const {
os << "[" << this->parameter() << "]";
// For most parameter types, we have only a verbose way to print them, namely
// ostream << parameter. But for some types it is particularly useful to have
// a shorter way to print them for the node labels in Turbolizer. The
// following method can be overridden to provide a concise and a verbose
// printing of a parameter.
virtual void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
os << "[" << parameter() << "]";
}
protected:
void PrintTo(std::ostream& os) const final {
virtual void PrintToImpl(std::ostream& os, PrintVerbosity verbose) const {
os << mnemonic();
PrintParameter(os);
PrintParameter(os, verbose);
}
private:
......
......@@ -124,6 +124,15 @@ std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
return os;
}
template <>
void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
PrintVerbosity verbose) const {
if (verbose == PrintVerbosity::kVerbose) {
os << parameter();
} else {
os << "[+" << parameter().offset << "]";
}
}
bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) {
// On purpose we don't include the write barrier kind here, as this method is
......
......@@ -7,6 +7,7 @@
#include <iosfwd>
#include "src/compiler/operator.h"
#include "src/compiler/type-hints.h"
#include "src/handles.h"
#include "src/machine-type.h"
......@@ -79,6 +80,9 @@ std::ostream& operator<<(std::ostream&, FieldAccess const&);
FieldAccess const& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT;
template <>
void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
PrintVerbosity verbose) const;
// An access descriptor for loads/stores of indexed structures like characters
// in strings or off-heap backing stores. Accesses from either tagged or
......
......@@ -788,7 +788,7 @@ class GraphView extends View {
})
.append("title")
.text(function(l) {
return d.getLabel();
return d.getTitle();
})
if (d.type != undefined) {
d3.select(this).append("text")
......
......@@ -47,8 +47,8 @@ var Node = {
var inputWidth = this.inputs.length * NODE_INPUT_WIDTH;
return Math.max(inputWidth, this.width);
},
getLabel: function() {
return this.label;
getTitle: function() {
return this.title;
},
getDisplayLabel: function() {
var result = this.id + ":" + this.label;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment