+
+}
+
+void V8ISel::SelectPHINodes() {
+ const TargetInstrInfo &TII = *TM.getInstrInfo();
+ const Function &LF = *F->getFunction(); // The LLVM function...
+ for (Function::const_iterator I = LF.begin(), E = LF.end(); I != E; ++I) {
+ const BasicBlock *BB = I;
+ MachineBasicBlock &MBB = *MBBMap[I];
+
+ // Loop over all of the PHI nodes in the LLVM basic block...
+ MachineBasicBlock::iterator PHIInsertPoint = MBB.begin();
+ for (BasicBlock::const_iterator I = BB->begin();
+ PHINode *PN = const_cast<PHINode*>(dyn_cast<PHINode>(I)); ++I) {
+
+ // Create a new machine instr PHI node, and insert it.
+ unsigned PHIReg = getReg(*PN);
+ MachineInstr *PhiMI = BuildMI(MBB, PHIInsertPoint,
+ V8::PHI, PN->getNumOperands(), PHIReg);
+
+ MachineInstr *LongPhiMI = 0;
+ if (PN->getType() == Type::LongTy || PN->getType() == Type::ULongTy)
+ LongPhiMI = BuildMI(MBB, PHIInsertPoint,
+ V8::PHI, PN->getNumOperands(), PHIReg+1);
+
+ // PHIValues - Map of blocks to incoming virtual registers. We use this
+ // so that we only initialize one incoming value for a particular block,
+ // even if the block has multiple entries in the PHI node.
+ //
+ std::map<MachineBasicBlock*, unsigned> PHIValues;
+
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+ MachineBasicBlock *PredMBB = 0;
+ for (MachineBasicBlock::pred_iterator PI = MBB.pred_begin (),
+ PE = MBB.pred_end (); PI != PE; ++PI)
+ if (PN->getIncomingBlock(i) == (*PI)->getBasicBlock()) {
+ PredMBB = *PI;
+ break;
+ }
+ assert (PredMBB && "Couldn't find incoming machine-cfg edge for phi");
+
+ unsigned ValReg;
+ std::map<MachineBasicBlock*, unsigned>::iterator EntryIt =
+ PHIValues.lower_bound(PredMBB);
+
+ if (EntryIt != PHIValues.end() && EntryIt->first == PredMBB) {
+ // We already inserted an initialization of the register for this
+ // predecessor. Recycle it.
+ ValReg = EntryIt->second;
+
+ } else {
+ // Get the incoming value into a virtual register.
+ //
+ Value *Val = PN->getIncomingValue(i);
+
+ // If this is a constant or GlobalValue, we may have to insert code
+ // into the basic block to compute it into a virtual register.
+ if ((isa<Constant>(Val) && !isa<ConstantExpr>(Val)) ||
+ isa<GlobalValue>(Val)) {
+ // Simple constants get emitted at the end of the basic block,
+ // before any terminator instructions. We "know" that the code to
+ // move a constant into a register will never clobber any flags.
+ ValReg = getReg(Val, PredMBB, PredMBB->getFirstTerminator());
+ } else {
+ // Because we don't want to clobber any values which might be in
+ // physical registers with the computation of this constant (which
+ // might be arbitrarily complex if it is a constant expression),
+ // just insert the computation at the top of the basic block.
+ MachineBasicBlock::iterator PI = PredMBB->begin();
+
+ // Skip over any PHI nodes though!
+ while (PI != PredMBB->end() && PI->getOpcode() == V8::PHI)
+ ++PI;
+
+ ValReg = getReg(Val, PredMBB, PI);
+ }
+
+ // Remember that we inserted a value for this PHI for this predecessor
+ PHIValues.insert(EntryIt, std::make_pair(PredMBB, ValReg));
+ }
+
+ PhiMI->addRegOperand(ValReg);
+ PhiMI->addMachineBasicBlockOperand(PredMBB);
+ if (LongPhiMI) {
+ LongPhiMI->addRegOperand(ValReg+1);
+ LongPhiMI->addMachineBasicBlockOperand(PredMBB);
+ }
+ }
+
+ // Now that we emitted all of the incoming values for the PHI node, make
+ // sure to reposition the InsertPoint after the PHI that we just added.
+ // This is needed because we might have inserted a constant into this
+ // block, right after the PHI's which is before the old insert point!
+ PHIInsertPoint = LongPhiMI ? LongPhiMI : PhiMI;
+ ++PHIInsertPoint;
+ }
+ }