2017-09-13 21:15:20 +00:00
|
|
|
//===- llvm/CodeGen/VirtRegMap.h - Virtual Register Map ---------*- C++ -*-===//
|
2004-02-23 23:08:11 +00:00
|
|
|
//
|
2019-01-19 08:50:56 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2004-02-23 23:08:11 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2004-09-30 01:54:45 +00:00
|
|
|
// This file implements a virtual register map. This maps virtual registers to
|
|
|
|
// physical registers and virtual registers to stack slots. It is created and
|
|
|
|
// updated by a register allocator and then used by a machine code rewriter that
|
|
|
|
// adds spill code and rewrites virtual into physical register references.
|
2004-02-23 23:08:11 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_CODEGEN_VIRTREGMAP_H
|
|
|
|
#define LLVM_CODEGEN_VIRTREGMAP_H
|
|
|
|
|
2012-12-03 17:02:12 +00:00
|
|
|
#include "llvm/ADT/IndexedMap.h"
|
2009-03-13 05:55:11 +00:00
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
2017-11-17 01:07:10 +00:00
|
|
|
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
2017-09-13 21:15:20 +00:00
|
|
|
#include "llvm/MC/MCRegisterInfo.h"
|
|
|
|
#include "llvm/Pass.h"
|
|
|
|
#include <cassert>
|
2004-02-23 23:08:11 +00:00
|
|
|
|
|
|
|
namespace llvm {
|
2017-09-13 21:15:20 +00:00
|
|
|
|
|
|
|
class MachineFunction;
|
|
|
|
class MachineRegisterInfo;
|
|
|
|
class raw_ostream;
|
|
|
|
class TargetInstrInfo;
|
2004-09-30 01:54:45 +00:00
|
|
|
|
2009-03-13 05:55:11 +00:00
|
|
|
class VirtRegMap : public MachineFunctionPass {
|
2004-09-30 01:54:45 +00:00
|
|
|
public:
|
2007-03-20 08:13:50 +00:00
|
|
|
enum {
|
|
|
|
NO_PHYS_REG = 0,
|
2007-04-04 07:40:01 +00:00
|
|
|
NO_STACK_SLOT = (1L << 30)-1,
|
|
|
|
MAX_STACK_SLOT = (1L << 18)-1
|
2007-03-20 08:13:50 +00:00
|
|
|
};
|
|
|
|
|
2004-09-30 01:54:45 +00:00
|
|
|
private:
|
2009-06-14 20:22:55 +00:00
|
|
|
MachineRegisterInfo *MRI;
|
2009-03-13 05:55:11 +00:00
|
|
|
const TargetInstrInfo *TII;
|
2009-05-04 03:30:11 +00:00
|
|
|
const TargetRegisterInfo *TRI;
|
2009-03-13 05:55:11 +00:00
|
|
|
MachineFunction *MF;
|
2009-05-04 03:30:11 +00:00
|
|
|
|
2004-10-01 00:35:07 +00:00
|
|
|
/// Virt2PhysMap - This is a virtual to physical register
|
|
|
|
/// mapping. Each virtual register is required to have an entry in
|
|
|
|
/// it; even spilled virtual registers (the register mapped to a
|
|
|
|
/// spilled register is the temporary used to load it from the
|
|
|
|
/// stack).
|
2019-08-13 00:55:24 +00:00
|
|
|
IndexedMap<Register, VirtReg2IndexFunctor> Virt2PhysMap;
|
Live interval splitting:
When a live interval is being spilled, rather than creating short, non-spillable
intervals for every def / use, split the interval at BB boundaries. That is, for
every BB where the live interval is defined or used, create a new interval that
covers all the defs and uses in the BB.
This is designed to eliminate one common problem: multiple reloads of the same
value in a single basic block. Note, it does *not* decrease the number of spills
since no copies are inserted so the split intervals are *connected* through
spill and reloads (or rematerialization). The newly created intervals can be
spilled again, in that case, since it does not span multiple basic blocks, it's
spilled in the usual manner. However, it can reuse the same stack slot as the
previously split interval.
This is currently controlled by -split-intervals-at-bb.
llvm-svn: 44198
2007-11-17 00:40:40 +00:00
|
|
|
|
2004-10-01 00:35:07 +00:00
|
|
|
/// Virt2StackSlotMap - This is virtual register to stack slot
|
|
|
|
/// mapping. Each spilled virtual register has an entry in it
|
|
|
|
/// which corresponds to the stack slot this register is spilled
|
|
|
|
/// at.
|
2007-02-01 05:32:05 +00:00
|
|
|
IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
|
Live interval splitting:
When a live interval is being spilled, rather than creating short, non-spillable
intervals for every def / use, split the interval at BB boundaries. That is, for
every BB where the live interval is defined or used, create a new interval that
covers all the defs and uses in the BB.
This is designed to eliminate one common problem: multiple reloads of the same
value in a single basic block. Note, it does *not* decrease the number of spills
since no copies are inserted so the split intervals are *connected* through
spill and reloads (or rematerialization). The newly created intervals can be
spilled again, in that case, since it does not span multiple basic blocks, it's
spilled in the usual manner. However, it can reuse the same stack slot as the
previously split interval.
This is currently controlled by -split-intervals-at-bb.
llvm-svn: 44198
2007-11-17 00:40:40 +00:00
|
|
|
|
|
|
|
/// Virt2SplitMap - This is virtual register to splitted virtual register
|
|
|
|
/// mapping.
|
|
|
|
IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap;
|
|
|
|
|
2010-11-16 00:41:01 +00:00
|
|
|
/// createSpillSlot - Allocate a spill slot for RC from MFI.
|
|
|
|
unsigned createSpillSlot(const TargetRegisterClass *RC);
|
|
|
|
|
2004-09-30 01:54:45 +00:00
|
|
|
public:
|
2009-03-13 05:55:11 +00:00
|
|
|
static char ID;
|
2017-09-13 21:15:20 +00:00
|
|
|
|
2019-07-14 11:47:36 +00:00
|
|
|
VirtRegMap()
|
|
|
|
: MachineFunctionPass(ID), MRI(nullptr), TII(nullptr), TRI(nullptr),
|
|
|
|
MF(nullptr), Virt2PhysMap(NO_PHYS_REG),
|
|
|
|
Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) {}
|
2017-09-13 21:15:20 +00:00
|
|
|
VirtRegMap(const VirtRegMap &) = delete;
|
|
|
|
VirtRegMap &operator=(const VirtRegMap &) = delete;
|
|
|
|
|
2014-03-07 09:26:03 +00:00
|
|
|
bool runOnMachineFunction(MachineFunction &MF) override;
|
2009-03-13 05:55:11 +00:00
|
|
|
|
2014-03-07 09:26:03 +00:00
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
2009-03-13 05:55:11 +00:00
|
|
|
AU.setPreservesAll();
|
|
|
|
MachineFunctionPass::getAnalysisUsage(AU);
|
|
|
|
}
|
2004-09-30 01:54:45 +00:00
|
|
|
|
2010-07-26 23:44:11 +00:00
|
|
|
MachineFunction &getMachineFunction() const {
|
2010-12-10 18:36:02 +00:00
|
|
|
assert(MF && "getMachineFunction called before runOnMachineFunction");
|
2010-07-26 23:44:11 +00:00
|
|
|
return *MF;
|
|
|
|
}
|
|
|
|
|
2010-12-10 18:36:02 +00:00
|
|
|
MachineRegisterInfo &getRegInfo() const { return *MRI; }
|
|
|
|
const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; }
|
|
|
|
|
2004-09-30 01:54:45 +00:00
|
|
|
void grow();
|
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// returns true if the specified virtual register is
|
2004-10-01 00:35:07 +00:00
|
|
|
/// mapped to a physical register
|
2019-08-13 00:55:24 +00:00
|
|
|
bool hasPhys(Register virtReg) const {
|
2004-09-30 01:54:45 +00:00
|
|
|
return getPhys(virtReg) != NO_PHYS_REG;
|
|
|
|
}
|
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// returns the physical register mapped to the specified
|
2004-10-01 00:35:07 +00:00
|
|
|
/// virtual register
|
2019-06-24 15:50:29 +00:00
|
|
|
Register getPhys(Register virtReg) const {
|
|
|
|
assert(virtReg.isVirtual());
|
2019-08-13 00:55:24 +00:00
|
|
|
return Virt2PhysMap[virtReg.id()];
|
2004-09-30 01:54:45 +00:00
|
|
|
}
|
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// creates a mapping for the specified virtual register to
|
2004-10-01 00:35:07 +00:00
|
|
|
/// the specified physical register
|
2019-08-13 00:55:24 +00:00
|
|
|
void assignVirt2Phys(Register virtReg, MCPhysReg physReg);
|
2004-09-30 01:54:45 +00:00
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// clears the specified virtual register's, physical
|
2004-10-01 00:35:07 +00:00
|
|
|
/// register mapping
|
2019-08-13 00:55:24 +00:00
|
|
|
void clearVirt(Register virtReg) {
|
|
|
|
assert(virtReg.isVirtual());
|
|
|
|
assert(Virt2PhysMap[virtReg.id()] != NO_PHYS_REG &&
|
2004-09-30 01:54:45 +00:00
|
|
|
"attempt to clear a not assigned virtual register");
|
2019-08-13 00:55:24 +00:00
|
|
|
Virt2PhysMap[virtReg.id()] = NO_PHYS_REG;
|
2004-09-30 01:54:45 +00:00
|
|
|
}
|
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// clears all virtual to physical register mappings
|
2004-09-30 01:54:45 +00:00
|
|
|
void clearAllVirt() {
|
2004-09-30 02:15:18 +00:00
|
|
|
Virt2PhysMap.clear();
|
2004-09-30 01:54:45 +00:00
|
|
|
grow();
|
|
|
|
}
|
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// returns true if VirtReg is assigned to its preferred physreg.
|
2019-08-13 00:55:24 +00:00
|
|
|
bool hasPreferredPhys(Register VirtReg);
|
2011-07-08 20:46:18 +00:00
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// returns true if VirtReg has a known preferred register.
|
2012-12-03 23:23:50 +00:00
|
|
|
/// This returns false if VirtReg has a preference that is a virtual
|
|
|
|
/// register that hasn't been assigned yet.
|
2019-08-13 00:55:24 +00:00
|
|
|
bool hasKnownPreference(Register VirtReg);
|
2012-12-03 23:23:50 +00:00
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// records virtReg is a split live interval from SReg.
|
2019-08-13 00:55:24 +00:00
|
|
|
void setIsSplitFromReg(Register virtReg, unsigned SReg) {
|
|
|
|
Virt2SplitMap[virtReg.id()] = SReg;
|
Live interval splitting:
When a live interval is being spilled, rather than creating short, non-spillable
intervals for every def / use, split the interval at BB boundaries. That is, for
every BB where the live interval is defined or used, create a new interval that
covers all the defs and uses in the BB.
This is designed to eliminate one common problem: multiple reloads of the same
value in a single basic block. Note, it does *not* decrease the number of spills
since no copies are inserted so the split intervals are *connected* through
spill and reloads (or rematerialization). The newly created intervals can be
spilled again, in that case, since it does not span multiple basic blocks, it's
spilled in the usual manner. However, it can reuse the same stack slot as the
previously split interval.
This is currently controlled by -split-intervals-at-bb.
llvm-svn: 44198
2007-11-17 00:40:40 +00:00
|
|
|
}
|
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// returns the live interval virtReg is split from.
|
2019-08-13 00:55:24 +00:00
|
|
|
unsigned getPreSplitReg(Register virtReg) const {
|
|
|
|
return Virt2SplitMap[virtReg.id()];
|
Live interval splitting:
When a live interval is being spilled, rather than creating short, non-spillable
intervals for every def / use, split the interval at BB boundaries. That is, for
every BB where the live interval is defined or used, create a new interval that
covers all the defs and uses in the BB.
This is designed to eliminate one common problem: multiple reloads of the same
value in a single basic block. Note, it does *not* decrease the number of spills
since no copies are inserted so the split intervals are *connected* through
spill and reloads (or rematerialization). The newly created intervals can be
spilled again, in that case, since it does not span multiple basic blocks, it's
spilled in the usual manner. However, it can reuse the same stack slot as the
previously split interval.
This is currently controlled by -split-intervals-at-bb.
llvm-svn: 44198
2007-11-17 00:40:40 +00:00
|
|
|
}
|
|
|
|
|
2011-02-19 00:38:43 +00:00
|
|
|
/// getOriginal - Return the original virtual register that VirtReg descends
|
|
|
|
/// from through splitting.
|
|
|
|
/// A register that was not created by splitting is its own original.
|
|
|
|
/// This operation is idempotent.
|
|
|
|
unsigned getOriginal(unsigned VirtReg) const {
|
|
|
|
unsigned Orig = getPreSplitReg(VirtReg);
|
|
|
|
return Orig ? Orig : VirtReg;
|
|
|
|
}
|
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// returns true if the specified virtual register is not
|
2007-08-13 23:45:17 +00:00
|
|
|
/// mapped to a stack slot or rematerialized.
|
2019-08-13 00:55:24 +00:00
|
|
|
bool isAssignedReg(Register virtReg) const {
|
2011-11-13 01:02:04 +00:00
|
|
|
if (getStackSlot(virtReg) == NO_STACK_SLOT)
|
Live interval splitting:
When a live interval is being spilled, rather than creating short, non-spillable
intervals for every def / use, split the interval at BB boundaries. That is, for
every BB where the live interval is defined or used, create a new interval that
covers all the defs and uses in the BB.
This is designed to eliminate one common problem: multiple reloads of the same
value in a single basic block. Note, it does *not* decrease the number of spills
since no copies are inserted so the split intervals are *connected* through
spill and reloads (or rematerialization). The newly created intervals can be
spilled again, in that case, since it does not span multiple basic blocks, it's
spilled in the usual manner. However, it can reuse the same stack slot as the
previously split interval.
This is currently controlled by -split-intervals-at-bb.
llvm-svn: 44198
2007-11-17 00:40:40 +00:00
|
|
|
return true;
|
|
|
|
// Split register can be assigned a physical register as well as a
|
|
|
|
// stack slot or remat id.
|
2019-08-13 00:55:24 +00:00
|
|
|
return (Virt2SplitMap[virtReg.id()] &&
|
|
|
|
Virt2PhysMap[virtReg.id()] != NO_PHYS_REG);
|
2004-09-30 01:54:45 +00:00
|
|
|
}
|
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// returns the stack slot mapped to the specified virtual
|
2004-10-01 00:35:07 +00:00
|
|
|
/// register
|
2019-08-13 00:55:24 +00:00
|
|
|
int getStackSlot(Register virtReg) const {
|
|
|
|
assert(virtReg.isVirtual());
|
|
|
|
return Virt2StackSlotMap[virtReg.id()];
|
2004-09-30 01:54:45 +00:00
|
|
|
}
|
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// create a mapping for the specifed virtual register to
|
2004-10-01 00:35:07 +00:00
|
|
|
/// the next available stack slot
|
2019-08-13 00:55:24 +00:00
|
|
|
int assignVirt2StackSlot(Register virtReg);
|
2017-09-13 21:15:20 +00:00
|
|
|
|
2018-05-01 16:10:38 +00:00
|
|
|
/// create a mapping for the specified virtual register to
|
2004-10-01 00:35:07 +00:00
|
|
|
/// the specified stack slot
|
2019-08-13 00:55:24 +00:00
|
|
|
void assignVirt2StackSlot(Register virtReg, int SS);
|
2004-09-30 01:54:45 +00:00
|
|
|
|
2014-04-14 00:51:57 +00:00
|
|
|
void print(raw_ostream &OS, const Module* M = nullptr) const override;
|
2004-09-30 01:54:45 +00:00
|
|
|
void dump() const;
|
|
|
|
};
|
|
|
|
|
2009-07-24 10:36:58 +00:00
|
|
|
inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) {
|
|
|
|
VRM.print(OS);
|
|
|
|
return OS;
|
|
|
|
}
|
2004-02-23 23:08:11 +00:00
|
|
|
|
2017-09-13 21:15:20 +00:00
|
|
|
} // end llvm namespace
|
|
|
|
|
|
|
|
#endif // LLVM_CODEGEN_VIRTREGMAP_H
|