[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