| 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
|
|
|