[llvm-commits] [llvm] r89356 - /llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp

Evan Cheng evan.cheng at apple.com
Thu Nov 19 11:36:55 PST 2009


On Nov 19, 2009, at 7:55 AM, David Greene wrote:

> 
> 
> +    // The queue of recently-used registers.
> +    SmallVector<unsigned, 3> RecentRegs;

Why the odd sized vector?

> +
> +    // Record that we just picked this register.
> +    void recordRecentlyUsed(unsigned reg) {
> +      assert(reg != 0 && "Recently used register is NOREG!");
> +      if (!RecentRegs.empty()) {
> +        std::copy(RecentRegs.begin() + 1, RecentRegs.end(), RecentRegs.begin());
> +        RecentRegs.back() = reg;

This seems extremely slow? Why not pop front and push back? Or just use a fixed size array and keep rotating the begin and end pointers?

Evan

> +      }
> +    }
> +
>   public:
>     virtual const char* getPassName() const {
>       return "Linear Scan Register Allocator";
> @@ -161,6 +194,12 @@
>     /// runOnMachineFunction - register allocate the whole function
>     bool runOnMachineFunction(MachineFunction&);
> 
> +    // Determine if we skip this register due to its being recently used.
> +    bool isRecentlyUsed(unsigned reg) const {
> +      return std::find(RecentRegs.begin(), RecentRegs.end(), reg) !=
> +             RecentRegs.end();
> +    }
> +
>   private:
>     /// linearScan - the linear scan algorithm
>     void linearScan();
> @@ -833,9 +872,15 @@
> 
> namespace {
>   struct WeightCompare {
> +  private:
> +    const RALinScan &Allocator;
> +
> +  public:
> +    WeightCompare(const RALinScan &Alloc) : Allocator(Alloc) {};
> +
>     typedef std::pair<unsigned, float> RegWeightPair;
>     bool operator()(const RegWeightPair &LHS, const RegWeightPair &RHS) const {
> -      return LHS.second < RHS.second;
> +      return LHS.second < RHS.second && !Allocator.isRecentlyUsed(LHS.first);
>     }
>   };
> }
> @@ -1079,7 +1124,8 @@
>            e = RC->allocation_order_end(*mf_); i != e; ++i) {
>       unsigned reg = *i;
>       float regWeight = SpillWeights[reg];
> -      if (minWeight > regWeight)
> +      // Skip recently allocated registers.
> +      if (minWeight > regWeight && !isRecentlyUsed(reg))
>         Found = true;
>       RegsWeights.push_back(std::make_pair(reg, regWeight));
>     }
> @@ -1097,7 +1143,7 @@
>   }
> 
>   // Sort all potential spill candidates by weight.
> -  std::sort(RegsWeights.begin(), RegsWeights.end(), WeightCompare());
> +  std::sort(RegsWeights.begin(), RegsWeights.end(), WeightCompare(*this));
>   minReg = RegsWeights[0].first;
>   minWeight = RegsWeights[0].second;
>   if (minWeight == HUGE_VALF) {
> @@ -1360,7 +1406,8 @@
>     // Ignore "downgraded" registers.
>     if (SkipDGRegs && DowngradedRegs.count(Reg))
>       continue;
> -    if (isRegAvail(Reg)) {
> +    // Skip recently allocated registers.
> +    if (isRegAvail(Reg) && !isRecentlyUsed(Reg)) {
>       FreeReg = Reg;
>       if (FreeReg < inactiveCounts.size())
>         FreeRegInactiveCount = inactiveCounts[FreeReg];
> @@ -1372,9 +1419,12 @@
> 
>   // If there are no free regs, or if this reg has the max inactive count,
>   // return this register.
> -  if (FreeReg == 0 || FreeRegInactiveCount == MaxInactiveCount)
> +  if (FreeReg == 0 || FreeRegInactiveCount == MaxInactiveCount) {
> +    // Remember what register we picked so we can skip it next time.
> +    if (FreeReg != 0) recordRecentlyUsed(FreeReg);
>     return FreeReg;
> - 
> +  }
> +
>   // Continue scanning the registers, looking for the one with the highest
>   // inactive count.  Alkis found that this reduced register pressure very
>   // slightly on X86 (in rev 1.94 of this file), though this should probably be
> @@ -1393,6 +1443,9 @@
>     }
>   }
> 
> +  // Remember what register we picked so we can skip it next time.
> +  recordRecentlyUsed(FreeReg);
> +
>   return FreeReg;
> }
> 
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list