//===- MachineSSAUpdater.cpp - Unstructured SSA Update Tool ---------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the MachineSSAUpdater class. It's based on SSAUpdater // class in lib/Transforms/Utils. // //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachineSSAUpdater.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/SSAUpdaterImpl.h" using namespace llvm; typedef DenseMap<MachineBasicBlock*, unsigned> AvailableValsTy; static AvailableValsTy &getAvailableVals(void *AV) { return *static_cast<AvailableValsTy*>(AV); } MachineSSAUpdater::MachineSSAUpdater(MachineFunction &MF, SmallVectorImpl<MachineInstr*> *NewPHI) : AV(0), InsertedPHIs(NewPHI) { TII = MF.getTarget().getInstrInfo(); MRI = &MF.getRegInfo(); } MachineSSAUpdater::~MachineSSAUpdater() { delete static_cast<AvailableValsTy*>(AV); } /// Initialize - Reset this object to get ready for a new set of SSA /// updates. ProtoValue is the value used to name PHI nodes. void MachineSSAUpdater::Initialize(unsigned V) { if (AV == 0) AV = new AvailableValsTy(); else getAvailableVals(AV).clear(); VR = V; VRC = MRI->getRegClass(VR); } /// HasValueForBlock - Return true if the MachineSSAUpdater already has a value for /// the specified block. bool MachineSSAUpdater::HasValueForBlock(MachineBasicBlock *BB) const { return getAvailableVals(AV).count(BB); } /// AddAvailableValue - Indicate that a rewritten value is available in the /// specified block with the specified value. void MachineSSAUpdater::AddAvailableValue(MachineBasicBlock *BB, unsigned V) { getAvailableVals(AV)[BB] = V; } /// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is /// live at the end of the specified block. unsigned MachineSSAUpdater::GetValueAtEndOfBlock(MachineBasicBlock *BB) { return GetValueAtEndOfBlockInternal(BB); } static unsigned LookForIdenticalPHI(MachineBasicBlock *BB, SmallVector<std::pair<MachineBasicBlock*, unsigned>, 8> &PredValues) { if (BB->empty()) return 0; MachineBasicBlock::iterator I = BB->front(); if (!I->isPHI()) return 0; AvailableValsTy AVals; for (unsigned i = 0, e = PredValues.size(); i != e; ++i) AVals[PredValues[i].first] = PredValues[i].second; while (I != BB->end() && I->isPHI()) { bool Same = true; for (unsigned i = 1, e = I->getNumOperands(); i != e; i += 2) { unsigned SrcReg = I->getOperand(i).getReg(); MachineBasicBlock *SrcBB = I->getOperand(i+1).getMBB(); if (AVals[SrcBB] != SrcReg) { Same = false; break; } } if (Same) return I->getOperand(0).getReg(); ++I; } return 0; } /// InsertNewDef - Insert an empty PHI or IMPLICIT_DEF instruction which define /// a value of the given register class at the start of the specified basic /// block. It returns the virtual register defined by the instruction. static MachineInstr *InsertNewDef(unsigned Opcode, MachineBasicBlock *BB, MachineBasicBlock::iterator I, const TargetRegisterClass *RC, MachineRegisterInfo *MRI, const TargetInstrInfo *TII) { unsigned NewVR = MRI->createVirtualRegister(RC); return BuildMI(*BB, I, DebugLoc(), TII->get(Opcode), NewVR); } /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that /// is live in the middle of the specified block. /// /// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one /// important case: if there is a definition of the rewritten value after the /// 'use' in BB. Consider code like this: /// /// X1 = ... /// SomeBB: /// use(X) /// X2 = ... /// br Cond, SomeBB, OutBB /// /// In this case, there are two values (X1 and X2) added to the AvailableVals /// set by the client of the rewriter, and those values are both live out of /// their respective blocks. However, the use of X happens in the *middle* of /// a block. Because of this, we need to insert a new PHI node in SomeBB to /// merge the appropriate values, and this value isn't live out of the block. /// unsigned MachineSSAUpdater::GetValueInMiddleOfBlock(MachineBasicBlock *BB) { // If there is no definition of the renamed variable in this block, just use // GetValueAtEndOfBlock to do our work. if (!HasValueForBlock(BB)) return GetValueAtEndOfBlockInternal(BB); // If there are no predecessors, just return undef. if (BB->pred_empty()) { // Insert an implicit_def to represent an undef value. MachineInstr *NewDef = InsertNewDef(TargetOpcode::IMPLICIT_DEF, BB, BB->getFirstTerminator(), VRC, MRI, TII); return NewDef->getOperand(0).getReg(); } // Otherwise, we have the hard case. Get the live-in values for each // predecessor. SmallVector<std::pair<MachineBasicBlock*, unsigned>, 8> PredValues; unsigned SingularValue = 0; bool isFirstPred = true; for (MachineBasicBlock::pred_iterator PI = BB->pred_begin(), E = BB->pred_end(); PI != E; ++PI) { MachineBasicBlock *PredBB = *PI; unsigned PredVal = GetValueAtEndOfBlockInternal(PredBB); PredValues.push_back(std::make_pair(PredBB, PredVal)); // Compute SingularValue. if (isFirstPred) { SingularValue = PredVal; isFirstPred = false; } else if (PredVal != SingularValue) SingularValue = 0; } // Otherwise, if all the merged values are the same, just use it. if (SingularValue != 0) return SingularValue; // If an identical PHI is already in BB, just reuse it. unsigned DupPHI = LookForIdenticalPHI(BB, PredValues); if (DupPHI) return DupPHI; // Otherwise, we do need a PHI: insert one now. MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front(); MachineInstr *InsertedPHI = InsertNewDef(TargetOpcode::PHI, BB, Loc, VRC, MRI, TII); // Fill in all the predecessors of the PHI. MachineInstrBuilder MIB(InsertedPHI); for (unsigned i = 0, e = PredValues.size(); i != e; ++i) MIB.addReg(PredValues[i].second).addMBB(PredValues[i].first); // See if the PHI node can be merged to a single value. This can happen in // loop cases when we get a PHI of itself and one other value. if (unsigned ConstVal = InsertedPHI->isConstantValuePHI()) { InsertedPHI->eraseFromParent(); return ConstVal; } // If the client wants to know about all new instructions, tell it. if (InsertedPHIs) InsertedPHIs->push_back(InsertedPHI); DEBUG(dbgs() << " Inserted PHI: " << *InsertedPHI << "\n"); return InsertedPHI->getOperand(0).getReg(); } static MachineBasicBlock *findCorrespondingPred(const MachineInstr *MI, MachineOperand *U) { for (unsigned i = 1, e = MI->getNumOperands(); i != e; i += 2) { if (&MI->getOperand(i) == U) return MI->getOperand(i+1).getMBB(); } llvm_unreachable("MachineOperand::getParent() failure?"); return 0; } /// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes, /// which use their value in the corresponding predecessor. void MachineSSAUpdater::RewriteUse(MachineOperand &U) { MachineInstr *UseMI = U.getParent(); unsigned NewVR = 0; if (UseMI->isPHI()) { MachineBasicBlock *SourceBB = findCorrespondingPred(UseMI, &U); NewVR = GetValueAtEndOfBlockInternal(SourceBB); } else { NewVR = GetValueInMiddleOfBlock(UseMI->getParent()); } U.setReg(NewVR); } void MachineSSAUpdater::ReplaceRegWith(unsigned OldReg, unsigned NewReg) { MRI->replaceRegWith(OldReg, NewReg); AvailableValsTy &AvailableVals = getAvailableVals(AV); for (DenseMap<MachineBasicBlock*, unsigned>::iterator I = AvailableVals.begin(), E = AvailableVals.end(); I != E; ++I) if (I->second == OldReg) I->second = NewReg; } /// MachinePHIiter - Iterator for PHI operands. This is used for the /// PHI_iterator in the SSAUpdaterImpl template. namespace { class MachinePHIiter { private: MachineInstr *PHI; unsigned idx; public: explicit MachinePHIiter(MachineInstr *P) // begin iterator : PHI(P), idx(1) {} MachinePHIiter(MachineInstr *P, bool) // end iterator : PHI(P), idx(PHI->getNumOperands()) {} MachinePHIiter &operator++() { idx += 2; return *this; } bool operator==(const MachinePHIiter& x) const { return idx == x.idx; } bool operator!=(const MachinePHIiter& x) const { return !operator==(x); } unsigned getIncomingValue() { return PHI->getOperand(idx).getReg(); } MachineBasicBlock *getIncomingBlock() { return PHI->getOperand(idx+1).getMBB(); } }; } /// SSAUpdaterTraits<MachineSSAUpdater> - Traits for the SSAUpdaterImpl /// template, specialized for MachineSSAUpdater. namespace llvm { template<> class SSAUpdaterTraits<MachineSSAUpdater> { public: typedef MachineBasicBlock BlkT; typedef unsigned ValT; typedef MachineInstr PhiT; typedef MachineBasicBlock::succ_iterator BlkSucc_iterator; static BlkSucc_iterator BlkSucc_begin(BlkT *BB) { return BB->succ_begin(); } static BlkSucc_iterator BlkSucc_end(BlkT *BB) { return BB->succ_end(); } typedef MachinePHIiter PHI_iterator; static inline PHI_iterator PHI_begin(PhiT *PHI) { return PHI_iterator(PHI); } static inline PHI_iterator PHI_end(PhiT *PHI) { return PHI_iterator(PHI, true); } /// FindPredecessorBlocks - Put the predecessors of BB into the Preds /// vector. static void FindPredecessorBlocks(MachineBasicBlock *BB, SmallVectorImpl<MachineBasicBlock*> *Preds){ for (MachineBasicBlock::pred_iterator PI = BB->pred_begin(), E = BB->pred_end(); PI != E; ++PI) Preds->push_back(*PI); } /// GetUndefVal - Create an IMPLICIT_DEF instruction with a new register. /// Add it into the specified block and return the register. static unsigned GetUndefVal(MachineBasicBlock *BB, MachineSSAUpdater *Updater) { // Insert an implicit_def to represent an undef value. MachineInstr *NewDef = InsertNewDef(TargetOpcode::IMPLICIT_DEF, BB, BB->getFirstTerminator(), Updater->VRC, Updater->MRI, Updater->TII); return NewDef->getOperand(0).getReg(); } /// CreateEmptyPHI - Create a PHI instruction that defines a new register. /// Add it into the specified block and return the register. static unsigned CreateEmptyPHI(MachineBasicBlock *BB, unsigned NumPreds, MachineSSAUpdater *Updater) { MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front(); MachineInstr *PHI = InsertNewDef(TargetOpcode::PHI, BB, Loc, Updater->VRC, Updater->MRI, Updater->TII); return PHI->getOperand(0).getReg(); } /// AddPHIOperand - Add the specified value as an operand of the PHI for /// the specified predecessor block. static void AddPHIOperand(MachineInstr *PHI, unsigned Val, MachineBasicBlock *Pred) { PHI->addOperand(MachineOperand::CreateReg(Val, false)); PHI->addOperand(MachineOperand::CreateMBB(Pred)); } /// InstrIsPHI - Check if an instruction is a PHI. /// static MachineInstr *InstrIsPHI(MachineInstr *I) { if (I && I->isPHI()) return I; return 0; } /// ValueIsPHI - Check if the instruction that defines the specified register /// is a PHI instruction. static MachineInstr *ValueIsPHI(unsigned Val, MachineSSAUpdater *Updater) { return InstrIsPHI(Updater->MRI->getVRegDef(Val)); } /// ValueIsNewPHI - Like ValueIsPHI but also check if the PHI has no source /// operands, i.e., it was just added. static MachineInstr *ValueIsNewPHI(unsigned Val, MachineSSAUpdater *Updater) { MachineInstr *PHI = ValueIsPHI(Val, Updater); if (PHI && PHI->getNumOperands() <= 1) return PHI; return 0; } /// GetPHIValue - For the specified PHI instruction, return the register /// that it defines. static unsigned GetPHIValue(MachineInstr *PHI) { return PHI->getOperand(0).getReg(); } }; } // End llvm namespace /// GetValueAtEndOfBlockInternal - Check to see if AvailableVals has an entry /// for the specified BB and if so, return it. If not, construct SSA form by /// first calculating the required placement of PHIs and then inserting new /// PHIs where needed. unsigned MachineSSAUpdater::GetValueAtEndOfBlockInternal(MachineBasicBlock *BB){ AvailableValsTy &AvailableVals = getAvailableVals(AV); if (unsigned V = AvailableVals[BB]) return V; SSAUpdaterImpl<MachineSSAUpdater> Impl(this, &AvailableVals, InsertedPHIs); return Impl.GetValue(BB); }