aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen/SimpleRegisterCoalescing.h
blob: b62c26cf2221d617d5c0c2b20f686f7ea9587fce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//===-- SimpleRegisterCoalescing.h - Register Coalescing --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a simple register copy coalescing phase.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_SIMPLE_REGISTER_COALESCING_H
#define LLVM_CODEGEN_SIMPLE_REGISTER_COALESCING_H

#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/RegisterCoalescer.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/IndexedMap.h"

namespace llvm {

  class LiveVariables;
  class MRegisterInfo;
  class TargetInstrInfo;
  class VirtRegMap;

  class SimpleRegisterCoalescing : public MachineFunctionPass,
                                   public RegisterCoalescer {
    MachineFunction* mf_;
    const TargetMachine* tm_;
    const MRegisterInfo* mri_;
    const TargetInstrInfo* tii_;
    LiveIntervals *li_;
    LiveVariables *lv_;
    
    BitVector allocatableRegs_;
    DenseMap<const TargetRegisterClass*, BitVector> allocatableRCRegs_;

    /// r2rMap_ - Map from register to its representative register.
    ///
    IndexedMap<unsigned> r2rMap_;

    /// r2rRevMap_ - Reverse of r2rRevMap_, i.e. Map from register to all
    /// the registers it represent.
    IndexedMap<std::vector<unsigned> > r2rRevMap_;

    /// JoinedLIs - Keep track which register intervals have been coalesced
    /// with other intervals.
    BitVector JoinedLIs;

    /// SubRegIdxes - Keep track of sub-register and indexes.
    ///
    SmallVector<std::pair<unsigned, unsigned>, 32> SubRegIdxes;

  public:
    static char ID; // Pass identifcation, replacement for typeid
    SimpleRegisterCoalescing() : MachineFunctionPass((intptr_t)&ID) {}

    struct CopyRec {
      MachineInstr *MI;
      unsigned SrcReg, DstReg;
    };
    CopyRec getCopyRec(MachineInstr *MI, unsigned SrcReg, unsigned DstReg) {
      CopyRec R;
      R.MI = MI;
      R.SrcReg = SrcReg;
      R.DstReg = DstReg;
      return R;
    }
    struct InstrSlots {
      enum {
        LOAD  = 0,
        USE   = 1,
        DEF   = 2,
        STORE = 3,
        NUM   = 4
      };
    };
    
    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
    virtual void releaseMemory();

    /// runOnMachineFunction - pass entry point
    virtual bool runOnMachineFunction(MachineFunction&);

    bool coalesceFunction(MachineFunction &mf, RegallocQuery &) {
      // This runs as an independent pass, so don't do anything.
      return(false);
    };

    /// print - Implement the dump method.
    virtual void print(std::ostream &O, const Module* = 0) const;
    void print(std::ostream *O, const Module* M = 0) const {
      if (O) print(*O, M);
    }

  private:      
    /// joinIntervals - join compatible live intervals
    void joinIntervals();

    /// CopyCoalesceInMBB - Coalesce copies in the specified MBB, putting
    /// copies that cannot yet be coalesced into the "TryAgain" list.
    void CopyCoalesceInMBB(MachineBasicBlock *MBB,
                           std::vector<CopyRec> &TryAgain);

    /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
    /// which are the src/dst of the copy instruction CopyMI.  This returns true
    /// if the copy was successfully coalesced away, or if it is never possible
    /// to coalesce these this copy, due to register constraints.  It returns
    /// false if it is not currently possible to coalesce this interval, but
    /// it may be possible if other things get coalesced.
    bool JoinCopy(MachineInstr *CopyMI, unsigned SrcReg, unsigned DstReg);
    
    /// JoinIntervals - Attempt to join these two intervals.  On failure, this
    /// returns false.  Otherwise, if one of the intervals being joined is a
    /// physreg, this method always canonicalizes DestInt to be it.  The output
    /// "SrcInt" will not have been modified, so we can use this information
    /// below to update aliases.
    bool JoinIntervals(LiveInterval &LHS, LiveInterval &RHS, bool &Swapped);
    
    /// SimpleJoin - Attempt to join the specified interval into this one. The
    /// caller of this method must guarantee that the RHS only contains a single
    /// value number and that the RHS is not defined by a copy from this
    /// interval.  This returns false if the intervals are not joinable, or it
    /// joins them and returns true.
    bool SimpleJoin(LiveInterval &LHS, LiveInterval &RHS);
    
    /// Return true if the two specified registers belong to different
    /// register classes.  The registers may be either phys or virt regs.
    bool differingRegisterClasses(unsigned RegA, unsigned RegB) const;


    bool AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB,
                              MachineInstr *CopyMI);

    /// AddSubRegIdxPairs - Recursively mark all the registers represented by the
    /// specified register as sub-registers. The recursion level is expected to be
    /// shallow.
    void AddSubRegIdxPairs(unsigned Reg, unsigned SubIdx);

    /// lastRegisterUse - Returns the last use of the specific register between
    /// cycles Start and End. It also returns the use operand by reference. It
    /// returns NULL if there are no uses.
    MachineInstr *lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,
                                  MachineOperand *&MOU);

    /// findDefOperand - Returns the MachineOperand that is a def of the specific
    /// register. It returns NULL if the def is not found.
    MachineOperand *findDefOperand(MachineInstr *MI, unsigned Reg);

    /// unsetRegisterKill - Unset IsKill property of all uses of the specific
    /// register of the specific instruction.
    void unsetRegisterKill(MachineInstr *MI, unsigned Reg);

    /// unsetRegisterKills - Unset IsKill property of all uses of specific register
    /// between cycles Start and End.
    void unsetRegisterKills(unsigned Start, unsigned End, unsigned Reg);

    /// hasRegisterDef - True if the instruction defines the specific register.
    ///
    bool hasRegisterDef(MachineInstr *MI, unsigned Reg);

    /// rep - returns the representative of this register
    unsigned rep(unsigned Reg) {
      unsigned Rep = r2rMap_[Reg];
      if (Rep)
        return r2rMap_[Reg] = rep(Rep);
      return Reg;
    }

    void printRegName(unsigned reg) const;
  };

} // End llvm namespace

#endif