diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-01-11 22:52:14 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-01-11 22:52:14 +0000 |
commit | a8bd9a68f7c00fe1d895bb5e27ff804aa33abd64 (patch) | |
tree | 99f9b3bde43889183edaf926d91ca84991fd8545 /lib/CodeGen/RegAllocBasic.cpp | |
parent | 078203f301baaa1fc96e172708f4bf7f9c7dcf82 (diff) |
Sink spillInterferences into RABasic.
This helper method is too simplistic for RAGreedy.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147976 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocBasic.cpp')
-rw-r--r-- | lib/CodeGen/RegAllocBasic.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/CodeGen/RegAllocBasic.cpp b/lib/CodeGen/RegAllocBasic.cpp index a67a6169be..a659f5b782 100644 --- a/lib/CodeGen/RegAllocBasic.cpp +++ b/lib/CodeGen/RegAllocBasic.cpp @@ -107,6 +107,15 @@ public: /// Perform register allocation. virtual bool runOnMachineFunction(MachineFunction &mf); + // Helper for spilling all live virtual registers currently unified under preg + // that interfere with the most recently queried lvr. Return true if spilling + // was successful, and append any new spilled/split intervals to splitLVRs. + bool spillInterferences(LiveInterval &VirtReg, unsigned PhysReg, + SmallVectorImpl<LiveInterval*> &SplitVRegs); + + void spillReg(LiveInterval &VirtReg, unsigned PhysReg, + SmallVectorImpl<LiveInterval*> &SplitVRegs); + static char ID; }; @@ -157,6 +166,59 @@ void RABasic::releaseMemory() { RegAllocBase::releaseMemory(); } +// Helper for spillInterferences() that spills all interfering vregs currently +// assigned to this physical register. +void RABasic::spillReg(LiveInterval& VirtReg, unsigned PhysReg, + SmallVectorImpl<LiveInterval*> &SplitVRegs) { + LiveIntervalUnion::Query &Q = query(VirtReg, PhysReg); + assert(Q.seenAllInterferences() && "need collectInterferences()"); + const SmallVectorImpl<LiveInterval*> &PendingSpills = Q.interferingVRegs(); + + for (SmallVectorImpl<LiveInterval*>::const_iterator I = PendingSpills.begin(), + E = PendingSpills.end(); I != E; ++I) { + LiveInterval &SpilledVReg = **I; + DEBUG(dbgs() << "extracting from " << + TRI->getName(PhysReg) << " " << SpilledVReg << '\n'); + + // Deallocate the interfering vreg by removing it from the union. + // A LiveInterval instance may not be in a union during modification! + unassign(SpilledVReg, PhysReg); + + // Spill the extracted interval. + LiveRangeEdit LRE(SpilledVReg, SplitVRegs, 0, &PendingSpills); + spiller().spill(LRE); + } + // After extracting segments, the query's results are invalid. But keep the + // contents valid until we're done accessing pendingSpills. + Q.clear(); +} + +// Spill or split all live virtual registers currently unified under PhysReg +// that interfere with VirtReg. The newly spilled or split live intervals are +// returned by appending them to SplitVRegs. +bool RABasic::spillInterferences(LiveInterval &VirtReg, unsigned PhysReg, + SmallVectorImpl<LiveInterval*> &SplitVRegs) { + // Record each interference and determine if all are spillable before mutating + // either the union or live intervals. + unsigned NumInterferences = 0; + // Collect interferences assigned to any alias of the physical register. + for (const unsigned *asI = TRI->getOverlaps(PhysReg); *asI; ++asI) { + LiveIntervalUnion::Query &QAlias = query(VirtReg, *asI); + NumInterferences += QAlias.collectInterferingVRegs(); + if (QAlias.seenUnspillableVReg()) { + return false; + } + } + DEBUG(dbgs() << "spilling " << TRI->getName(PhysReg) << + " interferences with " << VirtReg << "\n"); + assert(NumInterferences > 0 && "expect interference"); + + // Spill each interfering vreg allocated to PhysReg or an alias. + for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI) + spillReg(VirtReg, *AliasI, SplitVRegs); + return true; +} + // Driver for the register assignment and splitting heuristics. // Manages iteration over the LiveIntervalUnions. // |