summaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2010-08-10 00:02:26 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2010-08-10 00:02:26 +0000
commitdf30cf9e61e6586b45b74d1312bef1ee758ef94f (patch)
tree3360bcfa05c755a40a8d29fb846c45c498ac260a /include/llvm/CodeGen
parent533a7df02d8493978a76f001f5560e1569f024c0 (diff)
downloadllvm-df30cf9e61e6586b45b74d1312bef1ee758ef94f.tar.gz
llvm-df30cf9e61e6586b45b74d1312bef1ee758ef94f.tar.bz2
llvm-df30cf9e61e6586b45b74d1312bef1ee758ef94f.tar.xz
Transpose the calculation of spill weights such that we are calculating one
register at a time. This turns out to be slightly faster than iterating over instructions, but more importantly, it allows us to compute spill weights for new registers created after the spill weight pass has run. Also compute the allocation hint at the same time as the spill weight. This allows us to use the spill weight as a cost metric for copies, and choose the most profitable hint if there is more than one possibility. The new hints provide a very small (< 0.1%) but universal code size improvement. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110631 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/CodeGen')
-rw-r--r--include/llvm/CodeGen/CalcSpillWeights.h27
-rw-r--r--include/llvm/CodeGen/LiveInterval.h9
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h6
3 files changed, 41 insertions, 1 deletions
diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h
index e5273c5497..99703a1c10 100644
--- a/include/llvm/CodeGen/CalcSpillWeights.h
+++ b/include/llvm/CodeGen/CalcSpillWeights.h
@@ -12,10 +12,35 @@
#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/ADT/DenseMap.h"
namespace llvm {
class LiveInterval;
+ class LiveIntervals;
+ class MachineLoopInfo;
+
+ /// VirtRegAuxInfo - Calculate auxiliary information for a virtual
+ /// register such as its spill weight and allocation hint.
+ class VirtRegAuxInfo {
+ MachineFunction &mf_;
+ LiveIntervals &lis_;
+ MachineLoopInfo &loops_;
+ DenseMap<unsigned, float> hint_;
+ public:
+ VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis,
+ MachineLoopInfo &loops) :
+ mf_(mf), lis_(lis), loops_(loops) {}
+
+ /// CalculateRegClass - recompute the register class for li from its uses.
+ /// Since the register class can affect the allocation hint, this function
+ /// should be called before CalculateWeightAndHint if both are called.
+ void CalculateRegClass(LiveInterval &li);
+
+ /// CalculateWeightAndHint - (re)compute li's spill weight and allocation
+ /// hint.
+ void CalculateWeightAndHint(LiveInterval &li);
+ };
/// CalculateSpillWeights - Compute spill weights for all virtual register
/// live intervals.
@@ -27,7 +52,7 @@ namespace llvm {
virtual void getAnalysisUsage(AnalysisUsage &au) const;
- virtual bool runOnMachineFunction(MachineFunction &fn);
+ virtual bool runOnMachineFunction(MachineFunction &fn);
private:
/// Returns true if the given live interval is zero length.
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 0c92b85340..f0e068b8e9 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -520,6 +520,15 @@ namespace llvm {
///
unsigned getSize() const;
+ /// Returns true if the live interval is zero length, i.e. no live ranges
+ /// span instructions. It doesn't pay to spill such an interval.
+ bool isZeroLength() const {
+ for (const_iterator i = begin(), e = end(); i != e; ++i)
+ if (i->end.getPrevIndex() > i->start)
+ return false;
+ return true;
+ }
+
/// isSpillable - Can this interval be spilled?
bool isSpillable() const {
return weight != HUGE_VALF;
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index b154bf1b05..04477acfaa 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -105,6 +105,12 @@ namespace llvm {
return r2iMap_.count(reg);
}
+ /// isAllocatable - is the physical register reg allocatable in the current
+ /// function?
+ bool isAllocatable(unsigned reg) const {
+ return allocatableRegs_.test(reg);
+ }
+
/// getScaledIntervalSize - get the size of an interval in "units,"
/// where every function is composed of one thousand units. This
/// measure scales properly with empty index slots in the function.