5 #include "src/compiler/graph-assembler.h" 7 #include "src/code-factory.h" 8 #include "src/compiler/linkage.h" 14 GraphAssembler::GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control,
18 current_effect_(effect),
19 current_control_(control) {}
21 Node* GraphAssembler::IntPtrConstant(intptr_t value) {
22 return jsgraph()->IntPtrConstant(value);
25 Node* GraphAssembler::Int32Constant(int32_t value) {
26 return jsgraph()->Int32Constant(value);
29 Node* GraphAssembler::Int64Constant(
int64_t value) {
30 return jsgraph()->Int64Constant(value);
33 Node* GraphAssembler::UniqueIntPtrConstant(intptr_t value) {
34 return graph()->NewNode(
35 machine()->Is64() ? common()->Int64Constant(value)
36 : common()->Int32Constant(static_cast<int32_t>(value)));
39 Node* GraphAssembler::SmiConstant(int32_t value) {
40 return jsgraph()->SmiConstant(value);
43 Node* GraphAssembler::Uint32Constant(int32_t value) {
44 return jsgraph()->Uint32Constant(value);
47 Node* GraphAssembler::Float64Constant(
double value) {
48 return jsgraph()->Float64Constant(value);
51 Node* GraphAssembler::HeapConstant(Handle<HeapObject>
object) {
52 return jsgraph()->HeapConstant(
object);
56 Node* GraphAssembler::ExternalConstant(ExternalReference ref) {
57 return jsgraph()->ExternalConstant(ref);
60 Node* GraphAssembler::CEntryStubConstant(
int result_size) {
61 return jsgraph()->CEntryStubConstant(result_size);
64 Node* GraphAssembler::LoadFramePointer() {
65 return graph()->NewNode(machine()->LoadFramePointer());
68 #define SINGLETON_CONST_DEF(Name) \ 69 Node* GraphAssembler::Name() { return jsgraph()->Name(); } 70 JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DEF)
71 #undef SINGLETON_CONST_DEF 73 #define PURE_UNOP_DEF(Name) \ 74 Node* GraphAssembler::Name(Node* input) { \ 75 return graph()->NewNode(machine()->Name(), input); \ 77 PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF)
80 #define PURE_BINOP_DEF(Name) \ 81 Node* GraphAssembler::Name(Node* left, Node* right) { \ 82 return graph()->NewNode(machine()->Name(), left, right); \ 84 PURE_ASSEMBLER_MACH_BINOP_LIST(PURE_BINOP_DEF)
87 #define CHECKED_BINOP_DEF(Name) \ 88 Node* GraphAssembler::Name(Node* left, Node* right) { \ 89 return graph()->NewNode(machine()->Name(), left, right, current_control_); \ 91 CHECKED_ASSEMBLER_MACH_BINOP_LIST(CHECKED_BINOP_DEF)
92 #undef CHECKED_BINOP_DEF 94 Node* GraphAssembler::Float64RoundDown(Node* value) {
95 CHECK(machine()->Float64RoundDown().IsSupported());
96 return graph()->NewNode(machine()->Float64RoundDown().op(), value);
99 Node* GraphAssembler::Float64RoundTruncate(Node* value) {
100 CHECK(machine()->Float64RoundTruncate().IsSupported());
101 return graph()->NewNode(machine()->Float64RoundTruncate().op(), value);
104 Node* GraphAssembler::Projection(
int index, Node* value) {
105 return graph()->NewNode(common()->Projection(index), value, current_control_);
108 Node* GraphAssembler::Allocate(PretenureFlag pretenure, Node* size) {
109 return current_control_ = current_effect_ =
110 graph()->NewNode(simplified()->AllocateRaw(Type::Any(), pretenure),
111 size, current_effect_, current_control_);
114 Node* GraphAssembler::LoadField(FieldAccess
const& access, Node*
object) {
115 return current_effect_ =
116 graph()->NewNode(simplified()->LoadField(access),
object,
117 current_effect_, current_control_);
120 Node* GraphAssembler::LoadElement(ElementAccess
const& access, Node*
object,
122 return current_effect_ =
123 graph()->NewNode(simplified()->LoadElement(access),
object, index,
124 current_effect_, current_control_);
127 Node* GraphAssembler::StoreField(FieldAccess
const& access, Node*
object,
129 return current_effect_ =
130 graph()->NewNode(simplified()->StoreField(access),
object, value,
131 current_effect_, current_control_);
134 Node* GraphAssembler::StoreElement(ElementAccess
const& access, Node*
object,
135 Node* index, Node* value) {
136 return current_effect_ =
137 graph()->NewNode(simplified()->StoreElement(access),
object, index,
138 value, current_effect_, current_control_);
141 Node* GraphAssembler::DebugBreak() {
142 return current_effect_ = graph()->NewNode(machine()->DebugBreak(),
143 current_effect_, current_control_);
146 Node* GraphAssembler::Unreachable() {
147 return current_effect_ = graph()->NewNode(common()->Unreachable(),
148 current_effect_, current_control_);
151 Node* GraphAssembler::Store(StoreRepresentation rep, Node*
object, Node* offset,
153 return current_effect_ =
154 graph()->NewNode(machine()->Store(rep),
object, offset, value,
155 current_effect_, current_control_);
158 Node* GraphAssembler::Load(MachineType rep, Node*
object, Node* offset) {
159 return current_effect_ =
160 graph()->NewNode(machine()->Load(rep),
object, offset,
161 current_effect_, current_control_);
164 Node* GraphAssembler::StoreUnaligned(MachineRepresentation rep, Node*
object,
165 Node* offset, Node* value) {
166 Operator
const*
const op =
167 (rep == MachineRepresentation::kWord8 ||
168 machine()->UnalignedStoreSupported(rep))
169 ? machine()->Store(StoreRepresentation(rep, kNoWriteBarrier))
170 : machine()->UnalignedStore(rep);
171 return current_effect_ = graph()->NewNode(op,
object, offset, value,
172 current_effect_, current_control_);
175 Node* GraphAssembler::LoadUnaligned(MachineType rep, Node*
object,
177 Operator
const*
const op =
178 (rep.representation() == MachineRepresentation::kWord8 ||
179 machine()->UnalignedLoadSupported(rep.representation()))
180 ? machine()->Load(rep)
181 : machine()->UnalignedLoad(rep);
182 return current_effect_ = graph()->NewNode(op,
object, offset, current_effect_,
186 Node* GraphAssembler::Retain(Node* buffer) {
187 return current_effect_ =
188 graph()->NewNode(common()->Retain(), buffer, current_effect_);
191 Node* GraphAssembler::UnsafePointerAdd(Node* base, Node* external) {
192 return current_effect_ =
193 graph()->NewNode(machine()->UnsafePointerAdd(), base, external,
194 current_effect_, current_control_);
197 Node* GraphAssembler::ToNumber(Node* value) {
198 return current_effect_ =
199 graph()->NewNode(ToNumberOperator(), ToNumberBuiltinConstant(),
200 value, NoContextConstant(), current_effect_);
203 Node* GraphAssembler::BitcastWordToTagged(Node* value) {
204 return current_effect_ =
205 graph()->NewNode(machine()->BitcastWordToTagged(), value,
206 current_effect_, current_control_);
209 Node* GraphAssembler::Word32PoisonOnSpeculation(Node* value) {
210 return current_effect_ =
211 graph()->NewNode(machine()->Word32PoisonOnSpeculation(), value,
212 current_effect_, current_control_);
215 Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason,
216 VectorSlotPair
const& feedback,
217 Node* condition, Node* frame_state,
218 IsSafetyCheck is_safety_check) {
219 return current_control_ = current_effect_ = graph()->NewNode(
220 common()->DeoptimizeIf(DeoptimizeKind::kEager, reason, feedback,
222 condition, frame_state, current_effect_, current_control_);
225 Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeReason reason,
226 VectorSlotPair
const& feedback,
227 Node* condition, Node* frame_state,
228 IsSafetyCheck is_safety_check) {
229 return current_control_ = current_effect_ = graph()->NewNode(
230 common()->DeoptimizeUnless(DeoptimizeKind::kEager, reason,
231 feedback, is_safety_check),
232 condition, frame_state, current_effect_, current_control_);
235 void GraphAssembler::Branch(Node* condition, GraphAssemblerLabel<0u>* if_true,
236 GraphAssemblerLabel<0u>* if_false,
237 IsSafetyCheck is_safety_check) {
238 DCHECK_NOT_NULL(current_control_);
240 BranchHint hint = BranchHint::kNone;
241 if (if_true->IsDeferred() != if_false->IsDeferred()) {
242 hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
245 Node* branch = graph()->NewNode(common()->Branch(hint, is_safety_check),
246 condition, current_control_);
248 current_control_ = graph()->NewNode(common()->IfTrue(), branch);
251 current_control_ = graph()->NewNode(common()->IfFalse(), branch);
252 MergeState(if_false);
254 current_control_ =
nullptr;
255 current_effect_ =
nullptr;
259 Node* GraphAssembler::ExtractCurrentControl() {
260 Node* result = current_control_;
261 current_control_ =
nullptr;
265 Node* GraphAssembler::ExtractCurrentEffect() {
266 Node* result = current_effect_;
267 current_effect_ =
nullptr;
271 void GraphAssembler::Reset(Node* effect, Node* control) {
272 current_effect_ = effect;
273 current_control_ = control;
276 Operator
const* GraphAssembler::ToNumberOperator() {
277 if (!to_number_operator_.is_set()) {
279 Builtins::CallableFor(jsgraph()->isolate(), Builtins::kToNumber);
280 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
281 auto call_descriptor = Linkage::GetStubCallDescriptor(
282 graph()->zone(), callable.descriptor(),
283 callable.descriptor().GetStackParameterCount(), flags,
284 Operator::kEliminatable);
285 to_number_operator_.set(common()->Call(call_descriptor));
287 return to_number_operator_.get();