Commit 002d5be8 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[gasm] Implement parts of js call reducer using the graph assembler

An initial investigation of using GraphAssembler in JSCallReducer.

This CL ports two simple reductions (ReduceMathUnary,
ReduceMathBinary) as well as a slightly more involved reduction with
branching control flow (ReduceStringPrototypeSubstring). The graph
assembler abstracts away the details of maintaining effect and control
edges. Resulting code ends up looking very similar to CSA.

Newly introduced:
- Typing through TNode.
- IfBuilder1 for nicer if-then-else sequences that return exactly 1
  value. Future CLs will add more convenience builders that follow this
  pattern.
- Many small readability improvements through helper functions.

Bug: v8:9972
Change-Id: Iaa186b76c006e07c8d69a74f340a4912577a32a5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1914204
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65095}
parent 438f72f4
...@@ -399,6 +399,13 @@ Node* GraphAssembler::LoadFramePointer() { ...@@ -399,6 +399,13 @@ Node* GraphAssembler::LoadFramePointer() {
JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DEF) JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DEF)
#undef SINGLETON_CONST_DEF #undef SINGLETON_CONST_DEF
#define SINGLETON_CONST_TEST_DEF(Name) \
Node* GraphAssembler::Is##Name(Node* value) { \
return ReferenceEqual(value, Name##Constant()); \
}
JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_TEST_DEF)
#undef SINGLETON_CONST_TEST_DEF
#define PURE_UNOP_DEF(Name) \ #define PURE_UNOP_DEF(Name) \
Node* GraphAssembler::Name(Node* input) { \ Node* GraphAssembler::Name(Node* input) { \
return AddNode(graph()->NewNode(machine()->Name(), input)); \ return AddNode(graph()->NewNode(machine()->Name(), input)); \
...@@ -496,6 +503,40 @@ Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object, ...@@ -496,6 +503,40 @@ Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object,
index, value, effect(), control())); index, value, effect(), control()));
} }
Node* GraphAssembler::StringLength(Node* string) {
return AddNode(graph()->NewNode(simplified()->StringLength(), string));
}
Node* GraphAssembler::ReferenceEqual(Node* lhs, Node* rhs) {
return AddNode(graph()->NewNode(simplified()->ReferenceEqual(), lhs, rhs));
}
Node* GraphAssembler::NumberMin(Node* lhs, Node* rhs) {
return AddNode(graph()->NewNode(simplified()->NumberMin(), lhs, rhs));
}
Node* GraphAssembler::NumberMax(Node* lhs, Node* rhs) {
return AddNode(graph()->NewNode(simplified()->NumberMax(), lhs, rhs));
}
Node* GraphAssembler::NumberAdd(Node* lhs, Node* rhs) {
return AddNode(graph()->NewNode(simplified()->NumberAdd(), lhs, rhs));
}
Node* GraphAssembler::NumberLessThan(Node* lhs, Node* rhs) {
return AddNode(graph()->NewNode(simplified()->NumberLessThan(), lhs, rhs));
}
Node* GraphAssembler::StringSubstring(Node* string, Node* from, Node* to) {
return AddNode(graph()->NewNode(simplified()->StringSubstring(), string, from,
to, effect(), control()));
}
Node* GraphAssembler::TypeGuard(Type type, Node* value) {
return AddNode(
graph()->NewNode(common()->TypeGuard(type), value, effect(), control()));
}
Node* GraphAssembler::DebugBreak() { Node* GraphAssembler::DebugBreak() {
return AddNode( return AddNode(
graph()->NewNode(machine()->DebugBreak(), effect(), control())); graph()->NewNode(machine()->DebugBreak(), effect(), control()));
......
...@@ -163,12 +163,12 @@ class GraphAssemblerLabel { ...@@ -163,12 +163,12 @@ class GraphAssemblerLabel {
MachineRepresentation representations_[VarCount + 1]; MachineRepresentation representations_[VarCount + 1];
}; };
class GraphAssembler { class V8_EXPORT_PRIVATE GraphAssembler {
public: public:
// Constructs a GraphAssembler. If {schedule} is not null, the graph assembler // Constructs a GraphAssembler. If {schedule} is not null, the graph assembler
// will maintain the schedule as it updates blocks. // will maintain the schedule as it updates blocks.
GraphAssembler(JSGraph* jsgraph, Zone* zone, Schedule* schedule = nullptr); GraphAssembler(JSGraph* jsgraph, Zone* zone, Schedule* schedule = nullptr);
~GraphAssembler(); virtual ~GraphAssembler();
void Reset(BasicBlock* block); void Reset(BasicBlock* block);
void InitializeEffectControl(Node* effect, Node* control); void InitializeEffectControl(Node* effect, Node* control);
...@@ -220,6 +220,10 @@ class GraphAssembler { ...@@ -220,6 +220,10 @@ class GraphAssembler {
JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DECL) JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DECL)
#undef SINGLETON_CONST_DECL #undef SINGLETON_CONST_DECL
#define SINGLETON_CONST_TEST_DECL(Name) Node* Is##Name(Node* value);
JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_TEST_DECL)
#undef SINGLETON_CONST_TEST_DECL
#define PURE_UNOP_DECL(Name) Node* Name(Node* input); #define PURE_UNOP_DECL(Name) Node* Name(Node* input);
PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DECL) PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DECL)
#undef PURE_UNOP_DECL #undef PURE_UNOP_DECL
...@@ -253,6 +257,15 @@ class GraphAssembler { ...@@ -253,6 +257,15 @@ class GraphAssembler {
Node* StoreField(FieldAccess const&, Node* object, Node* value); Node* StoreField(FieldAccess const&, Node* object, Node* value);
Node* StoreElement(ElementAccess const&, Node* object, Node* index, Node* StoreElement(ElementAccess const&, Node* object, Node* index,
Node* value); Node* value);
Node* StringLength(Node* string);
Node* ReferenceEqual(Node* lhs, Node* rhs);
Node* NumberMin(Node* lhs, Node* rhs);
Node* NumberMax(Node* lhs, Node* rhs);
Node* NumberLessThan(Node* lhs, Node* rhs);
Node* NumberAdd(Node* lhs, Node* rhs);
Node* StringSubstring(Node* string, Node* from, Node* to);
Node* TypeGuard(Type type, Node* value);
Node* Store(StoreRepresentation rep, Node* object, Node* offset, Node* value); Node* Store(StoreRepresentation rep, Node* object, Node* offset, Node* value);
Node* Load(MachineType type, Node* object, Node* offset); Node* Load(MachineType type, Node* object, Node* offset);
...@@ -324,7 +337,7 @@ class GraphAssembler { ...@@ -324,7 +337,7 @@ class GraphAssembler {
Node* control() { return control_; } Node* control() { return control_; }
Node* effect() { return effect_; } Node* effect() { return effect_; }
private: protected:
class BasicBlockUpdater; class BasicBlockUpdater;
template <typename... Vars> template <typename... Vars>
......
This diff is collapsed.
...@@ -43,10 +43,12 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer { ...@@ -43,10 +43,12 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
using Flags = base::Flags<Flag>; using Flags = base::Flags<Flag>;
JSCallReducer(Editor* editor, JSGraph* jsgraph, JSHeapBroker* broker, JSCallReducer(Editor* editor, JSGraph* jsgraph, JSHeapBroker* broker,
Flags flags, CompilationDependencies* dependencies) Zone* temp_zone, Flags flags,
CompilationDependencies* dependencies)
: AdvancedReducer(editor), : AdvancedReducer(editor),
jsgraph_(jsgraph), jsgraph_(jsgraph),
broker_(broker), broker_(broker),
temp_zone_(temp_zone),
flags_(flags), flags_(flags),
dependencies_(dependencies) {} dependencies_(dependencies) {}
...@@ -250,6 +252,7 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer { ...@@ -250,6 +252,7 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
Graph* graph() const; Graph* graph() const;
JSGraph* jsgraph() const { return jsgraph_; } JSGraph* jsgraph() const { return jsgraph_; }
JSHeapBroker* broker() const { return broker_; } JSHeapBroker* broker() const { return broker_; }
Zone* temp_zone() const { return temp_zone_; }
Isolate* isolate() const; Isolate* isolate() const;
Factory* factory() const; Factory* factory() const;
NativeContextRef native_context() const; NativeContextRef native_context() const;
...@@ -261,6 +264,7 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer { ...@@ -261,6 +264,7 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
JSGraph* const jsgraph_; JSGraph* const jsgraph_;
JSHeapBroker* const broker_; JSHeapBroker* const broker_;
Zone* const temp_zone_;
Flags const flags_; Flags const flags_;
CompilationDependencies* const dependencies_; CompilationDependencies* const dependencies_;
std::set<Node*> waitlist_; std::set<Node*> waitlist_;
......
...@@ -1285,6 +1285,7 @@ struct InliningPhase { ...@@ -1285,6 +1285,7 @@ struct InliningPhase {
data->broker(), data->common(), data->broker(), data->common(),
data->machine(), temp_zone); data->machine(), temp_zone);
JSCallReducer call_reducer(&graph_reducer, data->jsgraph(), data->broker(), JSCallReducer call_reducer(&graph_reducer, data->jsgraph(), data->broker(),
temp_zone,
data->info()->is_bailout_on_uninitialized() data->info()->is_bailout_on_uninitialized()
? JSCallReducer::kBailoutOnUninitialized ? JSCallReducer::kBailoutOnUninitialized
: JSCallReducer::kNoFlags, : JSCallReducer::kNoFlags,
......
...@@ -37,7 +37,7 @@ class JSCallReducerTest : public TypedGraphTest { ...@@ -37,7 +37,7 @@ class JSCallReducerTest : public TypedGraphTest {
// TODO(titzer): mock the GraphReducer here for better unit testing. // TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph(), tick_counter()); GraphReducer graph_reducer(zone(), graph(), tick_counter());
JSCallReducer reducer(&graph_reducer, &jsgraph, broker(), JSCallReducer reducer(&graph_reducer, &jsgraph, broker(), zone(),
JSCallReducer::kNoFlags, &deps_); JSCallReducer::kNoFlags, &deps_);
return reducer.Reduce(node); return reducer.Reduce(node);
} }
......
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