Index: src/IceRegAlloc.cpp |
diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp |
index 2d5ff9b0dae87018fa06ad88d369b1cb5da69f69..36018466da2474b956d4f9f08b88edcd8790c223 100644 |
--- a/src/IceRegAlloc.cpp |
+++ b/src/IceRegAlloc.cpp |
@@ -141,7 +141,7 @@ void LinearScan::initForGlobal() { |
// |
// Some properties we aren't (yet) taking advantage of: |
// |
-// * Because live ranges are a single segment, the Unhandled set will |
+// * Because live ranges are a single segment, the Inactive set will |
// always be empty, and the live range trimming operation is |
// unnecessary. |
// |
@@ -258,7 +258,8 @@ void LinearScan::init(RegAllocKind Kind) { |
// Requires running Cfg::liveness(Liveness_Intervals) in |
// preparation. Results are assigned to Variable::RegNum for each |
// Variable. |
-void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
+void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull, |
+ bool Randomized) { |
TimerMarker T(TimerStack::TT_linearScan, Func); |
assert(RegMaskFull.any()); // Sanity check |
Ostream &Str = Func->getContext()->getStrDump(); |
@@ -266,6 +267,13 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
ALLOW_DUMP && Func->getContext()->isVerbose(IceV_LinearScan); |
Func->resetCurrentNode(); |
VariablesMetadata *VMetadata = Func->getVMetadata(); |
+ const size_t NumRegisters = RegMaskFull.size(); |
+ llvm::SmallBitVector PreDefinedRegisters(NumRegisters); |
+ if (Randomized) { |
+ for (Variable *Var : UnhandledPrecolored) { |
+ PreDefinedRegisters[Var->getRegNum()] = true; |
+ } |
+ } |
// Build a LiveRange representing the Kills list. |
LiveRange KillsRange(Kills); |
@@ -274,7 +282,7 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
// RegUses[I] is the number of live ranges (variables) that register |
// I is currently assigned to. It can be greater than 1 as a result |
// of AllowOverlap inference below. |
- std::vector<int> RegUses(RegMaskFull.size()); |
+ std::vector<int> RegUses(NumRegisters); |
// Unhandled is already set to all ranges in increasing order of |
// start points. |
assert(Active.empty()); |
@@ -662,23 +670,39 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
Inactive.clear(); |
dump(Func); |
- // Finish up by assigning RegNumTmp->RegNum for each Variable. |
+ // TODO(stichnot): Statically choose the size based on the target |
+ // being compiled. |
+ const size_t REGS_SIZE = 32; |
+ llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); |
+ if (Randomized) { |
+ Func->getTarget()->makeRandomRegisterPermutation( |
+ Permutation, PreDefinedRegisters | ~RegMaskFull); |
+ } |
+ |
+ // Finish up by assigning RegNumTmp->RegNum (or a random permutation |
+ // thereof) for each Variable. |
for (Variable *Item : Handled) { |
int32_t RegNum = Item->getRegNumTmp(); |
+ int32_t AssignedRegNum = RegNum; |
+ |
+ if (Randomized && Item->hasRegTmp() && !Item->hasReg()) { |
+ AssignedRegNum = Permutation[RegNum]; |
+ } |
if (Verbose) { |
if (!Item->hasRegTmp()) { |
Str << "Not assigning "; |
Item->dump(Func); |
Str << "\n"; |
} else { |
- Str << (RegNum == Item->getRegNum() ? "Reassigning " : "Assigning ") |
- << Func->getTarget()->getRegName(RegNum, IceType_i32) << "(r" |
- << RegNum << ") to "; |
+ Str << (AssignedRegNum == Item->getRegNum() ? "Reassigning " |
+ : "Assigning ") |
+ << Func->getTarget()->getRegName(AssignedRegNum, IceType_i32) |
+ << "(r" << AssignedRegNum << ") to "; |
Item->dump(Func); |
Str << "\n"; |
} |
} |
- Item->setRegNum(Item->getRegNumTmp()); |
+ Item->setRegNum(AssignedRegNum); |
} |
// TODO: Consider running register allocation one more time, with |