github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/src/cmd/compile/internal/ssa/regalloc.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Register allocation. 6 // 7 // We use a version of a linear scan register allocator. We treat the 8 // whole function as a single long basic block and run through 9 // it using a greedy register allocator. Then all merge edges 10 // (those targeting a block with len(Preds)>1) are processed to 11 // shuffle data into the place that the target of the edge expects. 12 // 13 // The greedy allocator moves values into registers just before they 14 // are used, spills registers only when necessary, and spills the 15 // value whose next use is farthest in the future. 16 // 17 // The register allocator requires that a block is not scheduled until 18 // at least one of its predecessors have been scheduled. The most recent 19 // such predecessor provides the starting register state for a block. 20 // 21 // It also requires that there are no critical edges (critical = 22 // comes from a block with >1 successor and goes to a block with >1 23 // predecessor). This makes it easy to add fixup code on merge edges - 24 // the source of a merge edge has only one successor, so we can add 25 // fixup code to the end of that block. 26 27 // Spilling 28 // 29 // For every value, we generate a spill immediately after the value itself. 30 // x = Op y z : AX 31 // x2 = StoreReg x 32 // While AX still holds x, any uses of x will use that value. When AX is needed 33 // for another value, we simply reuse AX. Spill code has already been generated 34 // so there is no code generated at "spill" time. When x is referenced 35 // subsequently, we issue a load to restore x to a register using x2 as 36 // its argument: 37 // x3 = Restore x2 : CX 38 // x3 can then be used wherever x is referenced again. 39 // If the spill (x2) is never used, it will be removed at the end of regalloc. 40 // 41 // Phi values are special, as always. We define two kinds of phis, those 42 // where the merge happens in a register (a "register" phi) and those where 43 // the merge happens in a stack location (a "stack" phi). 44 // 45 // A register phi must have the phi and all of its inputs allocated to the 46 // same register. Register phis are spilled similarly to regular ops: 47 // b1: y = ... : AX b2: z = ... : AX 48 // goto b3 goto b3 49 // b3: x = phi(y, z) : AX 50 // x2 = StoreReg x 51 // 52 // A stack phi must have the phi and all of its inputs allocated to the same 53 // stack location. Stack phis start out life already spilled - each phi 54 // input must be a store (using StoreReg) at the end of the corresponding 55 // predecessor block. 56 // b1: y = ... : AX b2: z = ... : BX 57 // y2 = StoreReg y z2 = StoreReg z 58 // goto b3 goto b3 59 // b3: x = phi(y2, z2) 60 // The stack allocator knows that StoreReg args of stack-allocated phis 61 // must be allocated to the same stack slot as the phi that uses them. 62 // x is now a spilled value and a restore must appear before its first use. 63 64 // TODO 65 66 // Use an affinity graph to mark two values which should use the 67 // same register. This affinity graph will be used to prefer certain 68 // registers for allocation. This affinity helps eliminate moves that 69 // are required for phi implementations and helps generate allocations 70 // for 2-register architectures. 71 72 // Note: regalloc generates a not-quite-SSA output. If we have: 73 // 74 // b1: x = ... : AX 75 // x2 = StoreReg x 76 // ... AX gets reused for something else ... 77 // if ... goto b3 else b4 78 // 79 // b3: x3 = LoadReg x2 : BX b4: x4 = LoadReg x2 : CX 80 // ... use x3 ... ... use x4 ... 81 // 82 // b2: ... use x3 ... 83 // 84 // If b3 is the primary predecessor of b2, then we use x3 in b2 and 85 // add a x4:CX->BX copy at the end of b4. 86 // But the definition of x3 doesn't dominate b2. We should really 87 // insert a dummy phi at the start of b2 (x5=phi(x3,x4):BX) to keep 88 // SSA form. For now, we ignore this problem as remaining in strict 89 // SSA form isn't needed after regalloc. We'll just leave the use 90 // of x3 not dominated by the definition of x3, and the CX->BX copy 91 // will have no use (so don't run deadcode after regalloc!). 92 // TODO: maybe we should introduce these extra phis? 93 94 // Additional not-quite-SSA output occurs when spills are sunk out 95 // of loops to the targets of exit edges from the loop. Before sinking, 96 // there is one spill site (one StoreReg) targeting stack slot X, after 97 // sinking there may be multiple spill sites targeting stack slot X, 98 // with no phi functions at any join points reachable by the multiple 99 // spill sites. In addition, uses of the spill from copies of the original 100 // will not name the copy in their reference; instead they will name 101 // the original, though both will have the same spill location. The 102 // first sunk spill will be the original, but moved, to an exit block, 103 // thus ensuring that there is a definition somewhere corresponding to 104 // the original spill's uses. 105 106 package ssa 107 108 import ( 109 "fmt" 110 "unsafe" 111 ) 112 113 const ( 114 moveSpills = iota 115 logSpills 116 regDebug 117 stackDebug 118 ) 119 120 // distance is a measure of how far into the future values are used. 121 // distance is measured in units of instructions. 122 const ( 123 likelyDistance = 1 124 normalDistance = 10 125 unlikelyDistance = 100 126 ) 127 128 // regalloc performs register allocation on f. It sets f.RegAlloc 129 // to the resulting allocation. 130 func regalloc(f *Func) { 131 var s regAllocState 132 s.init(f) 133 s.regalloc(f) 134 } 135 136 type register uint8 137 138 const noRegister register = 255 139 140 type regMask uint64 141 142 func (m regMask) String() string { 143 s := "" 144 for r := register(0); m != 0; r++ { 145 if m>>r&1 == 0 { 146 continue 147 } 148 m &^= regMask(1) << r 149 if s != "" { 150 s += " " 151 } 152 s += fmt.Sprintf("r%d", r) 153 } 154 return s 155 } 156 157 // countRegs returns the number of set bits in the register mask. 158 func countRegs(r regMask) int { 159 n := 0 160 for r != 0 { 161 n += int(r & 1) 162 r >>= 1 163 } 164 return n 165 } 166 167 // pickReg picks an arbitrary register from the register mask. 168 func pickReg(r regMask) register { 169 // pick the lowest one 170 if r == 0 { 171 panic("can't pick a register from an empty set") 172 } 173 for i := register(0); ; i++ { 174 if r&1 != 0 { 175 return i 176 } 177 r >>= 1 178 } 179 } 180 181 type use struct { 182 dist int32 // distance from start of the block to a use of a value 183 next *use // linked list of uses of a value in nondecreasing dist order 184 } 185 186 type valState struct { 187 regs regMask // the set of registers holding a Value (usually just one) 188 uses *use // list of uses in this block 189 spill *Value // spilled copy of the Value 190 spillUsed bool 191 spillUsedShuffle bool // true if used in shuffling, after ordinary uses 192 needReg bool // cached value of !v.Type.IsMemory() && !v.Type.IsVoid() && !.v.Type.IsFlags() 193 rematerializeable bool // cached value of v.rematerializeable() 194 } 195 196 type regState struct { 197 v *Value // Original (preregalloc) Value stored in this register. 198 c *Value // A Value equal to v which is currently in a register. Might be v or a copy of it. 199 // If a register is unused, v==c==nil 200 } 201 202 type regAllocState struct { 203 f *Func 204 205 registers []Register 206 numRegs register 207 SPReg register 208 SBReg register 209 allocatable regMask 210 211 // for each block, its primary predecessor. 212 // A predecessor of b is primary if it is the closest 213 // predecessor that appears before b in the layout order. 214 // We record the index in the Preds list where the primary predecessor sits. 215 primary []int32 216 217 // live values at the end of each block. live[b.ID] is a list of value IDs 218 // which are live at the end of b, together with a count of how many instructions 219 // forward to the next use. 220 live [][]liveInfo 221 // desired register assignments at the end of each block. 222 // Note that this is a static map computed before allocation occurs. Dynamic 223 // register desires (from partially completed allocations) will trump 224 // this information. 225 desired []desiredState 226 227 // current state of each (preregalloc) Value 228 values []valState 229 230 // For each Value, map from its value ID back to the 231 // preregalloc Value it was derived from. 232 orig []*Value 233 234 // current state of each register 235 regs []regState 236 237 // registers that contain values which can't be kicked out 238 nospill regMask 239 240 // mask of registers currently in use 241 used regMask 242 243 // current block we're working on 244 curBlock *Block 245 246 // cache of use records 247 freeUseRecords *use 248 249 // endRegs[blockid] is the register state at the end of each block. 250 // encoded as a set of endReg records. 251 endRegs [][]endReg 252 253 // startRegs[blockid] is the register state at the start of merge blocks. 254 // saved state does not include the state of phi ops in the block. 255 startRegs [][]startReg 256 257 // spillLive[blockid] is the set of live spills at the end of each block 258 spillLive [][]ID 259 260 loopnest *loopnest 261 } 262 263 type spillToSink struct { 264 spill *Value // Spill instruction to move (a StoreReg) 265 dests int32 // Bitmask indicating exit blocks from loop in which spill/val is defined. 1<<i set means val is live into loop.exitBlocks[i] 266 } 267 268 func (sts *spillToSink) spilledValue() *Value { 269 return sts.spill.Args[0] 270 } 271 272 type endReg struct { 273 r register 274 v *Value // pre-regalloc value held in this register (TODO: can we use ID here?) 275 c *Value // cached version of the value 276 } 277 278 type startReg struct { 279 r register 280 vid ID // pre-regalloc value needed in this register 281 } 282 283 // freeReg frees up register r. Any current user of r is kicked out. 284 func (s *regAllocState) freeReg(r register) { 285 v := s.regs[r].v 286 if v == nil { 287 s.f.Fatalf("tried to free an already free register %d\n", r) 288 } 289 290 // Mark r as unused. 291 if s.f.pass.debug > regDebug { 292 fmt.Printf("freeReg %s (dump %s/%s)\n", s.registers[r].Name(), v, s.regs[r].c) 293 } 294 s.regs[r] = regState{} 295 s.values[v.ID].regs &^= regMask(1) << r 296 s.used &^= regMask(1) << r 297 } 298 299 // freeRegs frees up all registers listed in m. 300 func (s *regAllocState) freeRegs(m regMask) { 301 for m&s.used != 0 { 302 s.freeReg(pickReg(m & s.used)) 303 } 304 } 305 306 // setOrig records that c's original value is the same as 307 // v's original value. 308 func (s *regAllocState) setOrig(c *Value, v *Value) { 309 for int(c.ID) >= len(s.orig) { 310 s.orig = append(s.orig, nil) 311 } 312 if s.orig[c.ID] != nil { 313 s.f.Fatalf("orig value set twice %s %s", c, v) 314 } 315 s.orig[c.ID] = s.orig[v.ID] 316 } 317 318 // assignReg assigns register r to hold c, a copy of v. 319 // r must be unused. 320 func (s *regAllocState) assignReg(r register, v *Value, c *Value) { 321 if s.f.pass.debug > regDebug { 322 fmt.Printf("assignReg %s %s/%s\n", s.registers[r].Name(), v, c) 323 } 324 if s.regs[r].v != nil { 325 s.f.Fatalf("tried to assign register %d to %s/%s but it is already used by %s", r, v, c, s.regs[r].v) 326 } 327 328 // Update state. 329 s.regs[r] = regState{v, c} 330 s.values[v.ID].regs |= regMask(1) << r 331 s.used |= regMask(1) << r 332 s.f.setHome(c, &s.registers[r]) 333 } 334 335 // allocReg chooses a register for v from the set of registers in mask. 336 // If there is no unused register, a Value will be kicked out of 337 // a register to make room. 338 func (s *regAllocState) allocReg(v *Value, mask regMask) register { 339 mask &= s.allocatable 340 mask &^= s.nospill 341 if mask == 0 { 342 s.f.Fatalf("no register available") 343 } 344 345 // Pick an unused register if one is available. 346 if mask&^s.used != 0 { 347 return pickReg(mask &^ s.used) 348 } 349 350 // Pick a value to spill. Spill the value with the 351 // farthest-in-the-future use. 352 // TODO: Prefer registers with already spilled Values? 353 // TODO: Modify preference using affinity graph. 354 // TODO: if a single value is in multiple registers, spill one of them 355 // before spilling a value in just a single register. 356 357 // Find a register to spill. We spill the register containing the value 358 // whose next use is as far in the future as possible. 359 // https://en.wikipedia.org/wiki/Page_replacement_algorithm#The_theoretically_optimal_page_replacement_algorithm 360 var r register 361 maxuse := int32(-1) 362 for t := register(0); t < s.numRegs; t++ { 363 if mask>>t&1 == 0 { 364 continue 365 } 366 v := s.regs[t].v 367 if n := s.values[v.ID].uses.dist; n > maxuse { 368 // v's next use is farther in the future than any value 369 // we've seen so far. A new best spill candidate. 370 r = t 371 maxuse = n 372 } 373 } 374 if maxuse == -1 { 375 s.f.Unimplementedf("couldn't find register to spill") 376 } 377 s.freeReg(r) 378 return r 379 } 380 381 // allocValToReg allocates v to a register selected from regMask and 382 // returns the register copy of v. Any previous user is kicked out and spilled 383 // (if necessary). Load code is added at the current pc. If nospill is set the 384 // allocated register is marked nospill so the assignment cannot be 385 // undone until the caller allows it by clearing nospill. Returns a 386 // *Value which is either v or a copy of v allocated to the chosen register. 387 func (s *regAllocState) allocValToReg(v *Value, mask regMask, nospill bool, line int32) *Value { 388 vi := &s.values[v.ID] 389 390 // Check if v is already in a requested register. 391 if mask&vi.regs != 0 { 392 r := pickReg(mask & vi.regs) 393 if s.regs[r].v != v || s.regs[r].c == nil { 394 panic("bad register state") 395 } 396 if nospill { 397 s.nospill |= regMask(1) << r 398 } 399 return s.regs[r].c 400 } 401 402 // Allocate a register. 403 r := s.allocReg(v, mask) 404 405 // Allocate v to the new register. 406 var c *Value 407 if vi.regs != 0 { 408 // Copy from a register that v is already in. 409 r2 := pickReg(vi.regs) 410 if s.regs[r2].v != v { 411 panic("bad register state") 412 } 413 c = s.curBlock.NewValue1(line, OpCopy, v.Type, s.regs[r2].c) 414 } else if v.rematerializeable() { 415 // Rematerialize instead of loading from the spill location. 416 c = v.copyInto(s.curBlock) 417 } else { 418 switch { 419 // Load v from its spill location. 420 case vi.spill != nil: 421 if s.f.pass.debug > logSpills { 422 s.f.Config.Warnl(vi.spill.Line, "load spill for %v from %v", v, vi.spill) 423 } 424 c = s.curBlock.NewValue1(line, OpLoadReg, v.Type, vi.spill) 425 vi.spillUsed = true 426 default: 427 s.f.Fatalf("attempt to load unspilled value %v", v.LongString()) 428 } 429 } 430 s.setOrig(c, v) 431 s.assignReg(r, v, c) 432 if nospill { 433 s.nospill |= regMask(1) << r 434 } 435 return c 436 } 437 438 func (s *regAllocState) init(f *Func) { 439 s.f = f 440 s.registers = f.Config.registers 441 s.numRegs = register(len(s.registers)) 442 if s.numRegs > noRegister || s.numRegs > register(unsafe.Sizeof(regMask(0))*8) { 443 panic("too many registers") 444 } 445 for r := register(0); r < s.numRegs; r++ { 446 if s.registers[r].Name() == "SP" { 447 s.SPReg = r 448 } 449 if s.registers[r].Name() == "SB" { 450 s.SBReg = r 451 } 452 } 453 454 // Figure out which registers we're allowed to use. 455 s.allocatable = regMask(1)<<s.numRegs - 1 456 s.allocatable &^= 1 << s.SPReg 457 s.allocatable &^= 1 << s.SBReg 458 if s.f.Config.ctxt.Framepointer_enabled { 459 s.allocatable &^= 1 << 5 // BP 460 } 461 if s.f.Config.ctxt.Flag_dynlink { 462 s.allocatable &^= 1 << 15 // R15 463 } 464 465 s.regs = make([]regState, s.numRegs) 466 s.values = make([]valState, f.NumValues()) 467 s.orig = make([]*Value, f.NumValues()) 468 for _, b := range f.Blocks { 469 for _, v := range b.Values { 470 if !v.Type.IsMemory() && !v.Type.IsVoid() && !v.Type.IsFlags() { 471 s.values[v.ID].needReg = true 472 s.values[v.ID].rematerializeable = v.rematerializeable() 473 s.orig[v.ID] = v 474 } 475 } 476 } 477 s.computeLive() 478 479 // Compute block order. This array allows us to distinguish forward edges 480 // from backward edges and compute how far they go. 481 blockOrder := make([]int32, f.NumBlocks()) 482 for i, b := range f.Blocks { 483 blockOrder[b.ID] = int32(i) 484 } 485 486 // Compute primary predecessors. 487 s.primary = make([]int32, f.NumBlocks()) 488 for _, b := range f.Blocks { 489 best := -1 490 for i, e := range b.Preds { 491 p := e.b 492 if blockOrder[p.ID] >= blockOrder[b.ID] { 493 continue // backward edge 494 } 495 if best == -1 || blockOrder[p.ID] > blockOrder[b.Preds[best].b.ID] { 496 best = i 497 } 498 } 499 s.primary[b.ID] = int32(best) 500 } 501 502 s.endRegs = make([][]endReg, f.NumBlocks()) 503 s.startRegs = make([][]startReg, f.NumBlocks()) 504 s.spillLive = make([][]ID, f.NumBlocks()) 505 } 506 507 // Adds a use record for id at distance dist from the start of the block. 508 // All calls to addUse must happen with nonincreasing dist. 509 func (s *regAllocState) addUse(id ID, dist int32) { 510 r := s.freeUseRecords 511 if r != nil { 512 s.freeUseRecords = r.next 513 } else { 514 r = &use{} 515 } 516 r.dist = dist 517 r.next = s.values[id].uses 518 s.values[id].uses = r 519 if r.next != nil && dist > r.next.dist { 520 s.f.Fatalf("uses added in wrong order") 521 } 522 } 523 524 // advanceUses advances the uses of v's args from the state before v to the state after v. 525 // Any values which have no more uses are deallocated from registers. 526 func (s *regAllocState) advanceUses(v *Value) { 527 for _, a := range v.Args { 528 if !s.values[a.ID].needReg { 529 continue 530 } 531 ai := &s.values[a.ID] 532 r := ai.uses 533 ai.uses = r.next 534 if r.next == nil { 535 // Value is dead, free all registers that hold it. 536 s.freeRegs(ai.regs) 537 } 538 r.next = s.freeUseRecords 539 s.freeUseRecords = r 540 } 541 } 542 543 // liveAfterCurrentInstruction reports whether v is live after 544 // the current instruction is completed. v must be used by the 545 // current instruction. 546 func (s *regAllocState) liveAfterCurrentInstruction(v *Value) bool { 547 u := s.values[v.ID].uses 548 d := u.dist 549 for u != nil && u.dist == d { 550 u = u.next 551 } 552 return u != nil && u.dist > d 553 } 554 555 // Sets the state of the registers to that encoded in regs. 556 func (s *regAllocState) setState(regs []endReg) { 557 s.freeRegs(s.used) 558 for _, x := range regs { 559 s.assignReg(x.r, x.v, x.c) 560 } 561 } 562 563 // compatRegs returns the set of registers which can store a type t. 564 func (s *regAllocState) compatRegs(t Type) regMask { 565 var m regMask 566 if t.IsFloat() || t == TypeInt128 { 567 m = 0xffff << 16 // X0-X15 568 } else { 569 m = 0xffff << 0 // AX-R15 570 } 571 return m & s.allocatable 572 } 573 574 // loopForBlock returns the loop containing block b, 575 // provided that the loop is "interesting" for purposes 576 // of improving register allocation (= is inner, and does 577 // not contain a call) 578 func (s *regAllocState) loopForBlock(b *Block) *loop { 579 loop := s.loopnest.b2l[b.ID] 580 581 // Minor for-the-time-being optimization: nothing happens 582 // unless a loop is both inner and call-free, therefore 583 // don't bother with other loops. 584 if loop != nil && (loop.containsCall || !loop.isInner) { 585 loop = nil 586 } 587 return loop 588 } 589 590 func (s *regAllocState) regalloc(f *Func) { 591 liveSet := f.newSparseSet(f.NumValues()) 592 defer f.retSparseSet(liveSet) 593 var oldSched []*Value 594 var phis []*Value 595 var phiRegs []register 596 var args []*Value 597 598 // statistics 599 var nSpills int // # of spills remaining 600 var nSpillsInner int // # of spills remaining in inner loops 601 var nSpillsSunk int // # of sunk spills remaining 602 var nSpillsChanged int // # of sunk spills lost because of register use change 603 var nSpillsSunkUnused int // # of spills not sunk because they were removed completely 604 var nSpillsNotSunkLateUse int // # of spills not sunk because of very late use (in shuffle) 605 606 // Data structure used for computing desired registers. 607 var desired desiredState 608 609 // Desired registers for inputs & outputs for each instruction in the block. 610 type dentry struct { 611 out [4]register // desired output registers 612 in [3][4]register // desired input registers (for inputs 0,1, and 2) 613 } 614 var dinfo []dentry 615 616 if f.Entry != f.Blocks[0] { 617 f.Fatalf("entry block must be first") 618 } 619 620 // Get loop nest so that spills in inner loops can be 621 // tracked. When the last block of a loop is processed, 622 // attempt to move spills out of the loop. 623 s.loopnest.findExits() 624 625 // Spills are moved from one block's slice of values to another's. 626 // This confuses register allocation if it occurs before it is 627 // complete, so candidates are recorded, then rechecked and 628 // moved after all allocation (register and stack) is complete. 629 // Because movement is only within a stack slot's lifetime, it 630 // is safe to do this. 631 var toSink []spillToSink 632 // Will be used to figure out live inputs to exit blocks of inner loops. 633 entryCandidates := newSparseMap(f.NumValues()) 634 635 for _, b := range f.Blocks { 636 s.curBlock = b 637 loop := s.loopForBlock(b) 638 639 // Initialize liveSet and uses fields for this block. 640 // Walk backwards through the block doing liveness analysis. 641 liveSet.clear() 642 d := int32(len(b.Values)) 643 if b.Kind == BlockCall || b.Kind == BlockDefer { 644 d += unlikelyDistance 645 } 646 for _, e := range s.live[b.ID] { 647 s.addUse(e.ID, d+e.dist) // pseudo-uses from beyond end of block 648 liveSet.add(e.ID) 649 } 650 if v := b.Control; v != nil && s.values[v.ID].needReg { 651 s.addUse(v.ID, int32(len(b.Values))) // psuedo-use by control value 652 liveSet.add(v.ID) 653 } 654 for i := len(b.Values) - 1; i >= 0; i-- { 655 v := b.Values[i] 656 liveSet.remove(v.ID) 657 if v.Op == OpPhi { 658 // Remove v from the live set, but don't add 659 // any inputs. This is the state the len(b.Preds)>1 660 // case below desires; it wants to process phis specially. 661 continue 662 } 663 for _, a := range v.Args { 664 if !s.values[a.ID].needReg { 665 continue 666 } 667 s.addUse(a.ID, int32(i)) 668 liveSet.add(a.ID) 669 } 670 } 671 if s.f.pass.debug > regDebug { 672 fmt.Printf("uses for %s:%s\n", s.f.Name, b) 673 for i := range s.values { 674 vi := &s.values[i] 675 u := vi.uses 676 if u == nil { 677 continue 678 } 679 fmt.Printf(" v%d:", i) 680 for u != nil { 681 fmt.Printf(" %d", u.dist) 682 u = u.next 683 } 684 fmt.Println() 685 } 686 } 687 688 // Make a copy of the block schedule so we can generate a new one in place. 689 // We make a separate copy for phis and regular values. 690 nphi := 0 691 for _, v := range b.Values { 692 if v.Op != OpPhi { 693 break 694 } 695 nphi++ 696 } 697 phis = append(phis[:0], b.Values[:nphi]...) 698 oldSched = append(oldSched[:0], b.Values[nphi:]...) 699 b.Values = b.Values[:0] 700 701 // Initialize start state of block. 702 if b == f.Entry { 703 // Regalloc state is empty to start. 704 if nphi > 0 { 705 f.Fatalf("phis in entry block") 706 } 707 } else if len(b.Preds) == 1 { 708 // Start regalloc state with the end state of the previous block. 709 s.setState(s.endRegs[b.Preds[0].b.ID]) 710 if nphi > 0 { 711 f.Fatalf("phis in single-predecessor block") 712 } 713 // Drop any values which are no longer live. 714 // This may happen because at the end of p, a value may be 715 // live but only used by some other successor of p. 716 for r := register(0); r < s.numRegs; r++ { 717 v := s.regs[r].v 718 if v != nil && !liveSet.contains(v.ID) { 719 s.freeReg(r) 720 } 721 } 722 } else { 723 // This is the complicated case. We have more than one predecessor, 724 // which means we may have Phi ops. 725 726 // Copy phi ops into new schedule. 727 b.Values = append(b.Values, phis...) 728 729 // Start with the final register state of the primary predecessor 730 idx := s.primary[b.ID] 731 if idx < 0 { 732 f.Fatalf("block with no primary predecessor %s", b) 733 } 734 p := b.Preds[idx].b 735 s.setState(s.endRegs[p.ID]) 736 737 if s.f.pass.debug > regDebug { 738 fmt.Printf("starting merge block %s with end state of %s:\n", b, p) 739 for _, x := range s.endRegs[p.ID] { 740 fmt.Printf(" %s: orig:%s cache:%s\n", s.registers[x.r].Name(), x.v, x.c) 741 } 742 } 743 744 // Decide on registers for phi ops. Use the registers determined 745 // by the primary predecessor if we can. 746 // TODO: pick best of (already processed) predecessors? 747 // Majority vote? Deepest nesting level? 748 phiRegs = phiRegs[:0] 749 var phiUsed regMask 750 for _, v := range phis { 751 if !s.values[v.ID].needReg { 752 phiRegs = append(phiRegs, noRegister) 753 continue 754 } 755 a := v.Args[idx] 756 m := s.values[a.ID].regs &^ phiUsed 757 if m != 0 { 758 r := pickReg(m) 759 s.freeReg(r) 760 phiUsed |= regMask(1) << r 761 phiRegs = append(phiRegs, r) 762 } else { 763 phiRegs = append(phiRegs, noRegister) 764 } 765 } 766 767 // Second pass - deallocate any phi inputs which are now dead. 768 for _, v := range phis { 769 if !s.values[v.ID].needReg { 770 continue 771 } 772 a := v.Args[idx] 773 if !liveSet.contains(a.ID) { 774 // Input is dead beyond the phi, deallocate 775 // anywhere else it might live. 776 s.freeRegs(s.values[a.ID].regs) 777 } 778 } 779 780 // Third pass - pick registers for phis whose inputs 781 // were not in a register. 782 for i, v := range phis { 783 if !s.values[v.ID].needReg { 784 continue 785 } 786 if phiRegs[i] != noRegister { 787 continue 788 } 789 m := s.compatRegs(v.Type) &^ phiUsed &^ s.used 790 if m != 0 { 791 r := pickReg(m) 792 phiRegs[i] = r 793 phiUsed |= regMask(1) << r 794 } 795 } 796 797 // Set registers for phis. Add phi spill code. 798 for i, v := range phis { 799 if !s.values[v.ID].needReg { 800 continue 801 } 802 r := phiRegs[i] 803 if r == noRegister { 804 // stack-based phi 805 // Spills will be inserted in all the predecessors below. 806 s.values[v.ID].spill = v // v starts life spilled 807 s.values[v.ID].spillUsed = true // use is guaranteed 808 continue 809 } 810 // register-based phi 811 s.assignReg(r, v, v) 812 // Spill the phi in case we need to restore it later. 813 spill := b.NewValue1(v.Line, OpStoreReg, v.Type, v) 814 s.setOrig(spill, v) 815 s.values[v.ID].spill = spill 816 s.values[v.ID].spillUsed = false 817 if loop != nil { 818 loop.spills = append(loop.spills, v) 819 nSpillsInner++ 820 } 821 nSpills++ 822 } 823 824 // Save the starting state for use by merge edges. 825 var regList []startReg 826 for r := register(0); r < s.numRegs; r++ { 827 v := s.regs[r].v 828 if v == nil { 829 continue 830 } 831 if phiUsed>>r&1 != 0 { 832 // Skip registers that phis used, we'll handle those 833 // specially during merge edge processing. 834 continue 835 } 836 regList = append(regList, startReg{r, v.ID}) 837 } 838 s.startRegs[b.ID] = regList 839 840 if s.f.pass.debug > regDebug { 841 fmt.Printf("after phis\n") 842 for _, x := range s.startRegs[b.ID] { 843 fmt.Printf(" %s: v%d\n", s.registers[x.r].Name(), x.vid) 844 } 845 } 846 } 847 848 // Allocate space to record the desired registers for each value. 849 dinfo = dinfo[:0] 850 for i := 0; i < len(oldSched); i++ { 851 dinfo = append(dinfo, dentry{}) 852 } 853 854 // Load static desired register info at the end of the block. 855 desired.copy(&s.desired[b.ID]) 856 857 // Check actual assigned registers at the start of the next block(s). 858 // Dynamically assigned registers will trump the static 859 // desired registers computed during liveness analysis. 860 // Note that we do this phase after startRegs is set above, so that 861 // we get the right behavior for a block which branches to itself. 862 for _, e := range b.Succs { 863 succ := e.b 864 // TODO: prioritize likely successor? 865 for _, x := range s.startRegs[succ.ID] { 866 desired.add(x.vid, x.r) 867 } 868 // Process phi ops in succ. 869 pidx := e.i 870 for _, v := range succ.Values { 871 if v.Op != OpPhi { 872 break 873 } 874 if !s.values[v.ID].needReg { 875 continue 876 } 877 rp, ok := s.f.getHome(v.ID).(*Register) 878 if !ok { 879 continue 880 } 881 desired.add(v.Args[pidx].ID, register(rp.Num)) 882 } 883 } 884 // Walk values backwards computing desired register info. 885 // See computeLive for more comments. 886 for i := len(oldSched) - 1; i >= 0; i-- { 887 v := oldSched[i] 888 prefs := desired.remove(v.ID) 889 desired.clobber(opcodeTable[v.Op].reg.clobbers) 890 for _, j := range opcodeTable[v.Op].reg.inputs { 891 if countRegs(j.regs) != 1 { 892 continue 893 } 894 desired.clobber(j.regs) 895 desired.add(v.Args[j.idx].ID, pickReg(j.regs)) 896 } 897 if opcodeTable[v.Op].resultInArg0 { 898 if opcodeTable[v.Op].commutative { 899 desired.addList(v.Args[1].ID, prefs) 900 } 901 desired.addList(v.Args[0].ID, prefs) 902 } 903 // Save desired registers for this value. 904 dinfo[i].out = prefs 905 for j, a := range v.Args { 906 if j >= len(dinfo[i].in) { 907 break 908 } 909 dinfo[i].in[j] = desired.get(a.ID) 910 } 911 } 912 913 // Process all the non-phi values. 914 for idx, v := range oldSched { 915 if s.f.pass.debug > regDebug { 916 fmt.Printf(" processing %s\n", v.LongString()) 917 } 918 if v.Op == OpPhi { 919 f.Fatalf("phi %s not at start of block", v) 920 } 921 if v.Op == OpSP { 922 s.assignReg(s.SPReg, v, v) 923 b.Values = append(b.Values, v) 924 s.advanceUses(v) 925 continue 926 } 927 if v.Op == OpSB { 928 s.assignReg(s.SBReg, v, v) 929 b.Values = append(b.Values, v) 930 s.advanceUses(v) 931 continue 932 } 933 if v.Op == OpArg { 934 // Args are "pre-spilled" values. We don't allocate 935 // any register here. We just set up the spill pointer to 936 // point at itself and any later user will restore it to use it. 937 s.values[v.ID].spill = v 938 s.values[v.ID].spillUsed = true // use is guaranteed 939 b.Values = append(b.Values, v) 940 s.advanceUses(v) 941 continue 942 } 943 if v.Op == OpKeepAlive { 944 // Make sure the argument to v is still live here. 945 s.advanceUses(v) 946 vi := &s.values[v.Args[0].ID] 947 if vi.spillUsed { 948 // Use the spill location. 949 v.SetArg(0, vi.spill) 950 } else { 951 // No need to keep unspilled values live. 952 // These are typically rematerializeable constants like nil, 953 // or values of a variable that were modified since the last call. 954 v.Op = OpCopy 955 v.SetArgs1(v.Args[1]) 956 } 957 b.Values = append(b.Values, v) 958 continue 959 } 960 regspec := opcodeTable[v.Op].reg 961 if len(regspec.inputs) == 0 && len(regspec.outputs) == 0 { 962 // No register allocation required (or none specified yet) 963 s.freeRegs(regspec.clobbers) 964 b.Values = append(b.Values, v) 965 s.advanceUses(v) 966 continue 967 } 968 969 if s.values[v.ID].rematerializeable { 970 // Value is rematerializeable, don't issue it here. 971 // It will get issued just before each use (see 972 // allocValueToReg). 973 for _, a := range v.Args { 974 a.Uses-- 975 } 976 s.advanceUses(v) 977 continue 978 } 979 980 if s.f.pass.debug > regDebug { 981 fmt.Printf("value %s\n", v.LongString()) 982 fmt.Printf(" out:") 983 for _, r := range dinfo[idx].out { 984 if r != noRegister { 985 fmt.Printf(" %s", s.registers[r].Name()) 986 } 987 } 988 fmt.Println() 989 for i := 0; i < len(v.Args) && i < 3; i++ { 990 fmt.Printf(" in%d:", i) 991 for _, r := range dinfo[idx].in[i] { 992 if r != noRegister { 993 fmt.Printf(" %s", s.registers[r].Name()) 994 } 995 } 996 fmt.Println() 997 } 998 } 999 1000 // Move arguments to registers. Process in an ordering defined 1001 // by the register specification (most constrained first). 1002 args = append(args[:0], v.Args...) 1003 for _, i := range regspec.inputs { 1004 mask := i.regs 1005 if mask == flagRegMask { 1006 // TODO: remove flag input from regspec.inputs. 1007 continue 1008 } 1009 if mask&s.values[args[i.idx].ID].regs == 0 { 1010 // Need a new register for the input. 1011 mask &= s.allocatable 1012 mask &^= s.nospill 1013 // Used desired register if available. 1014 if i.idx < 3 { 1015 for _, r := range dinfo[idx].in[i.idx] { 1016 if r != noRegister && (mask&^s.used)>>r&1 != 0 { 1017 // Desired register is allowed and unused. 1018 mask = regMask(1) << r 1019 break 1020 } 1021 } 1022 } 1023 // Avoid registers we're saving for other values. 1024 if mask&^desired.avoid != 0 { 1025 mask &^= desired.avoid 1026 } 1027 } 1028 args[i.idx] = s.allocValToReg(args[i.idx], mask, true, v.Line) 1029 } 1030 1031 // If the output clobbers the input register, make sure we have 1032 // at least two copies of the input register so we don't 1033 // have to reload the value from the spill location. 1034 if opcodeTable[v.Op].resultInArg0 { 1035 var m regMask 1036 if !s.liveAfterCurrentInstruction(v.Args[0]) { 1037 // arg0 is dead. We can clobber its register. 1038 goto ok 1039 } 1040 if countRegs(s.values[v.Args[0].ID].regs) >= 2 { 1041 // we have at least 2 copies of arg0. We can afford to clobber one. 1042 goto ok 1043 } 1044 if opcodeTable[v.Op].commutative { 1045 if !s.liveAfterCurrentInstruction(v.Args[1]) { 1046 args[0], args[1] = args[1], args[0] 1047 goto ok 1048 } 1049 if countRegs(s.values[v.Args[1].ID].regs) >= 2 { 1050 args[0], args[1] = args[1], args[0] 1051 goto ok 1052 } 1053 } 1054 1055 // We can't overwrite arg0 (or arg1, if commutative). So we 1056 // need to make a copy of an input so we have a register we can modify. 1057 1058 // Possible new registers to copy into. 1059 m = s.compatRegs(v.Args[0].Type) &^ s.used 1060 if m == 0 { 1061 // No free registers. In this case we'll just clobber 1062 // an input and future uses of that input must use a restore. 1063 // TODO(khr): We should really do this like allocReg does it, 1064 // spilling the value with the most distant next use. 1065 goto ok 1066 } 1067 1068 // Try to move an input to the desired output. 1069 for _, r := range dinfo[idx].out { 1070 if r != noRegister && m>>r&1 != 0 { 1071 m = regMask(1) << r 1072 args[0] = s.allocValToReg(v.Args[0], m, true, v.Line) 1073 // Note: we update args[0] so the instruction will 1074 // use the register copy we just made. 1075 goto ok 1076 } 1077 } 1078 // Try to copy input to its desired location & use its old 1079 // location as the result register. 1080 for _, r := range dinfo[idx].in[0] { 1081 if r != noRegister && m>>r&1 != 0 { 1082 m = regMask(1) << r 1083 s.allocValToReg(v.Args[0], m, true, v.Line) 1084 // Note: no update to args[0] so the instruction will 1085 // use the original copy. 1086 goto ok 1087 } 1088 } 1089 if opcodeTable[v.Op].commutative { 1090 for _, r := range dinfo[idx].in[1] { 1091 if r != noRegister && m>>r&1 != 0 { 1092 m = regMask(1) << r 1093 s.allocValToReg(v.Args[1], m, true, v.Line) 1094 args[0], args[1] = args[1], args[0] 1095 goto ok 1096 } 1097 } 1098 } 1099 // Avoid future fixed uses if we can. 1100 if m&^desired.avoid != 0 { 1101 m &^= desired.avoid 1102 } 1103 // Save input 0 to a new register so we can clobber it. 1104 s.allocValToReg(v.Args[0], m, true, v.Line) 1105 ok: 1106 } 1107 1108 // Now that all args are in regs, we're ready to issue the value itself. 1109 // Before we pick a register for the output value, allow input registers 1110 // to be deallocated. We do this here so that the output can use the 1111 // same register as a dying input. 1112 s.nospill = 0 1113 s.advanceUses(v) // frees any registers holding args that are no longer live 1114 1115 // Dump any registers which will be clobbered 1116 s.freeRegs(regspec.clobbers) 1117 1118 // Pick register for output. 1119 if s.values[v.ID].needReg { 1120 mask := regspec.outputs[0] & s.allocatable 1121 if opcodeTable[v.Op].resultInArg0 { 1122 if !opcodeTable[v.Op].commutative { 1123 // Output must use the same register as input 0. 1124 r := register(s.f.getHome(args[0].ID).(*Register).Num) 1125 mask = regMask(1) << r 1126 } else { 1127 // Output must use the same register as input 0 or 1. 1128 r0 := register(s.f.getHome(args[0].ID).(*Register).Num) 1129 r1 := register(s.f.getHome(args[1].ID).(*Register).Num) 1130 // Check r0 and r1 for desired output register. 1131 found := false 1132 for _, r := range dinfo[idx].out { 1133 if (r == r0 || r == r1) && (mask&^s.used)>>r&1 != 0 { 1134 mask = regMask(1) << r 1135 found = true 1136 if r == r1 { 1137 args[0], args[1] = args[1], args[0] 1138 } 1139 break 1140 } 1141 } 1142 if !found { 1143 // Neither are desired, pick r0. 1144 mask = regMask(1) << r0 1145 } 1146 } 1147 } 1148 for _, r := range dinfo[idx].out { 1149 if r != noRegister && (mask&^s.used)>>r&1 != 0 { 1150 // Desired register is allowed and unused. 1151 mask = regMask(1) << r 1152 break 1153 } 1154 } 1155 // Avoid registers we're saving for other values. 1156 if mask&^desired.avoid != 0 { 1157 mask &^= desired.avoid 1158 } 1159 r := s.allocReg(v, mask) 1160 s.assignReg(r, v, v) 1161 } 1162 1163 // Issue the Value itself. 1164 for i, a := range args { 1165 v.SetArg(i, a) // use register version of arguments 1166 } 1167 b.Values = append(b.Values, v) 1168 1169 // Issue a spill for this value. We issue spills unconditionally, 1170 // then at the end of regalloc delete the ones we never use. 1171 // TODO: schedule the spill at a point that dominates all restores. 1172 // The restore may be off in an unlikely branch somewhere and it 1173 // would be better to have the spill in that unlikely branch as well. 1174 // v := ... 1175 // if unlikely { 1176 // f() 1177 // } 1178 // It would be good to have both spill and restore inside the IF. 1179 if s.values[v.ID].needReg { 1180 spill := b.NewValue1(v.Line, OpStoreReg, v.Type, v) 1181 s.setOrig(spill, v) 1182 s.values[v.ID].spill = spill 1183 s.values[v.ID].spillUsed = false 1184 if loop != nil { 1185 loop.spills = append(loop.spills, v) 1186 nSpillsInner++ 1187 } 1188 nSpills++ 1189 } 1190 } 1191 1192 // Load control value into reg. 1193 if v := b.Control; v != nil && s.values[v.ID].needReg { 1194 if s.f.pass.debug > regDebug { 1195 fmt.Printf(" processing control %s\n", v.LongString()) 1196 } 1197 // TODO: regspec for block control values, instead of using 1198 // register set from the control op's output. 1199 s.allocValToReg(v, opcodeTable[v.Op].reg.outputs[0], false, b.Line) 1200 // Remove this use from the uses list. 1201 vi := &s.values[v.ID] 1202 u := vi.uses 1203 vi.uses = u.next 1204 if u.next == nil { 1205 s.freeRegs(vi.regs) // value is dead 1206 } 1207 u.next = s.freeUseRecords 1208 s.freeUseRecords = u 1209 } 1210 1211 // If we are approaching a merge point and we are the primary 1212 // predecessor of it, find live values that we use soon after 1213 // the merge point and promote them to registers now. 1214 if len(b.Succs) == 1 { 1215 // For this to be worthwhile, the loop must have no calls in it. 1216 top := b.Succs[0].b 1217 loop := s.loopnest.b2l[top.ID] 1218 if loop == nil || loop.header != top || loop.containsCall { 1219 goto badloop 1220 } 1221 1222 // TODO: sort by distance, pick the closest ones? 1223 for _, live := range s.live[b.ID] { 1224 if live.dist >= unlikelyDistance { 1225 // Don't preload anything live after the loop. 1226 continue 1227 } 1228 vid := live.ID 1229 vi := &s.values[vid] 1230 if vi.regs != 0 { 1231 continue 1232 } 1233 v := s.orig[vid] 1234 m := s.compatRegs(v.Type) &^ s.used 1235 if m&^desired.avoid != 0 { 1236 m &^= desired.avoid 1237 } 1238 if m != 0 { 1239 s.allocValToReg(v, m, false, b.Line) 1240 } 1241 } 1242 } 1243 badloop: 1244 ; 1245 1246 // Save end-of-block register state. 1247 // First count how many, this cuts allocations in half. 1248 k := 0 1249 for r := register(0); r < s.numRegs; r++ { 1250 v := s.regs[r].v 1251 if v == nil { 1252 continue 1253 } 1254 k++ 1255 } 1256 regList := make([]endReg, 0, k) 1257 for r := register(0); r < s.numRegs; r++ { 1258 v := s.regs[r].v 1259 if v == nil { 1260 continue 1261 } 1262 regList = append(regList, endReg{r, v, s.regs[r].c}) 1263 } 1264 s.endRegs[b.ID] = regList 1265 1266 // Check. TODO: remove 1267 { 1268 liveSet.clear() 1269 for _, x := range s.live[b.ID] { 1270 liveSet.add(x.ID) 1271 } 1272 for r := register(0); r < s.numRegs; r++ { 1273 v := s.regs[r].v 1274 if v == nil { 1275 continue 1276 } 1277 if !liveSet.contains(v.ID) { 1278 s.f.Fatalf("val %s is in reg but not live at end of %s", v, b) 1279 } 1280 } 1281 } 1282 1283 // If a value is live at the end of the block and 1284 // isn't in a register, remember that its spill location 1285 // is live. We need to remember this information so that 1286 // the liveness analysis in stackalloc is correct. 1287 for _, e := range s.live[b.ID] { 1288 if s.values[e.ID].regs != 0 { 1289 // in a register, we'll use that source for the merge. 1290 continue 1291 } 1292 spill := s.values[e.ID].spill 1293 if spill == nil { 1294 // rematerializeable values will have spill==nil. 1295 continue 1296 } 1297 s.spillLive[b.ID] = append(s.spillLive[b.ID], spill.ID) 1298 s.values[e.ID].spillUsed = true 1299 } 1300 1301 // Keep track of values that are spilled in the loop, but whose spill 1302 // is not used in the loop. It may be possible to move ("sink") the 1303 // spill out of the loop into one or more exit blocks. 1304 if loop != nil { 1305 loop.scratch++ // increment count of blocks in this loop that have been processed 1306 if loop.scratch == loop.nBlocks { // just processed last block of loop, if it is an inner loop. 1307 // This check is redundant with code at the top of the loop. 1308 // This is definitive; the one at the top of the loop is an optimization. 1309 if loop.isInner && // Common case, easier, most likely to be profitable 1310 !loop.containsCall && // Calls force spills, also lead to puzzling spill info. 1311 len(loop.exits) <= 32 { // Almost no inner loops have more than 32 exits, 1312 // and this allows use of a bitvector and a sparseMap. 1313 1314 // TODO: exit calculation is messed up for non-inner loops 1315 // because of multilevel exits that are not part of the "exit" 1316 // count. 1317 1318 // Compute the set of spill-movement candidates live at entry to exit blocks. 1319 // isLoopSpillCandidate filters for 1320 // (1) defined in appropriate loop 1321 // (2) needs a register 1322 // (3) spill not already used (in the loop) 1323 // Condition (3) === "in a register at all loop exits" 1324 1325 entryCandidates.clear() 1326 1327 for whichExit, ss := range loop.exits { 1328 // Start with live at end. 1329 for _, li := range s.live[ss.ID] { 1330 if s.isLoopSpillCandidate(loop, s.orig[li.ID]) { 1331 // s.live contains original IDs, use s.orig above to map back to *Value 1332 entryCandidates.setBit(li.ID, uint(whichExit)) 1333 } 1334 } 1335 // Control can also be live. 1336 if ss.Control != nil && s.orig[ss.Control.ID] != nil && s.isLoopSpillCandidate(loop, s.orig[ss.Control.ID]) { 1337 entryCandidates.setBit(s.orig[ss.Control.ID].ID, uint(whichExit)) 1338 } 1339 // Walk backwards, filling in locally live values, removing those defined. 1340 for i := len(ss.Values) - 1; i >= 0; i-- { 1341 v := ss.Values[i] 1342 vorig := s.orig[v.ID] 1343 if vorig != nil { 1344 entryCandidates.remove(vorig.ID) // Cannot be an issue, only keeps the sets smaller. 1345 } 1346 for _, a := range v.Args { 1347 aorig := s.orig[a.ID] 1348 if aorig != nil && s.isLoopSpillCandidate(loop, aorig) { 1349 entryCandidates.setBit(aorig.ID, uint(whichExit)) 1350 } 1351 } 1352 } 1353 } 1354 1355 for _, e := range loop.spills { 1356 whichblocks := entryCandidates.get(e.ID) 1357 oldSpill := s.values[e.ID].spill 1358 if whichblocks != 0 && whichblocks != -1 { // -1 = not in map. 1359 toSink = append(toSink, spillToSink{spill: oldSpill, dests: whichblocks}) 1360 } 1361 } 1362 1363 } // loop is inner etc 1364 loop.scratch = 0 // Don't leave a mess, just in case. 1365 loop.spills = nil 1366 } // if scratch == nBlocks 1367 } // if loop is not nil 1368 1369 // Clear any final uses. 1370 // All that is left should be the pseudo-uses added for values which 1371 // are live at the end of b. 1372 for _, e := range s.live[b.ID] { 1373 u := s.values[e.ID].uses 1374 if u == nil { 1375 f.Fatalf("live at end, no uses v%d", e.ID) 1376 } 1377 if u.next != nil { 1378 f.Fatalf("live at end, too many uses v%d", e.ID) 1379 } 1380 s.values[e.ID].uses = nil 1381 u.next = s.freeUseRecords 1382 s.freeUseRecords = u 1383 } 1384 } 1385 1386 // Erase any spills we never used 1387 for i := range s.values { 1388 vi := s.values[i] 1389 if vi.spillUsed { 1390 if s.f.pass.debug > logSpills { 1391 s.f.Config.Warnl(vi.spill.Line, "spilled value at %v remains", vi.spill) 1392 } 1393 continue 1394 } 1395 spill := vi.spill 1396 if spill == nil { 1397 // Constants, SP, SB, ... 1398 continue 1399 } 1400 loop := s.loopForBlock(spill.Block) 1401 if loop != nil { 1402 nSpillsInner-- 1403 } 1404 1405 spill.Args[0].Uses-- 1406 f.freeValue(spill) 1407 nSpills-- 1408 } 1409 1410 for _, b := range f.Blocks { 1411 i := 0 1412 for _, v := range b.Values { 1413 if v.Op == OpInvalid { 1414 continue 1415 } 1416 b.Values[i] = v 1417 i++ 1418 } 1419 b.Values = b.Values[:i] 1420 // TODO: zero b.Values[i:], recycle Values 1421 // Not important now because this is the last phase that manipulates Values 1422 } 1423 1424 // Must clear these out before any potential recycling, though that's 1425 // not currently implemented. 1426 for i, ts := range toSink { 1427 vsp := ts.spill 1428 if vsp.Op == OpInvalid { // This spill was completely eliminated 1429 toSink[i].spill = nil 1430 } 1431 } 1432 1433 // Anything that didn't get a register gets a stack location here. 1434 // (StoreReg, stack-based phis, inputs, ...) 1435 stacklive := stackalloc(s.f, s.spillLive) 1436 1437 // Fix up all merge edges. 1438 s.shuffle(stacklive) 1439 1440 // Insert moved spills (that have not been marked invalid above) 1441 // at start of appropriate block and remove the originals from their 1442 // location within loops. Notice that this can break SSA form; 1443 // if a spill is sunk to multiple exits, there will be no phi for that 1444 // spill at a join point downstream of those two exits, though the 1445 // two spills will target the same stack slot. Notice also that this 1446 // takes place after stack allocation, so the stack allocator does 1447 // not need to process these malformed flow graphs. 1448 sinking: 1449 for _, ts := range toSink { 1450 vsp := ts.spill 1451 if vsp == nil { // This spill was completely eliminated 1452 nSpillsSunkUnused++ 1453 continue sinking 1454 } 1455 e := ts.spilledValue() 1456 if s.values[e.ID].spillUsedShuffle { 1457 nSpillsNotSunkLateUse++ 1458 continue sinking 1459 } 1460 1461 // move spills to a better (outside of loop) block. 1462 // This would be costly if it occurred very often, but it doesn't. 1463 b := vsp.Block 1464 loop := s.loopnest.b2l[b.ID] 1465 dests := ts.dests 1466 1467 // Pre-check to be sure that spilled value is still in expected register on all exits where live. 1468 check_val_still_in_reg: 1469 for i := uint(0); i < 32 && dests != 0; i++ { 1470 1471 if dests&(1<<i) == 0 { 1472 continue 1473 } 1474 dests ^= 1 << i 1475 d := loop.exits[i] 1476 if len(d.Preds) > 1 { 1477 panic("Should be impossible given critical edges removed") 1478 } 1479 p := d.Preds[0].b // block in loop exiting to d. 1480 1481 endregs := s.endRegs[p.ID] 1482 for _, regrec := range endregs { 1483 if regrec.v == e && regrec.r != noRegister && regrec.c == e { // TODO: regrec.c != e implies different spill possible. 1484 continue check_val_still_in_reg 1485 } 1486 } 1487 // If here, the register assignment was lost down at least one exit and it can't be sunk 1488 if s.f.pass.debug > moveSpills { 1489 s.f.Config.Warnl(e.Line, "lost register assignment for spill %v in %v at exit %v to %v", 1490 vsp, b, p, d) 1491 } 1492 nSpillsChanged++ 1493 continue sinking 1494 } 1495 1496 nSpillsSunk++ 1497 nSpillsInner-- 1498 // don't update nSpills, since spill is only moved, and if it is duplicated, the spills-on-a-path is not increased. 1499 1500 dests = ts.dests 1501 1502 // remove vsp from b.Values 1503 i := 0 1504 for _, w := range b.Values { 1505 if vsp == w { 1506 continue 1507 } 1508 b.Values[i] = w 1509 i++ 1510 } 1511 b.Values = b.Values[:i] 1512 1513 first := true 1514 for i := uint(0); i < 32 && dests != 0; i++ { 1515 1516 if dests&(1<<i) == 0 { 1517 continue 1518 } 1519 1520 dests ^= 1 << i 1521 1522 d := loop.exits[i] 1523 vspnew := vsp // reuse original for first sunk spill, saves tracking down and renaming uses 1524 if !first { // any sunk spills after first must make a copy 1525 vspnew = d.NewValue1(e.Line, OpStoreReg, e.Type, e) 1526 f.setHome(vspnew, f.getHome(vsp.ID)) // copy stack home 1527 if s.f.pass.debug > moveSpills { 1528 s.f.Config.Warnl(e.Line, "copied spill %v in %v for %v to %v in %v", 1529 vsp, b, e, vspnew, d) 1530 } 1531 } else { 1532 first = false 1533 vspnew.Block = d 1534 d.Values = append(d.Values, vspnew) 1535 if s.f.pass.debug > moveSpills { 1536 s.f.Config.Warnl(e.Line, "moved spill %v in %v for %v to %v in %v", 1537 vsp, b, e, vspnew, d) 1538 } 1539 } 1540 1541 // shuffle vspnew to the beginning of its block 1542 copy(d.Values[1:], d.Values[0:len(d.Values)-1]) 1543 d.Values[0] = vspnew 1544 1545 } 1546 } 1547 1548 if f.pass.stats > 0 { 1549 f.LogStat("spills_info", 1550 nSpills, "spills", nSpillsInner, "inner_spills_remaining", nSpillsSunk, "inner_spills_sunk", nSpillsSunkUnused, "inner_spills_unused", nSpillsNotSunkLateUse, "inner_spills_shuffled", nSpillsChanged, "inner_spills_changed") 1551 } 1552 } 1553 1554 // isLoopSpillCandidate indicates whether the spill for v satisfies preliminary 1555 // spill-sinking conditions just after the last block of loop has been processed. 1556 // In particular: 1557 // v needs a register. 1558 // v's spill is not (YET) used. 1559 // v's definition is within loop. 1560 // The spill may be used in the future, either by an outright use 1561 // in the code, or by shuffling code inserted after stack allocation. 1562 // Outright uses cause sinking; shuffling (within the loop) inhibits it. 1563 func (s *regAllocState) isLoopSpillCandidate(loop *loop, v *Value) bool { 1564 return s.values[v.ID].needReg && !s.values[v.ID].spillUsed && s.loopnest.b2l[v.Block.ID] == loop 1565 } 1566 1567 // lateSpillUse notes a late (after stack allocation) use of the spill of value with ID vid. 1568 // This will inhibit spill sinking. 1569 func (s *regAllocState) lateSpillUse(vid ID) { 1570 // TODO investigate why this is necessary. 1571 // It appears that an outside-the-loop use of 1572 // an otherwise sinkable spill makes the spill 1573 // a candidate for shuffling, when it would not 1574 // otherwise have been the case (spillUsed was not 1575 // true when isLoopSpillCandidate was called, yet 1576 // it was shuffled). Such shuffling cuts the amount 1577 // of spill sinking by more than half (in make.bash) 1578 s.values[vid].spillUsedShuffle = true 1579 } 1580 1581 // shuffle fixes up all the merge edges (those going into blocks of indegree > 1). 1582 func (s *regAllocState) shuffle(stacklive [][]ID) { 1583 var e edgeState 1584 e.s = s 1585 e.cache = map[ID][]*Value{} 1586 e.contents = map[Location]contentRecord{} 1587 if s.f.pass.debug > regDebug { 1588 fmt.Printf("shuffle %s\n", s.f.Name) 1589 fmt.Println(s.f.String()) 1590 } 1591 1592 for _, b := range s.f.Blocks { 1593 if len(b.Preds) <= 1 { 1594 continue 1595 } 1596 e.b = b 1597 for i, edge := range b.Preds { 1598 p := edge.b 1599 e.p = p 1600 e.setup(i, s.endRegs[p.ID], s.startRegs[b.ID], stacklive[p.ID]) 1601 e.process() 1602 } 1603 } 1604 } 1605 1606 type edgeState struct { 1607 s *regAllocState 1608 p, b *Block // edge goes from p->b. 1609 1610 // for each pre-regalloc value, a list of equivalent cached values 1611 cache map[ID][]*Value 1612 cachedVals []ID // (superset of) keys of the above map, for deterministic iteration 1613 1614 // map from location to the value it contains 1615 contents map[Location]contentRecord 1616 1617 // desired destination locations 1618 destinations []dstRecord 1619 extra []dstRecord 1620 1621 usedRegs regMask // registers currently holding something 1622 uniqueRegs regMask // registers holding the only copy of a value 1623 finalRegs regMask // registers holding final target 1624 } 1625 1626 type contentRecord struct { 1627 vid ID // pre-regalloc value 1628 c *Value // cached value 1629 final bool // this is a satisfied destination 1630 } 1631 1632 type dstRecord struct { 1633 loc Location // register or stack slot 1634 vid ID // pre-regalloc value it should contain 1635 splice **Value // place to store reference to the generating instruction 1636 } 1637 1638 // setup initializes the edge state for shuffling. 1639 func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive []ID) { 1640 if e.s.f.pass.debug > regDebug { 1641 fmt.Printf("edge %s->%s\n", e.p, e.b) 1642 } 1643 1644 // Clear state. 1645 for _, vid := range e.cachedVals { 1646 delete(e.cache, vid) 1647 } 1648 e.cachedVals = e.cachedVals[:0] 1649 for k := range e.contents { 1650 delete(e.contents, k) 1651 } 1652 e.usedRegs = 0 1653 e.uniqueRegs = 0 1654 e.finalRegs = 0 1655 1656 // Live registers can be sources. 1657 for _, x := range srcReg { 1658 e.set(&e.s.registers[x.r], x.v.ID, x.c, false) 1659 } 1660 // So can all of the spill locations. 1661 for _, spillID := range stacklive { 1662 v := e.s.orig[spillID] 1663 spill := e.s.values[v.ID].spill 1664 e.set(e.s.f.getHome(spillID), v.ID, spill, false) 1665 } 1666 1667 // Figure out all the destinations we need. 1668 dsts := e.destinations[:0] 1669 for _, x := range dstReg { 1670 dsts = append(dsts, dstRecord{&e.s.registers[x.r], x.vid, nil}) 1671 } 1672 // Phis need their args to end up in a specific location. 1673 for _, v := range e.b.Values { 1674 if v.Op != OpPhi { 1675 break 1676 } 1677 loc := e.s.f.getHome(v.ID) 1678 if loc == nil { 1679 continue 1680 } 1681 dsts = append(dsts, dstRecord{loc, v.Args[idx].ID, &v.Args[idx]}) 1682 } 1683 e.destinations = dsts 1684 1685 if e.s.f.pass.debug > regDebug { 1686 for _, vid := range e.cachedVals { 1687 a := e.cache[vid] 1688 for _, c := range a { 1689 fmt.Printf("src %s: v%d cache=%s\n", e.s.f.getHome(c.ID).Name(), vid, c) 1690 } 1691 } 1692 for _, d := range e.destinations { 1693 fmt.Printf("dst %s: v%d\n", d.loc.Name(), d.vid) 1694 } 1695 } 1696 } 1697 1698 // process generates code to move all the values to the right destination locations. 1699 func (e *edgeState) process() { 1700 dsts := e.destinations 1701 1702 // Process the destinations until they are all satisfied. 1703 for len(dsts) > 0 { 1704 i := 0 1705 for _, d := range dsts { 1706 if !e.processDest(d.loc, d.vid, d.splice) { 1707 // Failed - save for next iteration. 1708 dsts[i] = d 1709 i++ 1710 } 1711 } 1712 if i < len(dsts) { 1713 // Made some progress. Go around again. 1714 dsts = dsts[:i] 1715 1716 // Append any extras destinations we generated. 1717 dsts = append(dsts, e.extra...) 1718 e.extra = e.extra[:0] 1719 continue 1720 } 1721 1722 // We made no progress. That means that any 1723 // remaining unsatisfied moves are in simple cycles. 1724 // For example, A -> B -> C -> D -> A. 1725 // A ----> B 1726 // ^ | 1727 // | | 1728 // | v 1729 // D <---- C 1730 1731 // To break the cycle, we pick an unused register, say R, 1732 // and put a copy of B there. 1733 // A ----> B 1734 // ^ | 1735 // | | 1736 // | v 1737 // D <---- C <---- R=copyofB 1738 // When we resume the outer loop, the A->B move can now proceed, 1739 // and eventually the whole cycle completes. 1740 1741 // Copy any cycle location to a temp register. This duplicates 1742 // one of the cycle entries, allowing the just duplicated value 1743 // to be overwritten and the cycle to proceed. 1744 loc := dsts[0].loc 1745 vid := e.contents[loc].vid 1746 c := e.contents[loc].c 1747 r := e.findRegFor(c.Type) 1748 if e.s.f.pass.debug > regDebug { 1749 fmt.Printf("breaking cycle with v%d in %s:%s\n", vid, loc.Name(), c) 1750 } 1751 if _, isReg := loc.(*Register); isReg { 1752 c = e.p.NewValue1(c.Line, OpCopy, c.Type, c) 1753 } else { 1754 e.s.lateSpillUse(vid) 1755 c = e.p.NewValue1(c.Line, OpLoadReg, c.Type, c) 1756 } 1757 e.set(r, vid, c, false) 1758 } 1759 } 1760 1761 // processDest generates code to put value vid into location loc. Returns true 1762 // if progress was made. 1763 func (e *edgeState) processDest(loc Location, vid ID, splice **Value) bool { 1764 occupant := e.contents[loc] 1765 if occupant.vid == vid { 1766 // Value is already in the correct place. 1767 e.contents[loc] = contentRecord{vid, occupant.c, true} 1768 if splice != nil { 1769 (*splice).Uses-- 1770 *splice = occupant.c 1771 occupant.c.Uses++ 1772 } 1773 // Note: if splice==nil then c will appear dead. This is 1774 // non-SSA formed code, so be careful after this pass not to run 1775 // deadcode elimination. 1776 return true 1777 } 1778 1779 // Check if we're allowed to clobber the destination location. 1780 if len(e.cache[occupant.vid]) == 1 && !e.s.values[occupant.vid].rematerializeable { 1781 // We can't overwrite the last copy 1782 // of a value that needs to survive. 1783 return false 1784 } 1785 1786 // Copy from a source of v, register preferred. 1787 v := e.s.orig[vid] 1788 var c *Value 1789 var src Location 1790 if e.s.f.pass.debug > regDebug { 1791 fmt.Printf("moving v%d to %s\n", vid, loc.Name()) 1792 fmt.Printf("sources of v%d:", vid) 1793 } 1794 for _, w := range e.cache[vid] { 1795 h := e.s.f.getHome(w.ID) 1796 if e.s.f.pass.debug > regDebug { 1797 fmt.Printf(" %s:%s", h.Name(), w) 1798 } 1799 _, isreg := h.(*Register) 1800 if src == nil || isreg { 1801 c = w 1802 src = h 1803 } 1804 } 1805 if e.s.f.pass.debug > regDebug { 1806 if src != nil { 1807 fmt.Printf(" [use %s]\n", src.Name()) 1808 } else { 1809 fmt.Printf(" [no source]\n") 1810 } 1811 } 1812 _, dstReg := loc.(*Register) 1813 var x *Value 1814 if c == nil { 1815 if !e.s.values[vid].rematerializeable { 1816 e.s.f.Fatalf("can't find source for %s->%s: v%d\n", e.p, e.b, vid) 1817 } 1818 if dstReg { 1819 x = v.copyInto(e.p) 1820 } else { 1821 // Rematerialize into stack slot. Need a free 1822 // register to accomplish this. 1823 e.erase(loc) // see pre-clobber comment below 1824 r := e.findRegFor(v.Type) 1825 x = v.copyInto(e.p) 1826 e.set(r, vid, x, false) 1827 // Make sure we spill with the size of the slot, not the 1828 // size of x (which might be wider due to our dropping 1829 // of narrowing conversions). 1830 x = e.p.NewValue1(x.Line, OpStoreReg, loc.(LocalSlot).Type, x) 1831 } 1832 } else { 1833 // Emit move from src to dst. 1834 _, srcReg := src.(*Register) 1835 if srcReg { 1836 if dstReg { 1837 x = e.p.NewValue1(c.Line, OpCopy, c.Type, c) 1838 } else { 1839 x = e.p.NewValue1(c.Line, OpStoreReg, loc.(LocalSlot).Type, c) 1840 } 1841 } else { 1842 if dstReg { 1843 e.s.lateSpillUse(vid) 1844 x = e.p.NewValue1(c.Line, OpLoadReg, c.Type, c) 1845 } else { 1846 // mem->mem. Use temp register. 1847 1848 // Pre-clobber destination. This avoids the 1849 // following situation: 1850 // - v is currently held in R0 and stacktmp0. 1851 // - We want to copy stacktmp1 to stacktmp0. 1852 // - We choose R0 as the temporary register. 1853 // During the copy, both R0 and stacktmp0 are 1854 // clobbered, losing both copies of v. Oops! 1855 // Erasing the destination early means R0 will not 1856 // be chosen as the temp register, as it will then 1857 // be the last copy of v. 1858 e.erase(loc) 1859 1860 r := e.findRegFor(c.Type) 1861 e.s.lateSpillUse(vid) 1862 t := e.p.NewValue1(c.Line, OpLoadReg, c.Type, c) 1863 e.set(r, vid, t, false) 1864 x = e.p.NewValue1(c.Line, OpStoreReg, loc.(LocalSlot).Type, t) 1865 } 1866 } 1867 } 1868 e.set(loc, vid, x, true) 1869 if splice != nil { 1870 (*splice).Uses-- 1871 *splice = x 1872 x.Uses++ 1873 } 1874 return true 1875 } 1876 1877 // set changes the contents of location loc to hold the given value and its cached representative. 1878 func (e *edgeState) set(loc Location, vid ID, c *Value, final bool) { 1879 e.s.f.setHome(c, loc) 1880 e.erase(loc) 1881 e.contents[loc] = contentRecord{vid, c, final} 1882 a := e.cache[vid] 1883 if len(a) == 0 { 1884 e.cachedVals = append(e.cachedVals, vid) 1885 } 1886 a = append(a, c) 1887 e.cache[vid] = a 1888 if r, ok := loc.(*Register); ok { 1889 e.usedRegs |= regMask(1) << uint(r.Num) 1890 if final { 1891 e.finalRegs |= regMask(1) << uint(r.Num) 1892 } 1893 if len(a) == 1 { 1894 e.uniqueRegs |= regMask(1) << uint(r.Num) 1895 } 1896 if len(a) == 2 { 1897 if t, ok := e.s.f.getHome(a[0].ID).(*Register); ok { 1898 e.uniqueRegs &^= regMask(1) << uint(t.Num) 1899 } 1900 } 1901 } 1902 if e.s.f.pass.debug > regDebug { 1903 fmt.Printf("%s\n", c.LongString()) 1904 fmt.Printf("v%d now available in %s:%s\n", vid, loc.Name(), c) 1905 } 1906 } 1907 1908 // erase removes any user of loc. 1909 func (e *edgeState) erase(loc Location) { 1910 cr := e.contents[loc] 1911 if cr.c == nil { 1912 return 1913 } 1914 vid := cr.vid 1915 1916 if cr.final { 1917 // Add a destination to move this value back into place. 1918 // Make sure it gets added to the tail of the destination queue 1919 // so we make progress on other moves first. 1920 e.extra = append(e.extra, dstRecord{loc, cr.vid, nil}) 1921 } 1922 1923 // Remove c from the list of cached values. 1924 a := e.cache[vid] 1925 for i, c := range a { 1926 if e.s.f.getHome(c.ID) == loc { 1927 if e.s.f.pass.debug > regDebug { 1928 fmt.Printf("v%d no longer available in %s:%s\n", vid, loc.Name(), c) 1929 } 1930 a[i], a = a[len(a)-1], a[:len(a)-1] 1931 break 1932 } 1933 } 1934 e.cache[vid] = a 1935 1936 // Update register masks. 1937 if r, ok := loc.(*Register); ok { 1938 e.usedRegs &^= regMask(1) << uint(r.Num) 1939 if cr.final { 1940 e.finalRegs &^= regMask(1) << uint(r.Num) 1941 } 1942 } 1943 if len(a) == 1 { 1944 if r, ok := e.s.f.getHome(a[0].ID).(*Register); ok { 1945 e.uniqueRegs |= regMask(1) << uint(r.Num) 1946 } 1947 } 1948 } 1949 1950 // findRegFor finds a register we can use to make a temp copy of type typ. 1951 func (e *edgeState) findRegFor(typ Type) Location { 1952 // Which registers are possibilities. 1953 var m regMask 1954 if typ.IsFloat() { 1955 m = e.s.compatRegs(e.s.f.Config.fe.TypeFloat64()) 1956 } else { 1957 m = e.s.compatRegs(e.s.f.Config.fe.TypeInt64()) 1958 } 1959 1960 // Pick a register. In priority order: 1961 // 1) an unused register 1962 // 2) a non-unique register not holding a final value 1963 // 3) a non-unique register 1964 x := m &^ e.usedRegs 1965 if x != 0 { 1966 return &e.s.registers[pickReg(x)] 1967 } 1968 x = m &^ e.uniqueRegs &^ e.finalRegs 1969 if x != 0 { 1970 return &e.s.registers[pickReg(x)] 1971 } 1972 x = m &^ e.uniqueRegs 1973 if x != 0 { 1974 return &e.s.registers[pickReg(x)] 1975 } 1976 1977 // No register is available. Allocate a temp location to spill a register to. 1978 // The type of the slot is immaterial - it will not be live across 1979 // any safepoint. Just use a type big enough to hold any register. 1980 typ = e.s.f.Config.fe.TypeInt64() 1981 t := LocalSlot{e.s.f.Config.fe.Auto(typ), typ, 0} 1982 // TODO: reuse these slots. 1983 1984 // Pick a register to spill. 1985 for _, vid := range e.cachedVals { 1986 a := e.cache[vid] 1987 for _, c := range a { 1988 if r, ok := e.s.f.getHome(c.ID).(*Register); ok && m>>uint(r.Num)&1 != 0 { 1989 x := e.p.NewValue1(c.Line, OpStoreReg, c.Type, c) 1990 e.set(t, vid, x, false) 1991 if e.s.f.pass.debug > regDebug { 1992 fmt.Printf(" SPILL %s->%s %s\n", r.Name(), t.Name(), x.LongString()) 1993 } 1994 // r will now be overwritten by the caller. At some point 1995 // later, the newly saved value will be moved back to its 1996 // final destination in processDest. 1997 return r 1998 } 1999 } 2000 } 2001 2002 fmt.Printf("m:%d unique:%d final:%d\n", m, e.uniqueRegs, e.finalRegs) 2003 for _, vid := range e.cachedVals { 2004 a := e.cache[vid] 2005 for _, c := range a { 2006 fmt.Printf("v%d: %s %s\n", vid, c, e.s.f.getHome(c.ID).Name()) 2007 } 2008 } 2009 e.s.f.Fatalf("can't find empty register on edge %s->%s", e.p, e.b) 2010 return nil 2011 } 2012 2013 func (v *Value) rematerializeable() bool { 2014 if !opcodeTable[v.Op].rematerializeable { 2015 return false 2016 } 2017 for _, a := range v.Args { 2018 // SP and SB (generated by OpSP and OpSB) are always available. 2019 if a.Op != OpSP && a.Op != OpSB { 2020 return false 2021 } 2022 } 2023 return true 2024 } 2025 2026 type liveInfo struct { 2027 ID ID // ID of value 2028 dist int32 // # of instructions before next use 2029 } 2030 2031 // dblock contains information about desired & avoid registers at the end of a block. 2032 type dblock struct { 2033 prefers []desiredStateEntry 2034 avoid regMask 2035 } 2036 2037 // computeLive computes a map from block ID to a list of value IDs live at the end 2038 // of that block. Together with the value ID is a count of how many instructions 2039 // to the next use of that value. The resulting map is stored in s.live. 2040 // computeLive also computes the desired register information at the end of each block. 2041 // This desired register information is stored in s.desired. 2042 // TODO: this could be quadratic if lots of variables are live across lots of 2043 // basic blocks. Figure out a way to make this function (or, more precisely, the user 2044 // of this function) require only linear size & time. 2045 func (s *regAllocState) computeLive() { 2046 f := s.f 2047 s.live = make([][]liveInfo, f.NumBlocks()) 2048 s.desired = make([]desiredState, f.NumBlocks()) 2049 var phis []*Value 2050 2051 live := newSparseMap(f.NumValues()) 2052 t := newSparseMap(f.NumValues()) 2053 2054 // Keep track of which value we want in each register. 2055 var desired desiredState 2056 2057 // Instead of iterating over f.Blocks, iterate over their postordering. 2058 // Liveness information flows backward, so starting at the end 2059 // increases the probability that we will stabilize quickly. 2060 // TODO: Do a better job yet. Here's one possibility: 2061 // Calculate the dominator tree and locate all strongly connected components. 2062 // If a value is live in one block of an SCC, it is live in all. 2063 // Walk the dominator tree from end to beginning, just once, treating SCC 2064 // components as single blocks, duplicated calculated liveness information 2065 // out to all of them. 2066 s.loopnest = loopnestfor(f) 2067 po := s.loopnest.po 2068 for { 2069 changed := false 2070 2071 for _, b := range po { 2072 // Start with known live values at the end of the block. 2073 // Add len(b.Values) to adjust from end-of-block distance 2074 // to beginning-of-block distance. 2075 live.clear() 2076 d := int32(len(b.Values)) 2077 if b.Kind == BlockCall || b.Kind == BlockDefer { 2078 // Because we keep no values in registers across a call, 2079 // make every use past a call appear very far away. 2080 d += unlikelyDistance 2081 } 2082 for _, e := range s.live[b.ID] { 2083 live.set(e.ID, e.dist+d) 2084 } 2085 2086 // Mark control value as live 2087 if b.Control != nil && s.values[b.Control.ID].needReg { 2088 live.set(b.Control.ID, int32(len(b.Values))) 2089 } 2090 2091 // Propagate backwards to the start of the block 2092 // Assumes Values have been scheduled. 2093 phis = phis[:0] 2094 for i := len(b.Values) - 1; i >= 0; i-- { 2095 v := b.Values[i] 2096 live.remove(v.ID) 2097 if v.Op == OpPhi { 2098 // save phi ops for later 2099 phis = append(phis, v) 2100 continue 2101 } 2102 for _, a := range v.Args { 2103 if s.values[a.ID].needReg { 2104 live.set(a.ID, int32(i)) 2105 } 2106 } 2107 } 2108 // Propagate desired registers backwards. 2109 desired.copy(&s.desired[b.ID]) 2110 for i := len(b.Values) - 1; i >= 0; i-- { 2111 v := b.Values[i] 2112 prefs := desired.remove(v.ID) 2113 if v.Op == OpPhi { 2114 // TODO: if v is a phi, save desired register for phi inputs. 2115 // For now, we just drop it and don't propagate 2116 // desired registers back though phi nodes. 2117 continue 2118 } 2119 // Cancel desired registers if they get clobbered. 2120 desired.clobber(opcodeTable[v.Op].reg.clobbers) 2121 // Update desired registers if there are any fixed register inputs. 2122 for _, j := range opcodeTable[v.Op].reg.inputs { 2123 if countRegs(j.regs) != 1 { 2124 continue 2125 } 2126 desired.clobber(j.regs) 2127 desired.add(v.Args[j.idx].ID, pickReg(j.regs)) 2128 } 2129 // Set desired register of input 0 if this is a 2-operand instruction. 2130 if opcodeTable[v.Op].resultInArg0 { 2131 if opcodeTable[v.Op].commutative { 2132 desired.addList(v.Args[1].ID, prefs) 2133 } 2134 desired.addList(v.Args[0].ID, prefs) 2135 } 2136 } 2137 2138 // For each predecessor of b, expand its list of live-at-end values. 2139 // invariant: live contains the values live at the start of b (excluding phi inputs) 2140 for i, e := range b.Preds { 2141 p := e.b 2142 // Compute additional distance for the edge. 2143 // Note: delta must be at least 1 to distinguish the control 2144 // value use from the first user in a successor block. 2145 delta := int32(normalDistance) 2146 if len(p.Succs) == 2 { 2147 if p.Succs[0].b == b && p.Likely == BranchLikely || 2148 p.Succs[1].b == b && p.Likely == BranchUnlikely { 2149 delta = likelyDistance 2150 } 2151 if p.Succs[0].b == b && p.Likely == BranchUnlikely || 2152 p.Succs[1].b == b && p.Likely == BranchLikely { 2153 delta = unlikelyDistance 2154 } 2155 } 2156 2157 // Update any desired registers at the end of p. 2158 s.desired[p.ID].merge(&desired) 2159 2160 // Start t off with the previously known live values at the end of p. 2161 t.clear() 2162 for _, e := range s.live[p.ID] { 2163 t.set(e.ID, e.dist) 2164 } 2165 update := false 2166 2167 // Add new live values from scanning this block. 2168 for _, e := range live.contents() { 2169 d := e.val + delta 2170 if !t.contains(e.key) || d < t.get(e.key) { 2171 update = true 2172 t.set(e.key, d) 2173 } 2174 } 2175 // Also add the correct arg from the saved phi values. 2176 // All phis are at distance delta (we consider them 2177 // simultaneously happening at the start of the block). 2178 for _, v := range phis { 2179 id := v.Args[i].ID 2180 if s.values[id].needReg && (!t.contains(id) || delta < t.get(id)) { 2181 update = true 2182 t.set(id, delta) 2183 } 2184 } 2185 2186 if !update { 2187 continue 2188 } 2189 // The live set has changed, update it. 2190 l := s.live[p.ID][:0] 2191 if cap(l) < t.size() { 2192 l = make([]liveInfo, 0, t.size()) 2193 } 2194 for _, e := range t.contents() { 2195 l = append(l, liveInfo{e.key, e.val}) 2196 } 2197 s.live[p.ID] = l 2198 changed = true 2199 } 2200 } 2201 2202 if !changed { 2203 break 2204 } 2205 } 2206 if f.pass.debug > regDebug { 2207 fmt.Println("live values at end of each block") 2208 for _, b := range f.Blocks { 2209 fmt.Printf(" %s:", b) 2210 for _, x := range s.live[b.ID] { 2211 fmt.Printf(" v%d", x.ID) 2212 for _, e := range s.desired[b.ID].entries { 2213 if e.ID != x.ID { 2214 continue 2215 } 2216 fmt.Printf("[") 2217 first := true 2218 for _, r := range e.regs { 2219 if r == noRegister { 2220 continue 2221 } 2222 if !first { 2223 fmt.Printf(",") 2224 } 2225 fmt.Print(s.registers[r].Name()) 2226 first = false 2227 } 2228 fmt.Printf("]") 2229 } 2230 } 2231 fmt.Printf(" avoid=%x", int64(s.desired[b.ID].avoid)) 2232 fmt.Println() 2233 } 2234 } 2235 } 2236 2237 // A desiredState represents desired register assignments. 2238 type desiredState struct { 2239 // Desired assignments will be small, so we just use a list 2240 // of valueID+registers entries. 2241 entries []desiredStateEntry 2242 // Registers that other values want to be in. This value will 2243 // contain at least the union of the regs fields of entries, but 2244 // may contain additional entries for values that were once in 2245 // this data structure but are no longer. 2246 avoid regMask 2247 } 2248 type desiredStateEntry struct { 2249 // (pre-regalloc) value 2250 ID ID 2251 // Registers it would like to be in, in priority order. 2252 // Unused slots are filled with noRegister. 2253 regs [4]register 2254 } 2255 2256 func (d *desiredState) clear() { 2257 d.entries = d.entries[:0] 2258 d.avoid = 0 2259 } 2260 2261 // get returns a list of desired registers for value vid. 2262 func (d *desiredState) get(vid ID) [4]register { 2263 for _, e := range d.entries { 2264 if e.ID == vid { 2265 return e.regs 2266 } 2267 } 2268 return [4]register{noRegister, noRegister, noRegister, noRegister} 2269 } 2270 2271 // add records that we'd like value vid to be in register r. 2272 func (d *desiredState) add(vid ID, r register) { 2273 d.avoid |= regMask(1) << r 2274 for i := range d.entries { 2275 e := &d.entries[i] 2276 if e.ID != vid { 2277 continue 2278 } 2279 if e.regs[0] == r { 2280 // Already known and highest priority 2281 return 2282 } 2283 for j := 1; j < len(e.regs); j++ { 2284 if e.regs[j] == r { 2285 // Move from lower priority to top priority 2286 copy(e.regs[1:], e.regs[:j]) 2287 e.regs[0] = r 2288 return 2289 } 2290 } 2291 copy(e.regs[1:], e.regs[:]) 2292 e.regs[0] = r 2293 return 2294 } 2295 d.entries = append(d.entries, desiredStateEntry{vid, [4]register{r, noRegister, noRegister, noRegister}}) 2296 } 2297 2298 func (d *desiredState) addList(vid ID, regs [4]register) { 2299 // regs is in priority order, so iterate in reverse order. 2300 for i := len(regs) - 1; i >= 0; i-- { 2301 r := regs[i] 2302 if r != noRegister { 2303 d.add(vid, r) 2304 } 2305 } 2306 } 2307 2308 // clobber erases any desired registers in the set m. 2309 func (d *desiredState) clobber(m regMask) { 2310 for i := 0; i < len(d.entries); { 2311 e := &d.entries[i] 2312 j := 0 2313 for _, r := range e.regs { 2314 if r != noRegister && m>>r&1 == 0 { 2315 e.regs[j] = r 2316 j++ 2317 } 2318 } 2319 if j == 0 { 2320 // No more desired registers for this value. 2321 d.entries[i] = d.entries[len(d.entries)-1] 2322 d.entries = d.entries[:len(d.entries)-1] 2323 continue 2324 } 2325 for ; j < len(e.regs); j++ { 2326 e.regs[j] = noRegister 2327 } 2328 i++ 2329 } 2330 d.avoid &^= m 2331 } 2332 2333 // copy copies a desired state from another desiredState x. 2334 func (d *desiredState) copy(x *desiredState) { 2335 d.entries = append(d.entries[:0], x.entries...) 2336 d.avoid = x.avoid 2337 } 2338 2339 // remove removes the desired registers for vid and returns them. 2340 func (d *desiredState) remove(vid ID) [4]register { 2341 for i := range d.entries { 2342 if d.entries[i].ID == vid { 2343 regs := d.entries[i].regs 2344 d.entries[i] = d.entries[len(d.entries)-1] 2345 d.entries = d.entries[:len(d.entries)-1] 2346 return regs 2347 } 2348 } 2349 return [4]register{noRegister, noRegister, noRegister, noRegister} 2350 } 2351 2352 // merge merges another desired state x into d. 2353 func (d *desiredState) merge(x *desiredState) { 2354 d.avoid |= x.avoid 2355 // There should only be a few desired registers, so 2356 // linear insert is ok. 2357 for _, e := range x.entries { 2358 d.addList(e.ID, e.regs) 2359 } 2360 }