js/src/jit/LiveRangeAllocator.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:5d898c580ce9
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "jit/LiveRangeAllocator.h"
8
9 #include "mozilla/DebugOnly.h"
10
11 #include "jsprf.h"
12
13 #include "jit/BacktrackingAllocator.h"
14 #include "jit/BitSet.h"
15 #include "jit/LinearScan.h"
16
17 using namespace js;
18 using namespace js::jit;
19
20 using mozilla::DebugOnly;
21
22 int
23 Requirement::priority() const
24 {
25 switch (kind_) {
26 case Requirement::FIXED:
27 return 0;
28
29 case Requirement::REGISTER:
30 return 1;
31
32 case Requirement::NONE:
33 return 2;
34
35 default:
36 MOZ_ASSUME_UNREACHABLE("Unknown requirement kind.");
37 }
38 }
39
40 bool
41 LiveInterval::Range::contains(const Range *other) const
42 {
43 return from <= other->from && to >= other->to;
44 }
45
46 void
47 LiveInterval::Range::intersect(const Range *other, Range *pre, Range *inside, Range *post) const
48 {
49 JS_ASSERT(pre->empty() && inside->empty() && post->empty());
50
51 CodePosition innerFrom = from;
52 if (from < other->from) {
53 if (to < other->from) {
54 *pre = Range(from, to);
55 return;
56 }
57 *pre = Range(from, other->from);
58 innerFrom = other->from;
59 }
60
61 CodePosition innerTo = to;
62 if (to > other->to) {
63 if (from >= other->to) {
64 *post = Range(from, to);
65 return;
66 }
67 *post = Range(other->to, to);
68 innerTo = other->to;
69 }
70
71 if (innerFrom != innerTo)
72 *inside = Range(innerFrom, innerTo);
73 }
74
75 bool
76 LiveInterval::addRangeAtHead(CodePosition from, CodePosition to)
77 {
78 JS_ASSERT(from < to);
79
80 Range newRange(from, to);
81
82 if (ranges_.empty())
83 return ranges_.append(newRange);
84
85 Range &first = ranges_.back();
86 if (to < first.from)
87 return ranges_.append(newRange);
88
89 if (to == first.from) {
90 first.from = from;
91 return true;
92 }
93
94 JS_ASSERT(from < first.to);
95 JS_ASSERT(to > first.from);
96 if (from < first.from)
97 first.from = from;
98 if (to > first.to)
99 first.to = to;
100
101 return true;
102 }
103
104 bool
105 LiveInterval::addRange(CodePosition from, CodePosition to)
106 {
107 JS_ASSERT(from < to);
108
109 Range newRange(from, to);
110
111 Range *i;
112 // Find the location to insert the new range
113 for (i = ranges_.end() - 1; i >= ranges_.begin(); i--) {
114 if (newRange.from <= i->to) {
115 if (i->from < newRange.from)
116 newRange.from = i->from;
117 break;
118 }
119 }
120 // Perform coalescing on overlapping ranges
121 for (; i >= ranges_.begin(); i--) {
122 if (newRange.to < i->from)
123 break;
124 if (newRange.to < i->to)
125 newRange.to = i->to;
126 ranges_.erase(i);
127 }
128
129 return ranges_.insert(i + 1, newRange);
130 }
131
132 void
133 LiveInterval::setFrom(CodePosition from)
134 {
135 while (!ranges_.empty()) {
136 if (ranges_.back().to < from) {
137 ranges_.erase(&ranges_.back());
138 } else {
139 if (from == ranges_.back().to)
140 ranges_.erase(&ranges_.back());
141 else
142 ranges_.back().from = from;
143 break;
144 }
145 }
146 }
147
148 bool
149 LiveInterval::covers(CodePosition pos)
150 {
151 if (pos < start() || pos >= end())
152 return false;
153
154 // Loop over the ranges in ascending order.
155 size_t i = lastProcessedRangeIfValid(pos);
156 for (; i < ranges_.length(); i--) {
157 if (pos < ranges_[i].from)
158 return false;
159 setLastProcessedRange(i, pos);
160 if (pos < ranges_[i].to)
161 return true;
162 }
163 return false;
164 }
165
166 CodePosition
167 LiveInterval::nextCoveredAfter(CodePosition pos)
168 {
169 for (size_t i = 0; i < ranges_.length(); i++) {
170 if (ranges_[i].to <= pos) {
171 if (i)
172 return ranges_[i-1].from;
173 break;
174 }
175 if (ranges_[i].from <= pos)
176 return pos;
177 }
178 return CodePosition::MIN;
179 }
180
181 CodePosition
182 LiveInterval::intersect(LiveInterval *other)
183 {
184 if (start() > other->start())
185 return other->intersect(this);
186
187 // Loop over the ranges in ascending order. As an optimization,
188 // try to start at the last processed range.
189 size_t i = lastProcessedRangeIfValid(other->start());
190 size_t j = other->ranges_.length() - 1;
191 if (i >= ranges_.length() || j >= other->ranges_.length())
192 return CodePosition::MIN;
193
194 while (true) {
195 const Range &r1 = ranges_[i];
196 const Range &r2 = other->ranges_[j];
197
198 if (r1.from <= r2.from) {
199 if (r1.from <= other->start())
200 setLastProcessedRange(i, other->start());
201 if (r2.from < r1.to)
202 return r2.from;
203 if (i == 0 || ranges_[i-1].from > other->end())
204 break;
205 i--;
206 } else {
207 if (r1.from < r2.to)
208 return r1.from;
209 if (j == 0 || other->ranges_[j-1].from > end())
210 break;
211 j--;
212 }
213 }
214
215 return CodePosition::MIN;
216 }
217
218 /*
219 * This function takes the callee interval and moves all ranges following or
220 * including provided position to the target interval. Additionally, if a
221 * range in the callee interval spans the given position, it is split and the
222 * latter half is placed in the target interval.
223 *
224 * This function should only be called if it is known that the interval should
225 * actually be split (and, presumably, a move inserted). As such, it is an
226 * error for the caller to request a split that moves all intervals into the
227 * target. Doing so will trip the assertion at the bottom of the function.
228 */
229 bool
230 LiveInterval::splitFrom(CodePosition pos, LiveInterval *after)
231 {
232 JS_ASSERT(pos >= start() && pos < end());
233 JS_ASSERT(after->ranges_.empty());
234
235 // Move all intervals over to the target
236 size_t bufferLength = ranges_.length();
237 Range *buffer = ranges_.extractRawBuffer();
238 if (!buffer)
239 return false;
240 after->ranges_.replaceRawBuffer(buffer, bufferLength);
241
242 // Move intervals back as required
243 for (Range *i = &after->ranges_.back(); i >= after->ranges_.begin(); i--) {
244 if (pos >= i->to)
245 continue;
246
247 if (pos > i->from) {
248 // Split the range
249 Range split(i->from, pos);
250 i->from = pos;
251 if (!ranges_.append(split))
252 return false;
253 }
254 if (!ranges_.append(i + 1, after->ranges_.end()))
255 return false;
256 after->ranges_.shrinkBy(after->ranges_.end() - i - 1);
257 break;
258 }
259
260 // Split the linked list of use positions
261 UsePosition *prev = nullptr;
262 for (UsePositionIterator usePos(usesBegin()); usePos != usesEnd(); usePos++) {
263 if (usePos->pos > pos)
264 break;
265 prev = *usePos;
266 }
267
268 uses_.splitAfter(prev, &after->uses_);
269 return true;
270 }
271
272 void
273 LiveInterval::addUse(UsePosition *use)
274 {
275 // Insert use positions in ascending order. Note that instructions
276 // are visited in reverse order, so in most cases the loop terminates
277 // at the first iteration and the use position will be added to the
278 // front of the list.
279 UsePosition *prev = nullptr;
280 for (UsePositionIterator current(usesBegin()); current != usesEnd(); current++) {
281 if (current->pos >= use->pos)
282 break;
283 prev = *current;
284 }
285
286 if (prev)
287 uses_.insertAfter(prev, use);
288 else
289 uses_.pushFront(use);
290 }
291
292 void
293 LiveInterval::addUseAtEnd(UsePosition *use)
294 {
295 JS_ASSERT(uses_.empty() || use->pos >= uses_.back()->pos);
296 uses_.pushBack(use);
297 }
298
299 UsePosition *
300 LiveInterval::nextUseAfter(CodePosition after)
301 {
302 for (UsePositionIterator usePos(usesBegin()); usePos != usesEnd(); usePos++) {
303 if (usePos->pos >= after) {
304 LUse::Policy policy = usePos->use->policy();
305 JS_ASSERT(policy != LUse::RECOVERED_INPUT);
306 if (policy != LUse::KEEPALIVE)
307 return *usePos;
308 }
309 }
310 return nullptr;
311 }
312
313 /*
314 * This function locates the first "real" use of this interval that follows
315 * the given code position. Non-"real" uses are currently just snapshots,
316 * which keep virtual registers alive but do not result in the
317 * generation of code that use them.
318 */
319 CodePosition
320 LiveInterval::nextUsePosAfter(CodePosition after)
321 {
322 UsePosition *min = nextUseAfter(after);
323 return min ? min->pos : CodePosition::MAX;
324 }
325
326 /*
327 * This function finds the position of the first use of this interval
328 * that is incompatible with the provideded allocation. For example,
329 * a use with a REGISTER policy would be incompatible with a stack slot
330 * allocation.
331 */
332 CodePosition
333 LiveInterval::firstIncompatibleUse(LAllocation alloc)
334 {
335 for (UsePositionIterator usePos(usesBegin()); usePos != usesEnd(); usePos++) {
336 if (!UseCompatibleWith(usePos->use, alloc))
337 return usePos->pos;
338 }
339 return CodePosition::MAX;
340 }
341
342 LiveInterval *
343 VirtualRegister::intervalFor(CodePosition pos)
344 {
345 for (LiveInterval **i = intervals_.begin(); i != intervals_.end(); i++) {
346 if ((*i)->covers(pos))
347 return *i;
348 if (pos < (*i)->end())
349 break;
350 }
351 return nullptr;
352 }
353
354 LiveInterval *
355 VirtualRegister::getFirstInterval()
356 {
357 JS_ASSERT(!intervals_.empty());
358 return intervals_[0];
359 }
360
361 // Instantiate LiveRangeAllocator for each template instance.
362 template bool LiveRangeAllocator<LinearScanVirtualRegister, true>::buildLivenessInfo();
363 template bool LiveRangeAllocator<BacktrackingVirtualRegister, false>::buildLivenessInfo();
364
365 #ifdef DEBUG
366 static inline bool
367 NextInstructionHasFixedUses(LBlock *block, LInstruction *ins)
368 {
369 LInstructionIterator iter(block->begin(ins));
370 iter++;
371 for (LInstruction::InputIterator alloc(**iter); alloc.more(); alloc.next()) {
372 if (alloc->isUse() && alloc->toUse()->isFixedRegister())
373 return true;
374 }
375 return false;
376 }
377
378 // Returns true iff ins has a def/temp reusing the input allocation.
379 static bool
380 IsInputReused(LInstruction *ins, LUse *use)
381 {
382 for (size_t i = 0; i < ins->numDefs(); i++) {
383 if (ins->getDef(i)->policy() == LDefinition::MUST_REUSE_INPUT &&
384 ins->getOperand(ins->getDef(i)->getReusedInput())->toUse() == use)
385 {
386 return true;
387 }
388 }
389
390 for (size_t i = 0; i < ins->numTemps(); i++) {
391 if (ins->getTemp(i)->policy() == LDefinition::MUST_REUSE_INPUT &&
392 ins->getOperand(ins->getTemp(i)->getReusedInput())->toUse() == use)
393 {
394 return true;
395 }
396 }
397
398 return false;
399 }
400 #endif
401
402 /*
403 * This function pre-allocates and initializes as much global state as possible
404 * to avoid littering the algorithms with memory management cruft.
405 */
406 template <typename VREG, bool forLSRA>
407 bool
408 LiveRangeAllocator<VREG, forLSRA>::init()
409 {
410 if (!RegisterAllocator::init())
411 return false;
412
413 liveIn = mir->allocate<BitSet*>(graph.numBlockIds());
414 if (!liveIn)
415 return false;
416
417 // Initialize fixed intervals.
418 for (size_t i = 0; i < AnyRegister::Total; i++) {
419 AnyRegister reg = AnyRegister::FromCode(i);
420 LiveInterval *interval = LiveInterval::New(alloc(), 0);
421 interval->setAllocation(LAllocation(reg));
422 fixedIntervals[i] = interval;
423 }
424
425 fixedIntervalsUnion = LiveInterval::New(alloc(), 0);
426
427 if (!vregs.init(mir, graph.numVirtualRegisters()))
428 return false;
429
430 // Build virtual register objects
431 for (size_t i = 0; i < graph.numBlocks(); i++) {
432 if (mir->shouldCancel("Create data structures (main loop)"))
433 return false;
434
435 LBlock *block = graph.getBlock(i);
436 for (LInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
437 for (size_t j = 0; j < ins->numDefs(); j++) {
438 LDefinition *def = ins->getDef(j);
439 if (def->policy() != LDefinition::PASSTHROUGH) {
440 if (!vregs[def].init(alloc(), block, *ins, def, /* isTemp */ false))
441 return false;
442 }
443 }
444
445 for (size_t j = 0; j < ins->numTemps(); j++) {
446 LDefinition *def = ins->getTemp(j);
447 if (def->isBogusTemp())
448 continue;
449 if (!vregs[def].init(alloc(), block, *ins, def, /* isTemp */ true))
450 return false;
451 }
452 }
453 for (size_t j = 0; j < block->numPhis(); j++) {
454 LPhi *phi = block->getPhi(j);
455 LDefinition *def = phi->getDef(0);
456 if (!vregs[def].init(alloc(), block, phi, def, /* isTemp */ false))
457 return false;
458 }
459 }
460
461 return true;
462 }
463
464 static void
465 AddRegisterToSafepoint(LSafepoint *safepoint, AnyRegister reg, const LDefinition &def)
466 {
467 safepoint->addLiveRegister(reg);
468
469 JS_ASSERT(def.type() == LDefinition::GENERAL ||
470 def.type() == LDefinition::INT32 ||
471 def.type() == LDefinition::DOUBLE ||
472 def.type() == LDefinition::FLOAT32 ||
473 def.type() == LDefinition::OBJECT);
474
475 if (def.type() == LDefinition::OBJECT)
476 safepoint->addGcRegister(reg.gpr());
477 }
478
479 /*
480 * This function builds up liveness intervals for all virtual registers
481 * defined in the function. Additionally, it populates the liveIn array with
482 * information about which registers are live at the beginning of a block, to
483 * aid resolution and reification in a later phase.
484 *
485 * The algorithm is based on the one published in:
486 *
487 * Wimmer, Christian, and Michael Franz. "Linear Scan Register Allocation on
488 * SSA Form." Proceedings of the International Symposium on Code Generation
489 * and Optimization. Toronto, Ontario, Canada, ACM. 2010. 170-79. PDF.
490 *
491 * The algorithm operates on blocks ordered such that dominators of a block
492 * are before the block itself, and such that all blocks of a loop are
493 * contiguous. It proceeds backwards over the instructions in this order,
494 * marking registers live at their uses, ending their live intervals at
495 * definitions, and recording which registers are live at the top of every
496 * block. To deal with loop backedges, variables live at the beginning of
497 * a loop gain an interval covering the entire loop.
498 */
499 template <typename VREG, bool forLSRA>
500 bool
501 LiveRangeAllocator<VREG, forLSRA>::buildLivenessInfo()
502 {
503 if (!init())
504 return false;
505
506 Vector<MBasicBlock *, 1, SystemAllocPolicy> loopWorkList;
507 BitSet *loopDone = BitSet::New(alloc(), graph.numBlockIds());
508 if (!loopDone)
509 return false;
510
511 for (size_t i = graph.numBlocks(); i > 0; i--) {
512 if (mir->shouldCancel("Build Liveness Info (main loop)"))
513 return false;
514
515 LBlock *block = graph.getBlock(i - 1);
516 MBasicBlock *mblock = block->mir();
517
518 BitSet *live = BitSet::New(alloc(), graph.numVirtualRegisters());
519 if (!live)
520 return false;
521 liveIn[mblock->id()] = live;
522
523 // Propagate liveIn from our successors to us
524 for (size_t i = 0; i < mblock->lastIns()->numSuccessors(); i++) {
525 MBasicBlock *successor = mblock->lastIns()->getSuccessor(i);
526 // Skip backedges, as we fix them up at the loop header.
527 if (mblock->id() < successor->id())
528 live->insertAll(liveIn[successor->id()]);
529 }
530
531 // Add successor phis
532 if (mblock->successorWithPhis()) {
533 LBlock *phiSuccessor = mblock->successorWithPhis()->lir();
534 for (unsigned int j = 0; j < phiSuccessor->numPhis(); j++) {
535 LPhi *phi = phiSuccessor->getPhi(j);
536 LAllocation *use = phi->getOperand(mblock->positionInPhiSuccessor());
537 uint32_t reg = use->toUse()->virtualRegister();
538 live->insert(reg);
539 }
540 }
541
542 // Variables are assumed alive for the entire block, a define shortens
543 // the interval to the point of definition.
544 for (BitSet::Iterator liveRegId(*live); liveRegId; liveRegId++) {
545 if (!vregs[*liveRegId].getInterval(0)->addRangeAtHead(inputOf(block->firstId()),
546 outputOf(block->lastId()).next()))
547 {
548 return false;
549 }
550 }
551
552 // Shorten the front end of live intervals for live variables to their
553 // point of definition, if found.
554 for (LInstructionReverseIterator ins = block->rbegin(); ins != block->rend(); ins++) {
555 // Calls may clobber registers, so force a spill and reload around the callsite.
556 if (ins->isCall()) {
557 for (AnyRegisterIterator iter(allRegisters_); iter.more(); iter++) {
558 if (forLSRA) {
559 if (!addFixedRangeAtHead(*iter, inputOf(*ins), outputOf(*ins)))
560 return false;
561 } else {
562 bool found = false;
563 for (size_t i = 0; i < ins->numDefs(); i++) {
564 if (ins->getDef(i)->isPreset() &&
565 *ins->getDef(i)->output() == LAllocation(*iter)) {
566 found = true;
567 break;
568 }
569 }
570 if (!found && !addFixedRangeAtHead(*iter, outputOf(*ins), outputOf(*ins).next()))
571 return false;
572 }
573 }
574 }
575
576 for (size_t i = 0; i < ins->numDefs(); i++) {
577 if (ins->getDef(i)->policy() != LDefinition::PASSTHROUGH) {
578 LDefinition *def = ins->getDef(i);
579
580 CodePosition from;
581 if (def->policy() == LDefinition::PRESET && def->output()->isRegister() && forLSRA) {
582 // The fixed range covers the current instruction so the
583 // interval for the virtual register starts at the next
584 // instruction. If the next instruction has a fixed use,
585 // this can lead to unnecessary register moves. To avoid
586 // special handling for this, assert the next instruction
587 // has no fixed uses. defineFixed guarantees this by inserting
588 // an LNop.
589 JS_ASSERT(!NextInstructionHasFixedUses(block, *ins));
590 AnyRegister reg = def->output()->toRegister();
591 if (!addFixedRangeAtHead(reg, inputOf(*ins), outputOf(*ins).next()))
592 return false;
593 from = outputOf(*ins).next();
594 } else {
595 from = forLSRA ? inputOf(*ins) : outputOf(*ins);
596 }
597
598 if (def->policy() == LDefinition::MUST_REUSE_INPUT) {
599 // MUST_REUSE_INPUT is implemented by allocating an output
600 // register and moving the input to it. Register hints are
601 // used to avoid unnecessary moves. We give the input an
602 // LUse::ANY policy to avoid allocating a register for the
603 // input.
604 LUse *inputUse = ins->getOperand(def->getReusedInput())->toUse();
605 JS_ASSERT(inputUse->policy() == LUse::REGISTER);
606 JS_ASSERT(inputUse->usedAtStart());
607 *inputUse = LUse(inputUse->virtualRegister(), LUse::ANY, /* usedAtStart = */ true);
608 }
609
610 LiveInterval *interval = vregs[def].getInterval(0);
611 interval->setFrom(from);
612
613 // Ensure that if there aren't any uses, there's at least
614 // some interval for the output to go into.
615 if (interval->numRanges() == 0) {
616 if (!interval->addRangeAtHead(from, from.next()))
617 return false;
618 }
619 live->remove(def->virtualRegister());
620 }
621 }
622
623 for (size_t i = 0; i < ins->numTemps(); i++) {
624 LDefinition *temp = ins->getTemp(i);
625 if (temp->isBogusTemp())
626 continue;
627
628 if (forLSRA) {
629 if (temp->policy() == LDefinition::PRESET) {
630 if (ins->isCall())
631 continue;
632 AnyRegister reg = temp->output()->toRegister();
633 if (!addFixedRangeAtHead(reg, inputOf(*ins), outputOf(*ins)))
634 return false;
635
636 // Fixed intervals are not added to safepoints, so do it
637 // here.
638 if (LSafepoint *safepoint = ins->safepoint())
639 AddRegisterToSafepoint(safepoint, reg, *temp);
640 } else {
641 JS_ASSERT(!ins->isCall());
642 if (!vregs[temp].getInterval(0)->addRangeAtHead(inputOf(*ins), outputOf(*ins)))
643 return false;
644 }
645 } else {
646 // Normally temps are considered to cover both the input
647 // and output of the associated instruction. In some cases
648 // though we want to use a fixed register as both an input
649 // and clobbered register in the instruction, so watch for
650 // this and shorten the temp to cover only the output.
651 CodePosition from = inputOf(*ins);
652 if (temp->policy() == LDefinition::PRESET) {
653 AnyRegister reg = temp->output()->toRegister();
654 for (LInstruction::InputIterator alloc(**ins); alloc.more(); alloc.next()) {
655 if (alloc->isUse()) {
656 LUse *use = alloc->toUse();
657 if (use->isFixedRegister()) {
658 if (GetFixedRegister(vregs[use].def(), use) == reg)
659 from = outputOf(*ins);
660 }
661 }
662 }
663 }
664
665 CodePosition to =
666 ins->isCall() ? outputOf(*ins) : outputOf(*ins).next();
667 if (!vregs[temp].getInterval(0)->addRangeAtHead(from, to))
668 return false;
669 }
670 }
671
672 DebugOnly<bool> hasUseRegister = false;
673 DebugOnly<bool> hasUseRegisterAtStart = false;
674
675 for (LInstruction::InputIterator inputAlloc(**ins); inputAlloc.more(); inputAlloc.next()) {
676 if (inputAlloc->isUse()) {
677 LUse *use = inputAlloc->toUse();
678
679 // The first instruction, LLabel, has no uses.
680 JS_ASSERT_IF(forLSRA, inputOf(*ins) > outputOf(block->firstId()));
681
682 // Call uses should always be at-start or fixed, since the fixed intervals
683 // use all registers.
684 JS_ASSERT_IF(ins->isCall() && !inputAlloc.isSnapshotInput(),
685 use->isFixedRegister() || use->usedAtStart());
686
687 #ifdef DEBUG
688 // Don't allow at-start call uses if there are temps of the same kind,
689 // so that we don't assign the same register.
690 if (ins->isCall() && use->usedAtStart()) {
691 for (size_t i = 0; i < ins->numTemps(); i++)
692 JS_ASSERT(vregs[ins->getTemp(i)].isFloatReg() != vregs[use].isFloatReg());
693 }
694
695 // If there are both useRegisterAtStart(x) and useRegister(y)
696 // uses, we may assign the same register to both operands due to
697 // interval splitting (bug 772830). Don't allow this for now.
698 if (use->policy() == LUse::REGISTER) {
699 if (use->usedAtStart()) {
700 if (!IsInputReused(*ins, use))
701 hasUseRegisterAtStart = true;
702 } else {
703 hasUseRegister = true;
704 }
705 }
706
707 JS_ASSERT(!(hasUseRegister && hasUseRegisterAtStart));
708 #endif
709
710 // Don't treat RECOVERED_INPUT uses as keeping the vreg alive.
711 if (use->policy() == LUse::RECOVERED_INPUT)
712 continue;
713
714 CodePosition to;
715 if (forLSRA) {
716 if (use->isFixedRegister()) {
717 AnyRegister reg = GetFixedRegister(vregs[use].def(), use);
718 if (!addFixedRangeAtHead(reg, inputOf(*ins), outputOf(*ins)))
719 return false;
720 to = inputOf(*ins);
721
722 // Fixed intervals are not added to safepoints, so do it
723 // here.
724 LSafepoint *safepoint = ins->safepoint();
725 if (!ins->isCall() && safepoint)
726 AddRegisterToSafepoint(safepoint, reg, *vregs[use].def());
727 } else {
728 to = use->usedAtStart() ? inputOf(*ins) : outputOf(*ins);
729 }
730 } else {
731 to = (use->usedAtStart() || ins->isCall())
732 ? inputOf(*ins) : outputOf(*ins);
733 if (use->isFixedRegister()) {
734 LAllocation reg(AnyRegister::FromCode(use->registerCode()));
735 for (size_t i = 0; i < ins->numDefs(); i++) {
736 LDefinition *def = ins->getDef(i);
737 if (def->policy() == LDefinition::PRESET && *def->output() == reg)
738 to = inputOf(*ins);
739 }
740 }
741 }
742
743 LiveInterval *interval = vregs[use].getInterval(0);
744 if (!interval->addRangeAtHead(inputOf(block->firstId()), forLSRA ? to : to.next()))
745 return false;
746 interval->addUse(new(alloc()) UsePosition(use, to));
747
748 live->insert(use->virtualRegister());
749 }
750 }
751 }
752
753 // Phis have simultaneous assignment semantics at block begin, so at
754 // the beginning of the block we can be sure that liveIn does not
755 // contain any phi outputs.
756 for (unsigned int i = 0; i < block->numPhis(); i++) {
757 LDefinition *def = block->getPhi(i)->getDef(0);
758 if (live->contains(def->virtualRegister())) {
759 live->remove(def->virtualRegister());
760 } else {
761 // This is a dead phi, so add a dummy range over all phis. This
762 // can go away if we have an earlier dead code elimination pass.
763 if (!vregs[def].getInterval(0)->addRangeAtHead(inputOf(block->firstId()),
764 outputOf(block->firstId())))
765 {
766 return false;
767 }
768 }
769 }
770
771 if (mblock->isLoopHeader()) {
772 // A divergence from the published algorithm is required here, as
773 // our block order does not guarantee that blocks of a loop are
774 // contiguous. As a result, a single live interval spanning the
775 // loop is not possible. Additionally, we require liveIn in a later
776 // pass for resolution, so that must also be fixed up here.
777 MBasicBlock *loopBlock = mblock->backedge();
778 while (true) {
779 // Blocks must already have been visited to have a liveIn set.
780 JS_ASSERT(loopBlock->id() >= mblock->id());
781
782 // Add an interval for this entire loop block
783 CodePosition from = inputOf(loopBlock->lir()->firstId());
784 CodePosition to = outputOf(loopBlock->lir()->lastId()).next();
785
786 for (BitSet::Iterator liveRegId(*live); liveRegId; liveRegId++) {
787 if (!vregs[*liveRegId].getInterval(0)->addRange(from, to))
788 return false;
789 }
790
791 // Fix up the liveIn set to account for the new interval
792 liveIn[loopBlock->id()]->insertAll(live);
793
794 // Make sure we don't visit this node again
795 loopDone->insert(loopBlock->id());
796
797 // If this is the loop header, any predecessors are either the
798 // backedge or out of the loop, so skip any predecessors of
799 // this block
800 if (loopBlock != mblock) {
801 for (size_t i = 0; i < loopBlock->numPredecessors(); i++) {
802 MBasicBlock *pred = loopBlock->getPredecessor(i);
803 if (loopDone->contains(pred->id()))
804 continue;
805 if (!loopWorkList.append(pred))
806 return false;
807 }
808 }
809
810 // Terminate loop if out of work.
811 if (loopWorkList.empty())
812 break;
813
814 // Grab the next block off the work list, skipping any OSR block.
815 while (!loopWorkList.empty()) {
816 loopBlock = loopWorkList.popCopy();
817 if (loopBlock->lir() != graph.osrBlock())
818 break;
819 }
820
821 // If end is reached without finding a non-OSR block, then no more work items were found.
822 if (loopBlock->lir() == graph.osrBlock()) {
823 JS_ASSERT(loopWorkList.empty());
824 break;
825 }
826 }
827
828 // Clear the done set for other loops
829 loopDone->clear();
830 }
831
832 JS_ASSERT_IF(!mblock->numPredecessors(), live->empty());
833 }
834
835 validateVirtualRegisters();
836
837 // If the script has an infinite loop, there may be no MReturn and therefore
838 // no fixed intervals. Add a small range to fixedIntervalsUnion so that the
839 // rest of the allocator can assume it has at least one range.
840 if (fixedIntervalsUnion->numRanges() == 0) {
841 if (!fixedIntervalsUnion->addRangeAtHead(CodePosition(0, CodePosition::INPUT),
842 CodePosition(0, CodePosition::OUTPUT)))
843 {
844 return false;
845 }
846 }
847
848 return true;
849 }
850
851 #ifdef DEBUG
852
853 void
854 LiveInterval::validateRanges()
855 {
856 Range *prev = nullptr;
857
858 for (size_t i = ranges_.length() - 1; i < ranges_.length(); i--) {
859 Range *range = &ranges_[i];
860
861 JS_ASSERT(range->from < range->to);
862 JS_ASSERT_IF(prev, prev->to <= range->from);
863 prev = range;
864 }
865 }
866
867 #endif // DEBUG
868
869 const char *
870 LiveInterval::rangesToString() const
871 {
872 #ifdef DEBUG
873 if (!numRanges())
874 return " empty";
875
876 // Not reentrant!
877 static char buf[1000];
878
879 char *cursor = buf;
880 char *end = cursor + sizeof(buf);
881
882 for (size_t i = 0; i < numRanges(); i++) {
883 const LiveInterval::Range *range = getRange(i);
884 int n = JS_snprintf(cursor, end - cursor, " [%u,%u>", range->from.pos(), range->to.pos());
885 if (n < 0)
886 return " ???";
887 cursor += n;
888 }
889
890 return buf;
891 #else
892 return " ???";
893 #endif
894 }
895
896 void
897 LiveInterval::dump()
898 {
899 fprintf(stderr, "v%u: index=%u allocation=%s %s\n",
900 vreg(), index(), getAllocation()->toString(), rangesToString());
901 }

mercurial