35#define DEBUG_TYPE "machine-ssaupdater"
45 : InsertedPHIs(NewPHI),
TII(MF.getSubtarget().getInstrInfo()),
46 MRI(&MF.getRegInfo()) {}
78 return GetValueAtEndOfBlockInternal(BB);
83 SmallVectorImpl<std::pair<MachineBasicBlock *, Register>> &PredValues) {
92 for (
const auto &[SrcBB, SrcReg] : PredValues)
93 AVals[SrcBB] = SrcReg;
94 while (
I != BB->
end() &&
I->isPHI()) {
96 for (
unsigned i = 1, e =
I->getNumOperands(); i != e; i += 2) {
97 Register SrcReg =
I->getOperand(i).getReg();
99 if (AVals[SrcBB] != SrcReg) {
105 return I->getOperand(0).getReg();
119 Register NewVR =
MRI->createVirtualRegister(RegAttrs);
144 bool ExistingValueOnly) {
148 return GetValueAtEndOfBlockInternal(BB, ExistingValueOnly);
153 if (ExistingValueOnly)
167 bool isFirstPred =
true;
169 Register PredVal = GetValueAtEndOfBlockInternal(PredBB, ExistingValueOnly);
170 PredValues.
push_back(std::make_pair(PredBB, PredVal));
174 SingularValue = PredVal;
176 }
else if (PredVal != SingularValue)
182 return SingularValue;
190 if (ExistingValueOnly)
196 InsertNewDef(TargetOpcode::PHI, BB, Loc, RegAttrs, MRI, TII);
199 for (
const auto &[SrcBB, SrcReg] : PredValues)
210 if (InsertedPHIs) InsertedPHIs->
push_back(InsertedPHI);
213 return InsertedPHI.
getReg(0);
219 for (
unsigned i = 1, e =
MI->getNumOperands(); i != e; i += 2) {
220 if (&
MI->getOperand(i) == U)
221 return MI->getOperand(i+1).getMBB();
234 NewVR = GetValueAtEndOfBlockInternal(SourceBB);
244 dyn_cast_or_null<const TargetRegisterClass *>(RegAttrs.
RCOrRB);
283 :
PHI(
P), idx(
PHI->getNumOperands()) {}
286 bool operator==(
const PHI_iterator& x)
const {
return idx == x.idx; }
292 return PHI->getOperand(idx+1).getMBB();
299 return PHI_iterator(
PHI,
true);
316 Updater->RegAttrs, Updater->MRI, Updater->TII);
326 InsertNewDef(TargetOpcode::PHI, BB, Loc, Updater->RegAttrs,
327 Updater->MRI, Updater->TII);
328 return PHI->getOperand(0).getReg();
348 return InstrIsPHI(Updater->MRI->
getVRegDef(Val));
355 if (
PHI &&
PHI->getNumOperands() <= 1)
363 return PHI->getOperand(0).getReg();
375 bool ExistingValueOnly) {
378 if (ExistingVal || ExistingValueOnly)
382 return Impl.GetValue(BB);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static MachineInstrBuilder InsertNewDef(unsigned Opcode, MachineBasicBlock *BB, MachineBasicBlock::iterator I, MachineRegisterInfo::VRegAttrs RegAttrs, MachineRegisterInfo *MRI, const TargetInstrInfo *TII)
InsertNewDef - Insert an empty PHI or IMPLICIT_DEF instruction which define a value of the given regi...
static MachineBasicBlock * findCorrespondingPred(const MachineInstr *MI, MachineOperand *U)
static Register LookForIdenticalPHI(MachineBasicBlock *BB, SmallVectorImpl< std::pair< MachineBasicBlock *, Register > > &PredValues)
static AvailableValsTy & getAvailableVals(void *AV)
DenseMap< MachineBasicBlock *, Register > AvailableValsTy
This file defines the SmallVector class.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
succ_iterator succ_begin()
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< pred_iterator > predecessors()
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
Register isConstantValuePHI() const
If the specified instruction is a PHI that always merges together the same virtual register,...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
VRegAttrs getVRegAttrs(Register Reg) const
Returns register class or bank and low level type of Reg.
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
MachineSSAUpdater - This class updates SSA form for a set of virtual registers defined in multiple bl...
void Initialize(Register V)
Initialize - Reset this object to get ready for a new set of SSA updates.
Register GetValueInMiddleOfBlock(MachineBasicBlock *BB, bool ExistingValueOnly=false)
GetValueInMiddleOfBlock - Construct SSA form, materializing a value that is live in the middle of the...
void RewriteUse(MachineOperand &U)
RewriteUse - Rewrite a use of the symbolic value.
Register GetValueAtEndOfBlock(MachineBasicBlock *BB)
GetValueAtEndOfBlock - Construct SSA form, materializing a value that is live at the end of the speci...
void AddAvailableValue(MachineBasicBlock *BB, Register V)
AddAvailableValue - Indicate that a rewritten value is available at the end of the specified block wi...
bool HasValueForBlock(MachineBasicBlock *BB) const
HasValueForBlock - Return true if the MachineSSAUpdater already has a value for the specified block.
MachineSSAUpdater(MachineFunction &MF, SmallVectorImpl< MachineInstr * > *NewPHI=nullptr)
MachineSSAUpdater constructor.
Wrapper class representing virtual and physical registers.
bool operator!=(const PHI_iterator &x) const
bool operator==(const PHI_iterator &x) const
PHI_iterator & operator++()
Register getIncomingValue()
PHI_iterator(MachineInstr *P, bool)
MachineBasicBlock * getIncomingBlock()
PHI_iterator(MachineInstr *P)
static MachineInstr * ValueIsNewPHI(Register Val, MachineSSAUpdater *Updater)
ValueIsNewPHI - Like ValueIsPHI but also check if the PHI has no source operands, i....
static Register CreateEmptyPHI(MachineBasicBlock *BB, unsigned NumPreds, MachineSSAUpdater *Updater)
CreateEmptyPHI - Create a PHI instruction that defines a new register.
static PHI_iterator PHI_begin(PhiT *PHI)
static Register GetPHIValue(MachineInstr *PHI)
GetPHIValue - For the specified PHI instruction, return the register that it defines.
static void FindPredecessorBlocks(MachineBasicBlock *BB, SmallVectorImpl< MachineBasicBlock * > *Preds)
FindPredecessorBlocks - Put the predecessors of BB into the Preds vector.
MachineBasicBlock::succ_iterator BlkSucc_iterator
static MachineInstr * ValueIsPHI(Register Val, MachineSSAUpdater *Updater)
ValueIsPHI - Check if the instruction that defines the specified register is a PHI instruction.
static Register GetPoisonVal(MachineBasicBlock *BB, MachineSSAUpdater *Updater)
GetPoisonVal - Create an IMPLICIT_DEF instruction with a new register.
static MachineInstr * InstrIsPHI(MachineInstr *I)
InstrIsPHI - Check if an instruction is a PHI.
static BlkSucc_iterator BlkSucc_begin(BlkT *BB)
static BlkSucc_iterator BlkSucc_end(BlkT *BB)
static void AddPHIOperand(MachineInstr *PHI, Register Val, MachineBasicBlock *Pred)
AddPHIOperand - Add the specified value as an operand of the PHI for the specified predecessor block.
static PHI_iterator PHI_end(PhiT *PHI)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
All attributes(register class or bank and low-level type) a virtual register can have.