[turbofan] Add a debug_name to Parameter operators.
R=bmeurer@chromium.org, mstarzinger@chromium.org BUG= Review URL: https://codereview.chromium.org/1090303004 Cr-Commit-Position: refs/heads/master@{#28002}
This commit is contained in:
parent
1ea118d592
commit
ab49ec14e3
@ -410,8 +410,8 @@ AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
|
||||
|
||||
Node* AstGraphBuilder::GetFunctionClosure() {
|
||||
if (!function_closure_.is_set()) {
|
||||
const Operator* op =
|
||||
common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex);
|
||||
const Operator* op = common()->Parameter(
|
||||
Linkage::kJSFunctionCallClosureParamIndex, "%closure");
|
||||
Node* node = NewNode(op, graph()->start());
|
||||
function_closure_.set(node);
|
||||
}
|
||||
@ -428,7 +428,8 @@ void AstGraphBuilder::CreateFunctionContext(bool constant_context) {
|
||||
|
||||
Node* AstGraphBuilder::NewOuterContextParam() {
|
||||
// Parameter (arity + 1) is special for the outer context of the function
|
||||
const Operator* op = common()->Parameter(info()->num_parameters() + 1);
|
||||
const Operator* op =
|
||||
common()->Parameter(info()->num_parameters() + 1, "%context");
|
||||
return NewNode(op, graph()->start());
|
||||
}
|
||||
|
||||
@ -436,7 +437,8 @@ Node* AstGraphBuilder::NewOuterContextParam() {
|
||||
Node* AstGraphBuilder::NewCurrentContextOsrValue() {
|
||||
// TODO(titzer): use a real OSR value here; a parameter works by accident.
|
||||
// Parameter (arity + 1) is special for the outer context of the function
|
||||
const Operator* op = common()->Parameter(info()->num_parameters() + 1);
|
||||
const Operator* op =
|
||||
common()->Parameter(info()->num_parameters() + 1, "%osr-context");
|
||||
return NewNode(op, graph()->start());
|
||||
}
|
||||
|
||||
@ -575,6 +577,20 @@ static LhsKind DetermineLhsKind(Expression* expr) {
|
||||
}
|
||||
|
||||
|
||||
static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) {
|
||||
#if DEBUG
|
||||
const AstRawString* name = scope->parameter(index)->raw_name();
|
||||
if (name && name->length() > 0) {
|
||||
char* data = zone->NewArray<char>(name->length() + 1);
|
||||
data[name->length()] = 0;
|
||||
memcpy(data, name->raw_data(), name->length());
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
|
||||
Scope* scope,
|
||||
Node* control_dependency)
|
||||
@ -592,15 +608,16 @@ AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
|
||||
DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
|
||||
|
||||
// Bind the receiver variable.
|
||||
Node* receiver = builder->graph()->NewNode(common()->Parameter(0),
|
||||
Node* receiver = builder->graph()->NewNode(common()->Parameter(0, "%this"),
|
||||
builder->graph()->start());
|
||||
values()->push_back(receiver);
|
||||
|
||||
// Bind all parameter variables. The parameter indices are shifted by 1
|
||||
// (receiver is parameter index -1 but environment index 0).
|
||||
for (int i = 0; i < scope->num_parameters(); ++i) {
|
||||
Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1),
|
||||
builder->graph()->start());
|
||||
const char* debug_name = GetDebugParameterName(graph()->zone(), scope, i);
|
||||
Node* parameter = builder->graph()->NewNode(
|
||||
common()->Parameter(i + 1, debug_name), builder->graph()->start());
|
||||
values()->push_back(parameter);
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,38 @@ size_t ProjectionIndexOf(const Operator* const op) {
|
||||
}
|
||||
|
||||
|
||||
int ParameterIndexOf(const Operator* const op) {
|
||||
DCHECK_EQ(IrOpcode::kParameter, op->opcode());
|
||||
return OpParameter<ParameterInfo>(op).index();
|
||||
}
|
||||
|
||||
|
||||
const ParameterInfo& ParameterInfoOf(const Operator* const op) {
|
||||
DCHECK_EQ(IrOpcode::kParameter, op->opcode());
|
||||
return OpParameter<ParameterInfo>(op);
|
||||
}
|
||||
|
||||
|
||||
bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
|
||||
return lhs.index() == rhs.index();
|
||||
}
|
||||
|
||||
|
||||
bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
|
||||
size_t hash_value(ParameterInfo const& p) { return p.index(); }
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
|
||||
if (i.debug_name()) os << i.debug_name() << '#';
|
||||
os << i.index();
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
#define CACHED_OP_LIST(V) \
|
||||
V(Always, Operator::kPure, 0, 0, 0, 1, 0, 0) \
|
||||
V(Dead, Operator::kFoldable, 0, 0, 0, 0, 0, 1) \
|
||||
@ -276,13 +308,13 @@ struct CommonOperatorGlobalCache final {
|
||||
#undef CACHED_PHI
|
||||
|
||||
template <int kIndex>
|
||||
struct ParameterOperator final : public Operator1<int> {
|
||||
struct ParameterOperator final : public Operator1<ParameterInfo> {
|
||||
ParameterOperator()
|
||||
: Operator1<int>( // --
|
||||
: Operator1<ParameterInfo>( // --
|
||||
IrOpcode::kParameter, Operator::kPure, // opcode
|
||||
"Parameter", // name
|
||||
1, 0, 0, 1, 0, 0, // counts,
|
||||
kIndex) {} // parameter
|
||||
ParameterInfo(kIndex, nullptr)) {} // parameter and name
|
||||
};
|
||||
#define CACHED_PARAMETER(index) \
|
||||
ParameterOperator<index> kParameter##index##Operator;
|
||||
@ -416,22 +448,25 @@ const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
|
||||
}
|
||||
|
||||
|
||||
const Operator* CommonOperatorBuilder::Parameter(int index) {
|
||||
switch (index) {
|
||||
const Operator* CommonOperatorBuilder::Parameter(int index,
|
||||
const char* debug_name) {
|
||||
if (!debug_name) {
|
||||
switch (index) {
|
||||
#define CACHED_PARAMETER(index) \
|
||||
case index: \
|
||||
return &cache_.kParameter##index##Operator;
|
||||
CACHED_PARAMETER_LIST(CACHED_PARAMETER)
|
||||
CACHED_PARAMETER_LIST(CACHED_PARAMETER)
|
||||
#undef CACHED_PARAMETER
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Uncached.
|
||||
return new (zone()) Operator1<int>( // --
|
||||
IrOpcode::kParameter, Operator::kPure, // opcode
|
||||
"Parameter", // name
|
||||
1, 0, 0, 1, 0, 0, // counts
|
||||
index); // parameter
|
||||
return new (zone()) Operator1<ParameterInfo>( // --
|
||||
IrOpcode::kParameter, Operator::kPure, // opcode
|
||||
"Parameter", // name
|
||||
1, 0, 0, 1, 0, 0, // counts
|
||||
ParameterInfo(index, debug_name)); // parameter info
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,6 +156,27 @@ std::ostream& operator<<(std::ostream&, FrameStateCallInfo const&);
|
||||
size_t ProjectionIndexOf(const Operator* const);
|
||||
|
||||
|
||||
// The {IrOpcode::kParameter} opcode represents an incoming parameter to the
|
||||
// function. This class bundles the index and a debug name for such operators.
|
||||
class ParameterInfo final {
|
||||
public:
|
||||
ParameterInfo(int index, const char* debug_name)
|
||||
: index_(index), debug_name_(debug_name) {}
|
||||
|
||||
int index() const { return index_; }
|
||||
const char* debug_name() const { return debug_name_; }
|
||||
|
||||
private:
|
||||
int index_;
|
||||
const char* debug_name_;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream&, ParameterInfo const&);
|
||||
|
||||
int ParameterIndexOf(const Operator* const);
|
||||
const ParameterInfo& ParameterInfoOf(const Operator* const);
|
||||
|
||||
|
||||
// Interface for building common operators that can be used at any level of IR,
|
||||
// including JavaScript, mid-level, and low-level.
|
||||
class CommonOperatorBuilder final : public ZoneObject {
|
||||
@ -184,7 +205,7 @@ class CommonOperatorBuilder final : public ZoneObject {
|
||||
const Operator* Start(int num_formal_parameters);
|
||||
const Operator* Loop(int control_input_count);
|
||||
const Operator* Merge(int control_input_count);
|
||||
const Operator* Parameter(int index);
|
||||
const Operator* Parameter(int index, const char* debug_name = nullptr);
|
||||
|
||||
const Operator* OsrNormalEntry();
|
||||
const Operator* OsrLoopEntry();
|
||||
|
@ -609,7 +609,8 @@ void InstructionSelector::VisitNode(Node* node) {
|
||||
case IrOpcode::kFinish:
|
||||
return MarkAsReference(node), VisitFinish(node);
|
||||
case IrOpcode::kParameter: {
|
||||
MachineType type = linkage()->GetParameterType(OpParameter<int>(node));
|
||||
MachineType type =
|
||||
linkage()->GetParameterType(ParameterIndexOf(node->op()));
|
||||
MarkAsRepresentation(type, node);
|
||||
return VisitParameter(node);
|
||||
}
|
||||
@ -968,7 +969,7 @@ void InstructionSelector::VisitFinish(Node* node) {
|
||||
|
||||
void InstructionSelector::VisitParameter(Node* node) {
|
||||
OperandGenerator g(this);
|
||||
int index = OpParameter<int>(node);
|
||||
int index = ParameterIndexOf(node->op());
|
||||
Emit(kArchNop,
|
||||
g.DefineAsLocation(node, linkage()->GetParameterLocation(index),
|
||||
linkage()->GetParameterType(index)));
|
||||
|
@ -235,7 +235,7 @@ Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) {
|
||||
Node* use = edge.from();
|
||||
switch (use->opcode()) {
|
||||
case IrOpcode::kParameter: {
|
||||
int index = 1 + OpParameter<int>(use->op());
|
||||
int index = 1 + ParameterIndexOf(use->op());
|
||||
if (index < inliner_inputs && index < inlinee_context_index) {
|
||||
// There is an input from the call, and the index is a value
|
||||
// projection but not the context, so rewire the input.
|
||||
|
@ -55,16 +55,6 @@ class Verifier::Visitor {
|
||||
Node* ValueInput(Node* node, int i = 0) {
|
||||
return NodeProperties::GetValueInput(node, i);
|
||||
}
|
||||
FieldAccess Field(Node* node) {
|
||||
DCHECK(node->opcode() == IrOpcode::kLoadField ||
|
||||
node->opcode() == IrOpcode::kStoreField);
|
||||
return OpParameter<FieldAccess>(node);
|
||||
}
|
||||
ElementAccess Element(Node* node) {
|
||||
DCHECK(node->opcode() == IrOpcode::kLoadElement ||
|
||||
node->opcode() == IrOpcode::kStoreElement);
|
||||
return OpParameter<ElementAccess>(node);
|
||||
}
|
||||
void CheckNotTyped(Node* node) {
|
||||
if (NodeProperties::IsTyped(node)) {
|
||||
std::ostringstream str;
|
||||
@ -714,7 +704,7 @@ void Verifier::Visitor::Check(Node* node) {
|
||||
// Object -> fieldtype
|
||||
// TODO(rossberg): activate once machine ops are typed.
|
||||
// CheckValueInputIs(node, 0, Type::Object());
|
||||
// CheckUpperIs(node, Field(node).type));
|
||||
// CheckUpperIs(node, FieldAccessOf(node->op()).type));
|
||||
break;
|
||||
case IrOpcode::kLoadBuffer:
|
||||
break;
|
||||
@ -722,13 +712,13 @@ void Verifier::Visitor::Check(Node* node) {
|
||||
// Object -> elementtype
|
||||
// TODO(rossberg): activate once machine ops are typed.
|
||||
// CheckValueInputIs(node, 0, Type::Object());
|
||||
// CheckUpperIs(node, Element(node).type));
|
||||
// CheckUpperIs(node, ElementAccessOf(node->op()).type));
|
||||
break;
|
||||
case IrOpcode::kStoreField:
|
||||
// (Object, fieldtype) -> _|_
|
||||
// TODO(rossberg): activate once machine ops are typed.
|
||||
// CheckValueInputIs(node, 0, Type::Object());
|
||||
// CheckValueInputIs(node, 1, Field(node).type));
|
||||
// CheckValueInputIs(node, 1, FieldAccessOf(node->op()).type));
|
||||
CheckNotTyped(node);
|
||||
break;
|
||||
case IrOpcode::kStoreBuffer:
|
||||
@ -737,7 +727,7 @@ void Verifier::Visitor::Check(Node* node) {
|
||||
// (Object, elementtype) -> _|_
|
||||
// TODO(rossberg): activate once machine ops are typed.
|
||||
// CheckValueInputIs(node, 0, Type::Object());
|
||||
// CheckValueInputIs(node, 1, Element(node).type));
|
||||
// CheckValueInputIs(node, 1, ElementAccessOf(node->op()).type));
|
||||
CheckNotTyped(node);
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user