22 if (v8_flags.trace_turbo_loop) PrintF(__VA_ARGS__); \
31 limits_(graph->NodeCount(), zone),
32 reduced_(graph->NodeCount(), zone),
33 induction_vars_(zone) {}
39 while (!queue.empty()) {
40 Node* node = queue.front();
42 queued.
Set(node,
false);
45 bool all_inputs_visited =
true;
46 int inputs_end = (node->opcode() == IrOpcode::kLoop)
48 : node->op()->ControlInputCount();
49 for (
int i = 0;
i < inputs_end;
i++) {
51 all_inputs_visited =
false;
55 if (!all_inputs_visited)
continue;
61 for (
Edge edge : node->use_edges()) {
63 edge.from()->op()->ControlOutputCount() > 0) {
64 Node* use = edge.from();
65 if (use->opcode() == IrOpcode::kLoop &&
68 }
else if (!queued.
Get(use)) {
70 queued.
Set(use,
true);
82 <<
"): " << *bound << std::endl;
98 if (loop->
op()->ControlInputCount() != 2)
return;
103 if (constraint.left->opcode() == IrOpcode::kPhi &&
107 var->second->AddUpperBound(constraint.right, constraint.kind);
110 if (constraint.right->opcode() == IrOpcode::kPhi &&
114 var->second->AddLowerBound(constraint.left, constraint.kind);
121 switch (node->opcode()) {
122 case IrOpcode::kMerge:
124 case IrOpcode::kLoop:
126 case IrOpcode::kIfFalse:
128 case IrOpcode::kIfTrue:
130 case IrOpcode::kStart:
132 case IrOpcode::kLoopExit:
142 for (
int i = 1;
i < node->InputCount();
i++) {
160 case IrOpcode::kJSLessThan:
161 case IrOpcode::kNumberLessThan:
162 case IrOpcode::kSpeculativeNumberLessThan:
165 case IrOpcode::kJSGreaterThan:
168 case IrOpcode::kJSLessThanOrEqual:
169 case IrOpcode::kNumberLessThanOrEqual:
170 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
173 case IrOpcode::kJSGreaterThanOrEqual:
206 DCHECK_EQ(1, node->op()->ControlInputCount());
224 DCHECK_EQ(2, phi->op()->ValueInputCount());
230 if (arith->
opcode() == IrOpcode::kJSAdd ||
231 arith->
opcode() == IrOpcode::kNumberAdd ||
232 arith->
opcode() == IrOpcode::kSpeculativeNumberAdd ||
233 arith->
opcode() == IrOpcode::kSpeculativeAdditiveSafeIntegerAdd ||
234 arith->
opcode() == IrOpcode::kSpeculativeAdditiveSafeIntegerSubtract ||
235 arith->
opcode() == IrOpcode::kSpeculativeSmallIntegerAdd) {
237 }
else if (arith->
opcode() == IrOpcode::kJSSubtract ||
238 arith->
opcode() == IrOpcode::kNumberSubtract ||
239 arith->
opcode() == IrOpcode::kSpeculativeNumberSubtract ||
240 arith->
opcode() == IrOpcode::kSpeculativeSmallIntegerSubtract) {
251 if (input->opcode() == IrOpcode::kSpeculativeToNumber ||
252 input->opcode() == IrOpcode::kJSToNumber ||
253 input->opcode() == IrOpcode::kJSToNumberConvertBigInt) {
254 input = input->InputAt(0);
256 if (input != phi)
return nullptr;
258 Node* effect_phi =
nullptr;
260 if (use->opcode() == IrOpcode::kEffectPhi) {
265 if (!effect_phi)
return nullptr;
269 zone(), arithmeticType);
273 if (loop->
op()->ControlInputCount() != 2)
return;
274 TRACE(
"Loop variables for loop %i:", loop->
id());
277 edge.from()->opcode() == IrOpcode::kPhi) {
278 Node* phi = edge.from();
314 induction_var->
phi(),
322 if (induction_var->
phi()->
opcode() == IrOpcode::kInductionVariablePhi) {
326 DCHECK_EQ(value_count, control->
op()->ControlInputCount());
330 induction_var->
phi(),
338 if (!backedge_type.
Is(phi_type)) {
341 Node* backedge_effect =
345 backedge_effect, backedge_control);
void ResetToCommonAncestor(FunctionalList other)
void AddLowerBound(Node *bound, ConstraintKind kind)
ZoneVector< Bound > lower_bounds_
void AddUpperBound(Node *bound, ConstraintKind kind)
const ZoneVector< Bound > & lower_bounds()
ZoneVector< Bound > upper_bounds_
const ZoneVector< Bound > & upper_bounds()
Node * effect_phi() const
void VisitIf(Node *node, bool polarity)
void VisitLoopExit(Node *node)
const InductionVariable * FindInductionVariable(Node *node)
InductionVariable * TryGetInductionVariable(Node *phi)
void ChangeToInductionVariablePhis()
void VisitStart(Node *node)
CommonOperatorBuilder * common()
NodeAuxData< bool > reduced_
void ChangeToPhisAndInsertGuards()
void AddCmpToLimits(VariableLimits *limits, Node *node, InductionVariable::ConstraintKind kind, bool polarity)
ZoneMap< int, InductionVariable * > induction_vars_
void VisitNode(Node *node)
void VisitBackedge(Node *from, Node *loop)
const int kAssumedLoopEntryIndex
void VisitOtherControl(Node *node)
void DetectInductionVariables(Node *loop)
NodeAuxData< VariableLimits > limits_
void VisitMerge(Node *node)
LoopVariableOptimizer(TFGraph *graph, CommonOperatorBuilder *common, Zone *zone)
void VisitLoop(Node *node)
void TakeConditionsFromFirstControl(Node *node)
bool Set(Node *node, T const &data)
V8_INLINE void Set(Node *node, State state)
V8_INLINE State Get(const Node *node)
static void ChangeOp(Node *node, const Operator *new_op)
static Type GetType(const Node *node)
static bool IsControlEdge(Edge edge)
static Node * GetEffectInput(Node *node, int index=0)
static Node * GetControlInput(Node *node, int index=0)
constexpr IrOpcode::Value opcode() const
void TrimInputCount(int new_input_count)
const Operator * op() const
void ReplaceInput(int index, Node *new_to)
Node * InputAt(int index) const
void InsertInput(Zone *zone, int index, Node *new_to)
Node * NewNode(const Operator *op, int input_count, Node *const *inputs, bool incomplete=false)
MachineRepresentation PhiRepresentationOf(const Operator *const op)
V8_EXPORT_PRIVATE FlagValues v8_flags
other heap size generate builtins concurrently on separate threads in mksnapshot track concurrent recompilation artificial compilation delay in ms max number of threads that concurrent Turbofan can use(0 for unbounded)") DEFINE_BOOL( stress_concurrent_inlining
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)