26 uint32_t unrolling_count =
28 if (unrolling_count == 0)
return;
30 uint32_t iteration_count = unrolling_count + 1;
32 uint32_t copied_size =
static_cast<uint32_t
>(loop->size()) * iteration_count;
36 NodeCopier copier(graph, copied_size, &copies, unrolling_count);
38 copier.
CopyNodes(graph, tmp_zone, graph->NewNode(common->
Dead()),
45 for (
Node* node : copies) {
47 node->opcode() != IrOpcode::kTerminate && node->UseCount() == 0) {
52#define COPY(node, n) copier.map(node, n)
53#define FOREACH_COPY_INDEX(i) for (uint32_t i = 0; i < unrolling_count; i++)
55 for (
Node* node : loop_node->
uses()) {
56 switch (node->opcode()) {
57 case IrOpcode::kBranch: {
61 if (stack_check->
opcode() != IrOpcode::kStackPointerGreaterThan) {
67 for (
Edge use_edge :
COPY(stack_check,
i)->use_edges()) {
81 case IrOpcode::kLoopExit: {
83 if (node->InputAt(1) == loop_node) {
86 merge_inputs[0] =
node;
87 for (uint32_t
i = 1;
i < iteration_count;
i++) {
88 merge_inputs[
i] =
COPY(node,
i - 1);
90 Node* merge_node = graph->NewNode(common->
Merge(iteration_count),
91 iteration_count, merge_inputs);
93 for (
Edge use_edge : node->use_edges()) {
94 Node* use = use_edge.from();
95 if (loop->count(use) == 1) {
100 if (use->opcode() == IrOpcode::kLoopExitEffect) {
101 phi_operator = common->
EffectPhi(iteration_count);
103 DCHECK(use->opcode() == IrOpcode::kLoopExitValue);
104 phi_operator = common->
Phi(
110 for (uint32_t
i = 1;
i < iteration_count;
i++) {
111 phi_inputs[
i] =
COPY(use,
i - 1);
113 phi_inputs[iteration_count] = merge_node;
115 graph->NewNode(phi_operator, iteration_count + 1, phi_inputs);
118 phi->ReplaceInput(0, use);
119 }
else if (use != merge_node) {
121 use->ReplaceInput(use_edge.index(), merge_node);
128 case IrOpcode::kTerminate: {
147 for (
int input_index = 1; input_index < loop_node->
InputCount();
149 Node* last_iteration_input =
150 COPY(loop_node, unrolling_count - 1)->
InputAt(input_index);
151 for (uint32_t copy_index = unrolling_count - 1; copy_index > 0;
153 COPY(loop_node, copy_index)
154 ->ReplaceInput(input_index,
155 COPY(loop_node, copy_index - 1)->InputAt(input_index));
159 loop_node->
ReplaceInput(input_index, last_iteration_input);
164 COPY(loop_node,
i)->RemoveInput(0);
170 for (
Node* use : loop_node->
uses()) {
172 int count = use->opcode() == IrOpcode::kPhi
173 ? use->op()->ValueInputCount()
174 : use->op()->EffectInputCount();
177 for (
int input_index = 1; input_index <
count; input_index++) {
178 Node* last_iteration_input =
179 COPY(use, unrolling_count - 1)->
InputAt(input_index);
180 for (uint32_t copy_index = unrolling_count - 1; copy_index > 0;
182 COPY(use, copy_index)
183 ->ReplaceInput(input_index,
184 COPY(use, copy_index - 1)->InputAt(input_index));
187 use->ReplaceInput(input_index, last_iteration_input);
193 COPY(use,
i)->RemoveInput(0);
200 if (use->opcode() == IrOpcode::kLoopExit) {
void UnrollLoop(Node *loop_node, ZoneUnorderedSet< Node * > *loop, uint32_t depth, TFGraph *graph, CommonOperatorBuilder *common, Zone *tmp_zone, SourcePositionTable *source_positions, NodeOriginTable *node_origins)