Weight variables for register allocation by their number of uses.

Count the number of instructions that use a variable following the heuristic
that more uses implies higher register priority. This is currently very simple
but is precursor work for weighting variables by loop nest depth.

BUG=
R=jvoung@chromium.org

Review URL: https://codereview.chromium.org/1312433004.
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index cf7be3b..5797fdc 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -765,7 +765,7 @@
         Str << getVMetadata()->isMultiBlock(Var);
       else
         Str << "?";
-      Str << " weight=" << Var->getWeight() << " ";
+      Str << " weight=" << Var->getWeight(this) << " ";
       Var->dump(this);
       Str << " LIVE=" << Var->getLiveRange() << "\n";
     }
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
index 6926722..f0fae92 100644
--- a/src/IceCfgNode.cpp
+++ b/src/IceCfgNode.cpp
@@ -700,15 +700,15 @@
 
     Variable *Var = Liveness->getVariable(i, this);
     if (LB > LE) {
-      Var->addLiveRange(FirstInstNum, LE, 1);
-      Var->addLiveRange(LB, LastInstNum + 1, 1);
+      Var->addLiveRange(FirstInstNum, LE);
+      Var->addLiveRange(LB, LastInstNum + 1);
       // Assert that Var is a global variable by checking that its
       // liveness index is less than the number of globals.  This
       // ensures that the LiveInAndOut[] access is valid.
       assert(i < Liveness->getNumGlobalVars());
       LiveInAndOut[i] = false;
     } else {
-      Var->addLiveRange(LB, LE, 1);
+      Var->addLiveRange(LB, LE);
     }
     if (i == i1)
       ++IBB;
@@ -720,7 +720,7 @@
        i = LiveInAndOut.find_next(i)) {
     Variable *Var = Liveness->getVariable(i, this);
     if (Liveness->getRangeMask(Var->getIndex()))
-      Var->addLiveRange(FirstInstNum, LastInstNum + 1, 1);
+      Var->addLiveRange(FirstInstNum, LastInstNum + 1);
   }
 }
 
diff --git a/src/IceLiveness.cpp b/src/IceLiveness.cpp
index 35e12b7..15877b2 100644
--- a/src/IceLiveness.cpp
+++ b/src/IceLiveness.cpp
@@ -102,7 +102,7 @@
     Variable *Var = *I;
     SizeT VarIndex = Var->getIndex();
     if (Var->getIgnoreLiveness() ||
-        (!IsFullInit && !Var->hasReg() && !Var->getWeight().isInf()))
+        (!IsFullInit && !Var->hasReg() && !Var->mustHaveReg()))
       RangeMask[VarIndex] = false;
   }
 
diff --git a/src/IceOperand.cpp b/src/IceOperand.cpp
index e46fac0..32316ba 100644
--- a/src/IceOperand.cpp
+++ b/src/IceOperand.cpp
@@ -145,9 +145,21 @@
   return V;
 }
 
+RegWeight Variable::getWeight(const Cfg *Func) const {
+  VariablesMetadata *VMetadata = Func->getVMetadata();
+  return RegWeight(mustHaveReg()
+                       ? RegWeight::Inf
+                       : mustNotHaveReg() ? RegWeight::Zero
+                                          : VMetadata->getUseWeight(this));
+}
+
 void VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr,
                                CfgNode *Node, bool IsImplicit) {
   (void)TrackingKind;
+
+  // TODO(ascull): get the loop nest depth from CfgNode
+  UseWeight += 1;
+
   if (MultiBlock == MBS_MultiBlock)
     return;
   // TODO(stichnot): If the use occurs as a source operand in the
@@ -383,6 +395,13 @@
   return Metadata[VarNum].getNode();
 }
 
+uint32_t VariablesMetadata::getUseWeight(const Variable *Var) const {
+  if (!isTracked(Var))
+    return 1; // conservative answer
+  SizeT VarNum = Var->getIndex();
+  return Metadata[VarNum].getUseWeight();
+}
+
 const InstDefList VariablesMetadata::NoDefinitions;
 
 // ======================== dump routines ======================== //
@@ -466,7 +485,6 @@
 void LiveRange::dump(Ostream &Str) const {
   if (!BuildDefs::dump())
     return;
-  Str << "(weight=" << Weight << ") ";
   bool First = true;
   for (const RangeElementType &I : Range) {
     if (!First)
diff --git a/src/IceOperand.h b/src/IceOperand.h
index bcb38d0..946f47d 100644
--- a/src/IceOperand.h
+++ b/src/IceOperand.h
@@ -332,8 +332,6 @@
   void addWeight(const RegWeight &Other) { addWeight(Other.Weight); }
   void setWeight(uint32_t Val) { Weight = Val; }
   uint32_t getWeight() const { return Weight; }
-  bool isInf() const { return Weight == Inf; }
-  bool isZero() const { return Weight == Zero; }
 
 private:
   uint32_t Weight = 0;
@@ -346,9 +344,7 @@
 /// LiveRange is a set of instruction number intervals representing
 /// a variable's live range.  Generally there is one interval per basic
 /// block where the variable is live, but adjacent intervals get
-/// coalesced into a single interval.  LiveRange also includes a
-/// weight, in case e.g. we want a live range to have higher weight
-/// inside a loop.
+/// coalesced into a single interval.
 class LiveRange {
 public:
   LiveRange() = default;
@@ -364,7 +360,6 @@
 
   void reset() {
     Range.clear();
-    Weight.setWeight(0);
     untrim();
   }
   void addSegment(InstNumberT Start, InstNumberT End);
@@ -384,9 +379,6 @@
   void untrim() { TrimmedBegin = Range.begin(); }
   void trim(InstNumberT Lower);
 
-  RegWeight getWeight() const { return Weight; }
-  void setWeight(const RegWeight &NewWeight) { Weight = NewWeight; }
-  void addWeight(uint32_t Delta) { Weight.addWeight(Delta); }
   void dump(Ostream &Str) const;
 
 private:
@@ -395,7 +387,6 @@
   typedef std::vector<RangeElementType, CfgLocalAllocator<RangeElementType>>
       RangeType;
   RangeType Range;
-  RegWeight Weight = RegWeight(0);
   /// TrimmedBegin is an optimization for the overlaps() computation.
   /// Since the linear-scan algorithm always calls it as overlaps(Cur)
   /// and Cur advances monotonically according to live range start, we
@@ -417,6 +408,12 @@
   Variable(const Variable &) = delete;
   Variable &operator=(const Variable &) = delete;
 
+  enum RegRequirement {
+    RR_MayHaveRegister,
+    RR_MustHaveRegister,
+    RR_MustNotHaveRegister,
+  };
+
 public:
   static Variable *create(Cfg *Func, Type Ty, SizeT Index) {
     return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index);
@@ -454,25 +451,22 @@
   int32_t getRegNumTmp() const { return RegNumTmp; }
   void setRegNumTmp(int32_t NewRegNum) { RegNumTmp = NewRegNum; }
 
-  RegWeight getWeight() const { return Weight; }
-  void setWeight(uint32_t NewWeight) { Weight = RegWeight(NewWeight); }
-  void setWeightInfinite() { setWeight(RegWeight::Inf); }
+  RegWeight getWeight(const Cfg *Func) const;
+
+  void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; }
+  bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; }
+  void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; }
+  bool mustNotHaveReg() const {
+    return RegRequirement == RR_MustNotHaveRegister;
+  }
 
   LiveRange &getLiveRange() { return Live; }
   const LiveRange &getLiveRange() const { return Live; }
   void setLiveRange(const LiveRange &Range) { Live = Range; }
   void resetLiveRange() { Live.reset(); }
-  void addLiveRange(InstNumberT Start, InstNumberT End, uint32_t WeightDelta) {
+  void addLiveRange(InstNumberT Start, InstNumberT End) {
     assert(!getIgnoreLiveness());
-    assert(WeightDelta != RegWeight::Inf);
     Live.addSegment(Start, End);
-    if (Weight.isInf())
-      Live.setWeight(RegWeight(RegWeight::Inf));
-    else
-      Live.addWeight(WeightDelta * Weight.getWeight());
-  }
-  void setLiveRangeInfiniteWeight() {
-    Live.setWeight(RegWeight(RegWeight::Inf));
   }
   void trimLiveRange(InstNumberT Start) { Live.trim(Start); }
   void untrimLiveRange() { Live.untrim(); }
@@ -500,7 +494,7 @@
   /// Used primarily for syntactic correctness of textual assembly
   /// emission.  Note that only basic information is copied, in
   /// particular not IsArgument, IsImplicitArgument, IgnoreLiveness,
-  /// RegNumTmp, Weight, Live, LoVar, HiVar, VarsReal.
+  /// RegNumTmp, Live, LoVar, HiVar, VarsReal.
   Variable *asType(Type Ty);
 
   void emit(const Cfg *Func) const override;
@@ -540,7 +534,7 @@
   int32_t RegNum = NoRegister;
   /// RegNumTmp is the tentative assignment during register allocation.
   int32_t RegNumTmp = NoRegister;
-  RegWeight Weight = RegWeight(1); // Register allocation priority
+  RegRequirement RegRequirement = RR_MayHaveRegister;
   LiveRange Live;
   // LoVar and HiVar are needed for lowering from 64 to 32 bits.  When
   // lowering from I64 to I32 on a 32-bit architecture, we split the
@@ -585,6 +579,7 @@
   const Inst *getSingleDefinition() const;
   const InstDefList &getLatterDefinitions() const { return Definitions; }
   CfgNode *getNode() const { return SingleUseNode; }
+  uint32_t getUseWeight() const { return UseWeight; }
   void markUse(MetadataKind TrackingKind, const Inst *Instr, CfgNode *Node,
                bool IsImplicit);
   void markDef(MetadataKind TrackingKind, const Inst *Instr, CfgNode *Node);
@@ -599,10 +594,11 @@
   InstDefList Definitions; /// Only used if Kind==VMK_All
   const Inst *FirstOrSingleDefinition =
       nullptr; /// Is a copy of Definitions[0] if Kind==VMK_All
+  uint32_t UseWeight = 0;
 };
 
-/// VariablesMetadata analyzes and summarizes the metadata for the
-/// complete set of Variables.
+/// VariablesMetadata analyzes and summarizes the metadata for the complete set
+/// of Variables.
 class VariablesMetadata {
   VariablesMetadata() = delete;
   VariablesMetadata(const VariablesMetadata &) = delete;
@@ -616,29 +612,27 @@
   /// Add a single node.  This is called by init(), and can be called
   /// incrementally from elsewhere, e.g. after edge-splitting.
   void addNode(CfgNode *Node);
-  /// Returns whether the given Variable is tracked in this object.  It
-  /// should only return false if changes were made to the CFG after
-  /// running init(), in which case the state is stale and the results
-  /// shouldn't be trusted (but it may be OK e.g. for dumping).
+  /// Returns whether the given Variable is tracked in this object.  It should
+  /// only return false if changes were made to the CFG after running init(), in
+  /// which case the state is stale and the results shouldn't be trusted (but it
+  /// may be OK e.g. for dumping).
   bool isTracked(const Variable *Var) const {
     return Var->getIndex() < Metadata.size();
   }
 
   /// Returns whether the given Variable has multiple definitions.
   bool isMultiDef(const Variable *Var) const;
-  /// Returns the first definition instruction of the given Variable.
-  /// This is only valid for variables whose definitions are all within
-  /// the same block, e.g. T after the lowered sequence "T=B; T+=C;
-  /// A=T", for which getFirstDefinition(T) would return the "T=B"
-  /// instruction.  For variables with definitions span multiple
-  /// blocks, nullptr is returned.
+  /// Returns the first definition instruction of the given Variable.  This is
+  /// only valid for variables whose definitions are all within the same block,
+  /// e.g. T after the lowered sequence "T=B; T+=C; A=T", for which
+  /// getFirstDefinition(T) would return the "T=B" instruction.  For variables
+  /// with definitions span multiple blocks, nullptr is returned.
   const Inst *getFirstDefinition(const Variable *Var) const;
   /// Returns the definition instruction of the given Variable, when
   /// the variable has exactly one definition.  Otherwise, nullptr is
   /// returned.
   const Inst *getSingleDefinition(const Variable *Var) const;
-  /// Returns the list of all definition instructions of the given
-  /// Variable.
+  /// Returns the list of all definition instructions of the given Variable.
   const InstDefList &getLatterDefinitions(const Variable *Var) const;
 
   /// Returns whether the given Variable is live across multiple
@@ -653,6 +647,10 @@
   /// isMultiBlock() returns false.  Otherwise, nullptr is returned.
   CfgNode *getLocalUseNode(const Variable *Var) const;
 
+  /// Returns the total use weight computed as the sum of uses multiplied by a
+  /// loop nest depth factor for each use.
+  uint32_t getUseWeight(const Variable *Var) const;
+
 private:
   const Cfg *Func;
   MetadataKind Kind;
diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp
index 0c15df7..2c6d742 100644
--- a/src/IceRegAlloc.cpp
+++ b/src/IceRegAlloc.cpp
@@ -99,7 +99,7 @@
   for (Variable *Var : Vars) {
     // Explicitly don't consider zero-weight variables, which are meant to be
     // spill slots.
-    if (Var->getWeight().isZero())
+    if (Var->mustNotHaveReg())
       continue;
     // Don't bother if the variable has a null live range, which means it was
     // never referenced.
@@ -109,7 +109,7 @@
     Unhandled.push_back(Var);
     if (Var->hasReg()) {
       Var->setRegNumTmp(Var->getRegNum());
-      Var->setLiveRangeInfiniteWeight();
+      Var->setMustHaveReg();
       UnhandledPrecolored.push_back(Var);
     }
   }
@@ -173,7 +173,7 @@
         continue;
       if (const Variable *Var = Inst.getDest()) {
         if (!Var->getIgnoreLiveness() &&
-            (Var->hasReg() || Var->getWeight().isInf())) {
+            (Var->hasReg() || Var->mustHaveReg())) {
           if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) {
             LRBegin[Var->getIndex()] = Inst.getNumber();
             ++NumVars;
@@ -187,7 +187,7 @@
           const Variable *Var = Src->getVar(J);
           if (Var->getIgnoreLiveness())
             continue;
-          if (Var->hasReg() || Var->getWeight().isInf())
+          if (Var->hasReg() || Var->mustHaveReg())
             LREnd[Var->getIndex()] = Inst.getNumber();
         }
       }
@@ -202,12 +202,11 @@
       assert(LREnd[i] != Inst::NumberSentinel);
       Unhandled.push_back(Var);
       Var->resetLiveRange();
-      constexpr uint32_t WeightDelta = 1;
-      Var->addLiveRange(LRBegin[i], LREnd[i], WeightDelta);
+      Var->addLiveRange(LRBegin[i], LREnd[i]);
       Var->untrimLiveRange();
       if (Var->hasReg()) {
         Var->setRegNumTmp(Var->getRegNum());
-        Var->setLiveRangeInfiniteWeight();
+        Var->setMustHaveReg();
         UnhandledPrecolored.push_back(Var);
       }
       --NumVars;
@@ -519,14 +518,14 @@
     assert(Item->rangeOverlaps(Iter.Cur));
     int32_t RegNum = Item->getRegNumTmp();
     assert(Item->hasRegTmp());
-    Iter.Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
+    Iter.Weights[RegNum].addWeight(Item->getWeight(Func));
   }
   // Same as above, but check Inactive ranges instead of Active.
   for (const Variable *Item : Inactive) {
     int32_t RegNum = Item->getRegNumTmp();
     assert(Item->hasRegTmp());
     if (Item->rangeOverlaps(Iter.Cur))
-      Iter.Weights[RegNum].addWeight(Item->getLiveRange().getWeight());
+      Iter.Weights[RegNum].addWeight(Item->getWeight(Func));
   }
 
   // All the weights are now calculated. Find the register with smallest
@@ -539,11 +538,11 @@
       MinWeightIndex = i;
   }
 
-  if (Iter.Cur->getLiveRange().getWeight() <= Iter.Weights[MinWeightIndex]) {
+  if (Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) {
     // Cur doesn't have priority over any other live ranges, so don't allocate
     // any register to it, and move it to the Handled state.
     Handled.push_back(Iter.Cur);
-    if (Iter.Cur->getLiveRange().getWeight().isInf()) {
+    if (Iter.Cur->mustHaveReg()) {
       if (Kind == RAK_Phi)
         addSpillFill(Iter);
       else
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index c3d05a2..9b10eff 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -410,7 +410,7 @@
     Str << getRegName(Var->getRegNum(), Var->getType());
     return;
   }
-  if (Var->getWeight().isInf()) {
+  if (Var->mustHaveReg()) {
     llvm::report_fatal_error(
         "Infinite-weight Variable has no register assigned");
   }
@@ -907,7 +907,7 @@
   else
     _add(ScratchReg, OrigBaseReg, OffsetVal);
   StackVariable *NewVar = Func->makeVariable<StackVariable>(stackSlotType());
-  NewVar->setWeight(RegWeight::Zero);
+  NewVar->setMustNotHaveReg();
   NewVar->setBaseRegNum(ScratchReg->getRegNum());
   constexpr int32_t NewOffset = 0;
   NewVar->setStackOffset(NewOffset);
@@ -984,7 +984,7 @@
             if (isLegalVariableStackOffset(OffsetDiff)) {
               StackVariable *NewDest =
                   Func->makeVariable<StackVariable>(stackSlotType());
-              NewDest->setWeight(RegWeight::Zero);
+              NewDest->setMustNotHaveReg();
               NewDest->setBaseRegNum(NewBaseReg->getBaseRegNum());
               NewDest->setStackOffset(OffsetDiff);
               Variable *NewDestVar = NewDest;
@@ -1014,7 +1014,7 @@
             if (isLegalVariableStackOffset(OffsetDiff)) {
               StackVariable *NewVar =
                   Func->makeVariable<StackVariable>(stackSlotType());
-              NewVar->setWeight(RegWeight::Zero);
+              NewVar->setMustNotHaveReg();
               NewVar->setBaseRegNum(NewBaseReg->getBaseRegNum());
               NewVar->setStackOffset(OffsetDiff);
               _mov(Dest, NewVar);
@@ -2834,7 +2834,7 @@
     // Check if the variable is guaranteed a physical register.  This
     // can happen either when the variable is pre-colored or when it is
     // assigned infinite weight.
-    bool MustHaveRegister = (Var->hasReg() || Var->getWeight().isInf());
+    bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
     // We need a new physical register for the operand if:
     //   Mem is not allowed and Var isn't guaranteed a physical
     //   register, or
@@ -2899,7 +2899,7 @@
   assert(Type != IceType_i64);
   Variable *Reg = Func->makeVariable(Type);
   if (RegNum == Variable::NoRegister)
-    Reg->setWeightInfinite();
+    Reg->setMustHaveReg();
   else
     Reg->setRegNum(RegNum);
   return Reg;
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index e9f9989..a4ceac0 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -429,7 +429,7 @@
       [&VariablesLinkedToSpillSlots](Variable *Var) {
         if (auto *SpillVar =
                 llvm::dyn_cast<typename Traits::SpillVariable>(Var)) {
-          assert(Var->getWeight().isZero());
+          assert(Var->mustNotHaveReg());
           if (SpillVar->getLinkedTo() && !SpillVar->getLinkedTo()->hasReg()) {
             VariablesLinkedToSpillSlots.push_back(Var);
             return true;
diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp
index 76fffa0..4bb177e 100644
--- a/src/IceTargetLoweringX8664.cpp
+++ b/src/IceTargetLoweringX8664.cpp
@@ -449,7 +449,7 @@
       [&VariablesLinkedToSpillSlots](Variable *Var) {
         if (auto *SpillVar =
                 llvm::dyn_cast<typename Traits::SpillVariable>(Var)) {
-          assert(Var->getWeight().isZero());
+          assert(Var->mustNotHaveReg());
           if (SpillVar->getLinkedTo() && !SpillVar->getLinkedTo()->hasReg()) {
             VariablesLinkedToSpillSlots.push_back(Var);
             return true;
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index a0b5b6c..afbbaf3 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -585,7 +585,7 @@
               Str << "\n";
             }
             Variable *Beacon = Func->makeVariable(IceType_i32);
-            Beacon->setWeight(0);
+            Beacon->setMustNotHaveReg();
             Store->setRmwBeacon(Beacon);
             InstFakeDef *BeaconDef = InstFakeDef::create(Func, Beacon);
             Node->getInsts().insert(I3, BeaconDef);
@@ -763,7 +763,7 @@
     Str << "%" << getRegName(Var->getRegNum(), Var->getType());
     return;
   }
-  if (Var->getWeight().isInf()) {
+  if (Var->mustHaveReg()) {
     llvm_unreachable("Infinite-weight Variable has no register assigned");
   }
   int32_t Offset = Var->getStackOffset();
@@ -784,7 +784,7 @@
 TargetX86Base<Machine>::stackVarToAsmOperand(const Variable *Var) const {
   if (Var->hasReg())
     llvm_unreachable("Stack Variable has a register assigned");
-  if (Var->getWeight().isInf()) {
+  if (Var->mustHaveReg()) {
     llvm_unreachable("Infinite-weight Variable has no register assigned");
   }
   int32_t Offset = Var->getStackOffset();
@@ -2054,7 +2054,7 @@
         T_1 = makeReg(IceType_i32);
       }
       // cvt() requires its integer argument to be a GPR.
-      T_1->setWeightInfinite();
+      T_1->setMustHaveReg();
       Variable *T_2 = makeReg(Dest->getType());
       _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si);
       _mov(T_2, T_1); // T_1 and T_2 may have different integer types
@@ -2105,7 +2105,7 @@
         assert(Dest->getType() != IceType_i32);
         T_1 = makeReg(IceType_i32);
       }
-      T_1->setWeightInfinite();
+      T_1->setMustHaveReg();
       Variable *T_2 = makeReg(Dest->getType());
       _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si);
       _mov(T_2, T_1); // T_1 and T_2 may have different integer types
@@ -2147,7 +2147,7 @@
         assert(Src0RM->getType() != IceType_i64);
         T_1 = makeReg(IceType_i32);
       }
-      T_1->setWeightInfinite();
+      T_1->setMustHaveReg();
       Variable *T_2 = makeReg(Dest->getType());
       if (Src0RM->getType() == T_1->getType())
         _mov(T_1, Src0RM);
@@ -2196,7 +2196,7 @@
         assert(Traits::Is64Bit || Src0RM->getType() != IceType_i32);
         T_1 = makeReg(IceType_i32);
       }
-      T_1->setWeightInfinite();
+      T_1->setMustHaveReg();
       Variable *T_2 = makeReg(Dest->getType());
       if (Src0RM->getType() == T_1->getType())
         _mov(T_1, Src0RM);
@@ -2248,7 +2248,7 @@
           Func->makeVariable<typename Traits::SpillVariable>(SrcType);
       SpillVar->setLinkedTo(Dest);
       Variable *Spill = SpillVar;
-      Spill->setWeight(RegWeight::Zero);
+      Spill->setMustNotHaveReg();
       _mov(T, Src0RM);
       _mov(Spill, T);
       _mov(Dest, Spill);
@@ -2276,7 +2276,7 @@
               Func->makeVariable<typename Traits::SpillVariable>(IceType_f64);
           SpillVar->setLinkedTo(Src0Var);
           Variable *Spill = SpillVar;
-          Spill->setWeight(RegWeight::Zero);
+          Spill->setMustNotHaveReg();
           _movq(Spill, Src0RM);
           SpillLo = Traits::VariableSplit::create(Func, Spill,
                                                   Traits::VariableSplit::Low);
@@ -2305,7 +2305,7 @@
         Variable *T = makeReg(IceType_f64);
         // Movd requires its fp argument (in this case, the bitcast destination)
         // to be an xmm register.
-        T->setWeightInfinite();
+        T->setMustHaveReg();
         _movd(T, Src0RM);
         _mov(Dest, T);
       } else {
@@ -2327,7 +2327,7 @@
             Func->makeVariable<typename Traits::SpillVariable>(IceType_f64);
         SpillVar->setLinkedTo(Dest);
         Variable *Spill = SpillVar;
-        Spill->setWeight(RegWeight::Zero);
+        Spill->setMustNotHaveReg();
 
         Variable *T_Lo = nullptr, *T_Hi = nullptr;
         typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create(
@@ -2429,7 +2429,7 @@
     // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
     // support for legalizing to mem is implemented.
     Variable *Slot = Func->makeVariable(Ty);
-    Slot->setWeight(RegWeight::Zero);
+    Slot->setMustNotHaveReg();
     _movp(Slot, legalizeToReg(SourceVectNotLegalized));
 
     // Compute the location of the element in memory.
@@ -2838,7 +2838,7 @@
     // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when
     // support for legalizing to mem is implemented.
     Variable *Slot = Func->makeVariable(Ty);
-    Slot->setWeight(RegWeight::Zero);
+    Slot->setMustNotHaveReg();
     _movp(Slot, legalizeToReg(SourceVectNotLegalized));
 
     // Compute the location of the position to insert in memory.
@@ -4848,7 +4848,7 @@
 TargetX86Base<Machine>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
                                                      uint32_t Offset) {
   // Ensure that Loc is a stack slot.
-  assert(Slot->getWeight().isZero());
+  assert(Slot->mustNotHaveReg());
   assert(Slot->getRegNum() == Variable::NoRegister);
   // Compute the location of Loc in memory.
   // TODO(wala,stichnot): lea should not be required.  The address of
@@ -4932,7 +4932,7 @@
     if (Traits::Is64Bit) {
       if (llvm::isa<ConstantInteger64>(Const)) {
         Variable *V = copyToReg(Const, RegNum);
-        V->setWeightInfinite();
+        V->setMustHaveReg();
         return V;
       }
     }
@@ -4973,7 +4973,7 @@
     // Check if the variable is guaranteed a physical register.  This
     // can happen either when the variable is pre-colored or when it is
     // assigned infinite weight.
-    bool MustHaveRegister = (Var->hasReg() || Var->getWeight().isInf());
+    bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
     // We need a new physical register for the operand if:
     //   Mem is not allowed and Var isn't guaranteed a physical
     //   register, or
@@ -5077,7 +5077,7 @@
   assert(Traits::Is64Bit || Type != IceType_i64);
   Variable *Reg = Func->makeVariable(Type);
   if (RegNum == Variable::NoRegister)
-    Reg->setWeightInfinite();
+    Reg->setMustHaveReg();
   else
     Reg->setRegNum(RegNum);
   return Reg;
diff --git a/tests_lit/assembler/x86/jump_encodings.ll b/tests_lit/assembler/x86/jump_encodings.ll
index d94be0a..5a12527 100644
--- a/tests_lit/assembler/x86/jump_encodings.ll
+++ b/tests_lit/assembler/x86/jump_encodings.ll
@@ -169,13 +169,13 @@
   br i1 %cmp, label %next, label %next2
 }
 ; CHECK-LABEL: test_local_forward_then_back
-; CHECK:      14: {{.*}} mov DWORD PTR
-; CHECK-NEXT: 16: {{.*}} mfence
-; CHECK-NEXT: 19: {{.*}} mov DWORD PTR {{.*}},0x1
-; CHECK-NEXT: 20: {{.*}} cmp
-; CHECK-NEXT: 23: {{.*}} jb 33
-; CHECK:      37: {{.*}} jne 14
-; CHECK:      39: {{.*}} jmp 19
+; CHECK:      {{.*}} mov DWORD PTR
+; CHECK-NEXT: {{.*}} mfence
+; CHECK-NEXT: 16: {{.*}} mov {{.*}},0x1
+; CHECK-NEXT: {{.*}} cmp
+; CHECK-NEXT: {{.*}} jb
+; CHECK:      {{.*}} jne
+; CHECK:      {{.*}} jmp 16
 
 
 ; Test that backward local branches also work and are small.
diff --git a/tests_lit/assembler/x86/opcode_register_encodings.ll b/tests_lit/assembler/x86/opcode_register_encodings.ll
index a232175..9685182 100644
--- a/tests_lit/assembler/x86/opcode_register_encodings.ll
+++ b/tests_lit/assembler/x86/opcode_register_encodings.ll
@@ -33,14 +33,14 @@
   %res = select <8 x i1> %cond, <8 x i16> %res_acc1_3, <8 x i16> %res_acc2_4
   ret <8 x i16> %res
 ; CHECK-LABEL: test_mul_v8i16_more_regs
-; CHECK-DAG: 66 0f d5 c2 pmullw xmm0,xmm2
-; CHECK-DAG: 66 0f d5 c3 pmullw xmm0,xmm3
-; CHECK-DAG: 66 0f d5 c4 pmullw xmm0,xmm4
-; CHECK-DAG: 66 0f d5 c5 pmullw xmm0,xmm5
-; CHECK-DAG: 66 0f d5 c6 pmullw xmm0,xmm6
-; CHECK-DAG: 66 0f d5 c7 pmullw xmm0,xmm7
-; CHECK-DAG: 66 0f d5 44 24 70 pmullw xmm0,XMMWORD PTR [esp
-; CHECK-DAG: 66 0f d5 8c 24 80 00 00 00 pmullw xmm1,XMMWORD PTR [esp
+; CHECK-DAG: pmullw xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmullw xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmullw xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmullw xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmullw xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmullw xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmullw xmm0,XMMWORD PTR [esp
+; CHECK-DAG: pmullw xmm1,XMMWORD PTR [esp
 }
 
 define <4 x i32> @test_mul_v4i32(<4 x i32> %arg0, <4 x i32> %arg1) {
@@ -70,14 +70,14 @@
   %res = select <4 x i1> %cond, <4 x i32> %res_acc1_3, <4 x i32> %res_acc2_4
   ret <4 x i32> %res
 ; CHECK-LABEL: test_mul_v4i32_more_regs
-; CHECK-DAG: 66 0f 38 40 c2 pmulld xmm0,xmm2
-; CHECK-DAG: 66 0f 38 40 c3 pmulld xmm0,xmm3
-; CHECK-DAG: 66 0f 38 40 c4 pmulld xmm0,xmm4
-; CHECK-DAG: 66 0f 38 40 c5 pmulld xmm0,xmm5
-; CHECK-DAG: 66 0f 38 40 c6 pmulld xmm0,xmm6
-; CHECK-DAG: 66 0f 38 40 c7 pmulld xmm0,xmm7
-; CHECK-DAG: 66 0f 38 40 44 24 70 pmulld xmm0,XMMWORD PTR [esp
-; CHECK-DAG: 66 0f 38 40 8c 24 80 00 00 00 pmulld xmm1,XMMWORD PTR [esp
+; CHECK-DAG: pmulld xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmulld xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmulld xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmulld xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmulld xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmulld xmm0,{{xmm[0-7]|xmmword ptr\[esp}}
+; CHECK-DAG: pmulld xmm0,XMMWORD PTR [esp
+; CHECK-DAG: pmulld xmm1,XMMWORD PTR [esp
 }
 
 ; Test movq, which is used by atomic stores.
@@ -192,7 +192,7 @@
 ; CHECK-LABEL: test_pinsrb
 ; CHECK-DAG: 66 0f 3a 20 c{{.*}} 01 pinsrb xmm0,e{{.*}}
 ; CHECK-DAG: 66 0f 3a 20 c{{.*}} 07 pinsrb xmm0,e{{.*}}
-; CHECK-DAG: 66 0f 3a 20 {{.*}} 0f pinsrb xmm0,BYTE PTR {{.*}}
+; CHECK-DAG: 66 0f 3a 20 c{{.*}} 0f pinsrb xmm0,e{{.*}}
 
 define <8 x i16> @test_pinsrw(<8 x i16> %vec, i32 %elt1_w, i32 %elt2_w, i32 %elt3_w, i32 %elt4_w) {
 entry:
diff --git a/tests_lit/llvm2ice_tests/nacl-atomic-cmpxchg-optimization.ll b/tests_lit/llvm2ice_tests/nacl-atomic-cmpxchg-optimization.ll
index ee81cce..7646c10 100644
--- a/tests_lit/llvm2ice_tests/nacl-atomic-cmpxchg-optimization.ll
+++ b/tests_lit/llvm2ice_tests/nacl-atomic-cmpxchg-optimization.ll
@@ -128,6 +128,5 @@
 }
 ; O2-LABEL: test_atomic_cmpxchg_no_opt2
 ; O2: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}}
-; O2: mov {{.*}}
 ; O2: cmp
 ; O2: sete