use-define
1. SSA Reg¶
C++
MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
const TargetRegisterInfo *TRI = &getRegisterInfo();
DefMI = MRI->getVRegDef(TrueReg);
C++
/// getVRegDef - Return the machine instr that defines the specified virtual
/// register or null if none is found. This assumes that the code is in SSA
/// form, so there should only be one definition.
MachineInstr *MachineRegisterInfo::getVRegDef(Register Reg) const {
// Since we are in SSA form, we can use the first definition.
def_instr_iterator I = def_instr_begin(Reg);
assert((I.atEnd() || std::next(I) == def_instr_end()) &&
"getVRegDef assumes a single definition or no definition");
return !I.atEnd() ? &*I : nullptr;
}
/// getUniqueVRegDef - Return the unique machine instr that defines the
/// specified virtual register or null if none is found. If there are
/// multiple definitions or no definition, return null.
MachineInstr *MachineRegisterInfo::getUniqueVRegDef(Register Reg) const {
if (def_empty(Reg)) return nullptr;
def_instr_iterator I = def_instr_begin(Reg);
if (std::next(I) != def_instr_end())
return nullptr;
return &*I;
}
C++
MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
MachineInstr *PPCInstrInfo::getForwardingDefMI(
MachineInstr &MI,
unsigned &OpNoForForwarding,
bool &SeenIntermediateUse) const {
OpNoForForwarding = ~0U;
MachineInstr *DefMI = nullptr;
MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
const TargetRegisterInfo *TRI = &getRegisterInfo();
// If we're in SSA, get the defs through the MRI. Otherwise, only look
// within the basic block to see if the register is defined using an
// LI/LI8/ADDI/ADDI8.
if (MRI->isSSA()) {
for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
if (!MI.getOperand(i).isReg())
continue;
Register Reg = MI.getOperand(i).getReg();
if (!Register::isVirtualRegister(Reg))
continue;
unsigned TrueReg = TRI->lookThruCopyLike(Reg, MRI);
if (Register::isVirtualRegister(TrueReg)) {
DefMI = MRI->getVRegDef(TrueReg);
if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8 ||
DefMI->getOpcode() == PPC::ADDI ||
DefMI->getOpcode() == PPC::ADDI8) {
OpNoForForwarding = i;
// The ADDI and LI operand maybe exist in one instruction at same
// time. we prefer to fold LI operand as LI only has one Imm operand
// and is more possible to be converted. So if current DefMI is
// ADDI/ADDI8, we continue to find possible LI/LI8.
if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8)
break;
}
}
}
} else {
C++
void MachineRegisterInfo::clearKillFlags(Register Reg) const {
for (MachineOperand &MO : use_operands(Reg))
MO.setIsKill(false);
}
PPCBoolRetToInt: Skip translation if there is ConstantExpr
C++
bool OnlyOneUse = MRI->hasOneNonDBGUse(Reg);
175 MachineInstr *DefMI = MRI->getVRegDef(Reg);
MRI->use_nodbg_empty(SrcReg)
MRI.hasOneNonDBGUse(Reg) && MRI.hasOneDef(Reg) &
C++
MachineInstr *MachineRegisterInfo::getVRegDef(Register Reg) const {
// Since we are in SSA form, we can use the first definition.
def_instr_iterator I = def_instr_begin(Reg);
assert((I.atEnd() || std::next(I) == def_instr_end()) &&
"getVRegDef assumes a single definition or no definition");
return !I.atEnd() ? &*I : nullptr;
}
/// getUniqueVRegDef - Return the unique machine instr that defines the
/// specified virtual register or null if none is found. If there are
/// multiple definitions or no definition, return null.
MachineInstr *MachineRegisterInfo::getUniqueVRegDef(Register Reg) const {
if (def_empty(Reg)) return nullptr;
def_instr_iterator I = def_instr_begin(Reg);
if (std::next(I) != def_instr_end())
return nullptr;
return &*I;
}
C++
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
using use_iterator =
defusechain_iterator<true, false, false, true, false, false>;
use_iterator use_begin(Register RegNo) const {
return use_iterator(getRegUseDefListHead(RegNo));
}
static use_iterator use_end() { return use_iterator(nullptr); }
inline iterator_range<use_iterator> use_operands(Register Reg) const {
return make_range(use_begin(Reg), use_end());
}
/// use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the
/// specified register, stepping by MachineInstr.
using use_instr_iterator =
defusechain_instr_iterator<true, false, false, false, true, false>;
use_instr_iterator use_instr_begin(Register RegNo) const {
return use_instr_iterator(getRegUseDefListHead(RegNo));
}
static use_instr_iterator use_instr_end() {
return use_instr_iterator(nullptr);
}
inline iterator_range<use_instr_iterator>
use_instructions(Register Reg) const {
return make_range(use_instr_begin(Reg), use_instr_end());
}
/// use_bundle_iterator/use_bundle_begin/use_bundle_end - Walk all uses of the
/// specified register, stepping by bundle.
using use_bundle_iterator =
defusechain_instr_iterator<true, false, false, false, false, true>;
use_bundle_iterator use_bundle_begin(Register RegNo) const {
return use_bundle_iterator(getRegUseDefListHead(RegNo));
}
static use_bundle_iterator use_bundle_end() {
return use_bundle_iterator(nullptr);
}
inline iterator_range<use_bundle_iterator> use_bundles(Register Reg) const {
return make_range(use_bundle_begin(Reg), use_bundle_end());
}
/// use_empty - Return true if there are no instructions using the specified
/// register.
bool use_empty(Register RegNo) const { return use_begin(RegNo) == use_end(); }
/// hasOneUse - Return true if there is exactly one instruction using the
/// specified register.
bool hasOneUse(Register RegNo) const {
use_iterator UI = use_begin(RegNo);
if (UI == use_end())
return false;
return ++UI == use_end();
}
/// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
/// specified register, skipping those marked as Debug.
using use_nodbg_iterator =
defusechain_iterator<true, false, true, true, false, false>;
use_nodbg_iterator use_nodbg_begin(Register RegNo) const {
return use_nodbg_iterator(getRegUseDefListHead(RegNo));
}
static use_nodbg_iterator use_nodbg_end() {
return use_nodbg_iterator(nullptr);
}
inline iterator_range<use_nodbg_iterator>
use_nodbg_operands(Register Reg) const {
return make_range(use_nodbg_begin(Reg), use_nodbg_end());
}
/// use_instr_nodbg_iterator/use_instr_nodbg_begin/use_instr_nodbg_end - Walk
/// all uses of the specified register, stepping by MachineInstr, skipping
/// those marked as Debug.
using use_instr_nodbg_iterator =
defusechain_instr_iterator<true, false, true, false, true, false>;
use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const {
return use_instr_nodbg_iterator(getRegUseDefListHead(RegNo));
}
static use_instr_nodbg_iterator use_instr_nodbg_end() {
return use_instr_nodbg_iterator(nullptr);
}
inline iterator_range<use_instr_nodbg_iterator>
use_nodbg_instructions(Register Reg) const {
return make_range(use_instr_nodbg_begin(Reg), use_instr_nodbg_end());
}
/// use_bundle_nodbg_iterator/use_bundle_nodbg_begin/use_bundle_nodbg_end - Walk
/// all uses of the specified register, stepping by bundle, skipping
/// those marked as Debug.
using use_bundle_nodbg_iterator =
defusechain_instr_iterator<true, false, true, false, false, true>;
use_bundle_nodbg_iterator use_bundle_nodbg_begin(Register RegNo) const {
return use_bundle_nodbg_iterator(getRegUseDefListHead(RegNo));
}
static use_bundle_nodbg_iterator use_bundle_nodbg_end() {
return use_bundle_nodbg_iterator(nullptr);
}
inline iterator_range<use_bundle_nodbg_iterator>
use_nodbg_bundles(Register Reg) const {
return make_range(use_bundle_nodbg_begin(Reg), use_bundle_nodbg_end());
}
/// use_nodbg_empty - Return true if there are no non-Debug instructions
/// using the specified register.
bool use_nodbg_empty(Register RegNo) const {
return use_nodbg_begin(RegNo) == use_nodbg_end();
}
/// hasOneNonDBGUse - Return true if there is exactly one non-Debug
/// use of the specified register.
bool hasOneNonDBGUse(Register RegNo) const;
/// hasOneNonDBGUse - Return true if there is exactly one non-Debug
/// instruction using the specified register. Said instruction may have
/// multiple uses.
bool hasOneNonDBGUser(Register RegNo) const;
/// replaceRegWith - Replace all instances of FromReg with ToReg in the
/// machine function. This is like llvm-level X->replaceAllUsesWith(Y),
/// except that it also changes any definitions of the register as well.
///
/// Note that it is usually necessary to first constrain ToReg's register
/// class and register bank to match the FromReg constraints using one of the
/// methods:
///
/// constrainRegClass(ToReg, getRegClass(FromReg))
/// constrainRegAttrs(ToReg, FromReg)
/// RegisterBankInfo::constrainGenericRegister(ToReg,
/// *MRI.getRegClass(FromReg), MRI)
///
/// These functions will return a falsy result if the virtual registers have
/// incompatible constraints.
///
/// Note that if ToReg is a physical register the function will replace and
/// apply sub registers to ToReg in order to obtain a final/proper physical
/// register.
void replaceRegWith(Register FromReg, Register ToReg);
/// getVRegDef - Return the machine instr that defines the specified virtual
/// register or null if none is found. This assumes that the code is in SSA
/// form, so there should only be one definition.
MachineInstr *getVRegDef(Register Reg) const;
/// getUniqueVRegDef - Return the unique machine instr that defines the
/// specified virtual register or null if none is found. If there are
/// multiple definitions or no definition, return null.
MachineInstr *getUniqueVRegDef(Register Reg) const;
/// clearKillFlags - Iterate over all the uses of the given register and
/// clear the kill flag from the MachineOperand. This function is used by
/// optimization passes which extend register lifetimes and need only
/// preserve conservative kill flag information.
void clearKillFlags(Register Reg) const;
void dumpUses(Register RegNo) const;
C++
if (!MRI->hasOneUse(SrcMI->getOperand(1).getReg())) {
// FIXME: Set the kill/dead flag when there are more than 1 use.
for (MachineRegisterInfo::use_instr_iterator I = MRI->use_instr_begin(SrcMI->getOperand(1).getReg()),
E = MRI->use_instr_end();
I != E; ++I) {
I->dump();
}
SrcMI->getOperand(1).setIsKill(false);
dbgs() << __LINE__ << " zhangkang\n";
} else if (SrcMI->getParent() == MI.getParent()) {
2. PostRA(not SSA)¶
PPCInstrInfo提供getDefMIPostRA()方法。
C++
// In PostRA phase, try to find instruction defines \p Reg before \p MI.
// \p SeenIntermediate is set to true if uses between DefMI and \p MI exist.
MachineInstr *PPCInstrInfo::getDefMIPostRA(unsigned Reg, MachineInstr &MI,
bool &SeenIntermediateUse) const {
assert(!MI.getParent()->getParent()->getRegInfo().isSSA() &&
"Should be called after register allocation.");
const TargetRegisterInfo *TRI = &getRegisterInfo();
MachineBasicBlock::reverse_iterator E = MI.getParent()->rend(), It = MI;
It++;
SeenIntermediateUse = false;
for (; It != E; ++It) {
if (It->modifiesRegister(Reg, TRI))
return &*It;
if (It->readsRegister(Reg, TRI))
SeenIntermediateUse = true;
}
return nullptr;
}