| Index: src/IceRegAlloc.cpp
|
| diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp
|
| index 10a02a3ee381dfd44c8574a75e16b735f3c56cf3..fc6d2bdd879879791f04f635559dc26d3a3c7407 100644
|
| --- a/src/IceRegAlloc.cpp
|
| +++ b/src/IceRegAlloc.cpp
|
| @@ -32,7 +32,8 @@ namespace Ice {
|
| // Requires running Cfg::liveness(Liveness_RangesFull) 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) {
|
| assert(RegMaskFull.any()); // Sanity check
|
| Unhandled.clear();
|
| Handled.clear();
|
| @@ -40,6 +41,8 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) {
|
| Active.clear();
|
| Ostream &Str = Func->getContext()->getStrDump();
|
| Func->setCurrentNode(NULL);
|
| + const size_t NumRegisters = RegMaskFull.size();
|
| + llvm::SmallBitVector PreDefinedRegisters(NumRegisters);
|
|
|
| // Gather the live ranges of all variables and add them to the
|
| // Unhandled set. TODO: Unhandled is a set<> which is based on a
|
| @@ -61,15 +64,19 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) {
|
| continue;
|
| Unhandled.insert(LiveRangeWrapper(Var));
|
| if (Var->hasReg()) {
|
| - Var->setRegNumTmp(Var->getRegNum());
|
| + int32_t RegNum = Var->getRegNum();
|
| + Var->setRegNumTmp(RegNum);
|
| Var->setLiveRangeInfiniteWeight();
|
| + if (Var->getIsArg() || Var->getDefinition()) {
|
| + PreDefinedRegisters[RegNum] = true;
|
| + }
|
| }
|
| }
|
|
|
| // 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 Variable::AllowRegisterOverlap.
|
| - 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());
|
| @@ -397,25 +404,40 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) {
|
| }
|
| dump(Func);
|
|
|
| - // Finish up by assigning RegNumTmp->RegNum for each Variable.
|
| + // TODO: 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 (UnorderedRanges::const_iterator I = Handled.begin(), E = Handled.end();
|
| I != E; ++I) {
|
| - LiveRangeWrapper Item = *I;
|
| - int32_t RegNum = Item.Var->getRegNumTmp();
|
| + Variable *Var = I->Var;
|
| + int32_t RegNum = Var->getRegNumTmp();
|
| + int32_t AssignedRegNum = RegNum;
|
| +
|
| + if (Randomized && Var->hasRegTmp() && !Var->hasReg()) {
|
| + AssignedRegNum = Permutation[RegNum];
|
| + }
|
| if (Func->getContext()->isVerbose(IceV_LinearScan)) {
|
| - if (!Item.Var->hasRegTmp()) {
|
| + if (!Var->hasRegTmp()) {
|
| Str << "Not assigning ";
|
| - Item.Var->dump(Func);
|
| + Var->dump(Func);
|
| Str << "\n";
|
| } else {
|
| - Str << (RegNum == Item.Var->getRegNum() ? "Reassigning " : "Assigning ")
|
| - << Func->getTarget()->getRegName(RegNum, IceType_i32) << "(r"
|
| - << RegNum << ") to ";
|
| - Item.Var->dump(Func);
|
| + Str << (RegNum == Var->getRegNum() ? "Reassigning " : "Assigning ")
|
| + << Func->getTarget()->getRegName(AssignedRegNum, IceType_i32)
|
| + << "(r" << AssignedRegNum << ") to ";
|
| + Var->dump(Func);
|
| Str << "\n";
|
| }
|
| }
|
| - Item.Var->setRegNum(Item.Var->getRegNumTmp());
|
| + Var->setRegNum(AssignedRegNum);
|
| }
|
|
|
| // TODO: Consider running register allocation one more time, with
|
|
|