Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAGISel.cpp updated: 1.302 -> 1.303 --- Log message: Fix a bug in merged condition handling (CodeGen/Generic/2006-10-27-CondFolding.ll). Add many fewer CFG edges and PHI node entries. If there is a switch which has the same block as multiple destinations, only add that block once as a successor/phi node (in the jumptable case) --- Diffs of the changes: (+111 -68) SelectionDAGISel.cpp | 179 +++++++++++++++++++++++++++++++-------------------- 1 files changed, 111 insertions(+), 68 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.302 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.303 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.302 Fri Oct 27 16:58:03 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Oct 27 18:50:33 2006 @@ -282,24 +282,24 @@ // Create Machine PHI nodes for LLVM PHI nodes, lowering them as // appropriate. PHINode *PN; - for (BasicBlock::iterator I = BB->begin(); - (PN = dyn_cast<PHINode>(I)); ++I) - if (!PN->use_empty()) { - MVT::ValueType VT = TLI.getValueType(PN->getType()); - unsigned NumElements; - if (VT != MVT::Vector) - NumElements = TLI.getNumElements(VT); - else { - MVT::ValueType VT1,VT2; - NumElements = - TLI.getPackedTypeBreakdown(cast<PackedType>(PN->getType()), - VT1, VT2); - } - unsigned PHIReg = ValueMap[PN]; - assert(PHIReg &&"PHI node does not have an assigned virtual register!"); - for (unsigned i = 0; i != NumElements; ++i) - BuildMI(MBB, TargetInstrInfo::PHI, PN->getNumOperands(), PHIReg+i); - } + for (BasicBlock::iterator I = BB->begin();(PN = dyn_cast<PHINode>(I)); ++I){ + if (PN->use_empty()) continue; + + MVT::ValueType VT = TLI.getValueType(PN->getType()); + unsigned NumElements; + if (VT != MVT::Vector) + NumElements = TLI.getNumElements(VT); + else { + MVT::ValueType VT1,VT2; + NumElements = + TLI.getPackedTypeBreakdown(cast<PackedType>(PN->getType()), + VT1, VT2); + } + unsigned PHIReg = ValueMap[PN]; + assert(PHIReg && "PHI node does not have an assigned virtual register!"); + for (unsigned i = 0; i != NumElements; ++i) + BuildMI(MBB, TargetInstrInfo::PHI, PN->getNumOperands(), PHIReg+i); + } } } @@ -497,6 +497,7 @@ void FindMergedConditions(Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB, MachineBasicBlock *CurBB, unsigned Opc); + bool isExportableFromCurrentBlock(Value *V, const BasicBlock *FromBB); void ExportFromCurrentBlock(Value *V); // Terminator instructions. @@ -798,15 +799,39 @@ PendingLoads.push_back(CopyValueToVirtualRegister(V, Reg)); } +bool SelectionDAGLowering::isExportableFromCurrentBlock(Value *V, + const BasicBlock *FromBB) { + // The operands of the setcc have to be in this block. We don't know + // how to export them from some other block. + if (Instruction *VI = dyn_cast<Instruction>(V)) { + // Can export from current BB. + if (VI->getParent() == FromBB) + return true; + + // Is already exported, noop. + return FuncInfo.isExportedInst(V); + } + + // If this is an argument, we can export it if the BB is the entry block or + // if it is already exported. + if (isa<Argument>(V)) { + if (FromBB == &FromBB->getParent()->getEntryBlock()) + return true; + + // Otherwise, can only export this if it is already exported. + return FuncInfo.isExportedInst(V); + } + + // Otherwise, constants can always be exported. + return true; +} + /// FindMergedConditions - If Cond is an expression like void SelectionDAGLowering::FindMergedConditions(Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB, MachineBasicBlock *CurBB, unsigned Opc) { - // FIXME: HANDLE AND. - // FIXME: HANDLE NOT - // If this node is not part of the or/and tree, emit it as a branch. BinaryOperator *BOp = dyn_cast<BinaryOperator>(Cond); @@ -819,12 +844,8 @@ if (BOp && isa<SetCondInst>(BOp) && // The operands of the setcc have to be in this block. We don't know // how to export them from some other block. - (!isa<Instruction>(BOp->getOperand(0)) || - cast<Instruction>(BOp->getOperand(0))->getParent() == BB || - FuncInfo.isExportedInst(BOp->getOperand(0))) && - (!isa<Instruction>(BOp->getOperand(1)) || - cast<Instruction>(BOp->getOperand(1))->getParent() == BB || - FuncInfo.isExportedInst(BOp->getOperand(1)))) { + isExportableFromCurrentBlock(BOp->getOperand(0), BB) && + isExportableFromCurrentBlock(BOp->getOperand(1), BB)) { ExportFromCurrentBlock(BOp->getOperand(0)); ExportFromCurrentBlock(BOp->getOperand(1)); @@ -1222,10 +1243,18 @@ DestBBs.push_back(Default); } - // Update successor info + // Update successor info. Add one edge to each unique successor. + // Vector bool would be better, but vector<bool> is really slow. + std::vector<unsigned char> SuccsHandled; + SuccsHandled.resize(CurMBB->getParent()->getNumBlockIDs()); + for (std::vector<MachineBasicBlock*>::iterator I = DestBBs.begin(), - E = DestBBs.end(); I != E; ++I) - JumpTableBB->addSuccessor(*I); + E = DestBBs.end(); I != E; ++I) { + if (!SuccsHandled[(*I)->getNumber()]) { + SuccsHandled[(*I)->getNumber()] = true; + JumpTableBB->addSuccessor(*I); + } + } // Create a jump table index for this jump table, or return an existing // one. @@ -3710,63 +3739,77 @@ // BB. As such, the start of the BB might correspond to a different MBB than // the end. // + TerminatorInst *TI = LLVMBB->getTerminator(); // Emit constants only once even if used by multiple PHI nodes. std::map<Constant*, unsigned> ConstantsOut; + // Vector bool would be better, but vector<bool> is really slow. + std::vector<unsigned char> SuccsHandled; + if (TI->getNumSuccessors()) + SuccsHandled.resize(BB->getParent()->getNumBlockIDs()); + // Check successor nodes PHI nodes that expect a constant to be available from // this block. - TerminatorInst *TI = LLVMBB->getTerminator(); for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) { BasicBlock *SuccBB = TI->getSuccessor(succ); if (!isa<PHINode>(SuccBB->begin())) continue; + MachineBasicBlock *SuccMBB = FuncInfo.MBBMap[SuccBB]; - MachineBasicBlock::iterator MBBI = FuncInfo.MBBMap[SuccBB]->begin(); + // If this terminator has multiple identical successors (common for + // switches), only handle each succ once. + unsigned SuccMBBNo = SuccMBB->getNumber(); + if (SuccsHandled[SuccMBBNo]) continue; + SuccsHandled[SuccMBBNo] = true; + + MachineBasicBlock::iterator MBBI = SuccMBB->begin(); PHINode *PN; // At this point we know that there is a 1-1 correspondence between LLVM PHI // nodes and Machine PHI nodes, but the incoming operands have not been // emitted yet. for (BasicBlock::iterator I = SuccBB->begin(); - (PN = dyn_cast<PHINode>(I)); ++I) - if (!PN->use_empty()) { - unsigned Reg; - Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB); - if (Constant *C = dyn_cast<Constant>(PHIOp)) { - unsigned &RegOut = ConstantsOut[C]; - if (RegOut == 0) { - RegOut = FuncInfo.CreateRegForValue(C); - UnorderedChains.push_back( - SDL.CopyValueToVirtualRegister(C, RegOut)); - } - Reg = RegOut; - } else { - Reg = FuncInfo.ValueMap[PHIOp]; - if (Reg == 0) { - assert(isa<AllocaInst>(PHIOp) && - FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(PHIOp)) && - "Didn't codegen value into a register!??"); - Reg = FuncInfo.CreateRegForValue(PHIOp); - UnorderedChains.push_back( - SDL.CopyValueToVirtualRegister(PHIOp, Reg)); - } + (PN = dyn_cast<PHINode>(I)); ++I) { + // Ignore dead phi's. + if (PN->use_empty()) continue; + + unsigned Reg; + Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB); + if (Constant *C = dyn_cast<Constant>(PHIOp)) { + unsigned &RegOut = ConstantsOut[C]; + if (RegOut == 0) { + RegOut = FuncInfo.CreateRegForValue(C); + UnorderedChains.push_back( + SDL.CopyValueToVirtualRegister(C, RegOut)); } - - // Remember that this register needs to added to the machine PHI node as - // the input for this MBB. - MVT::ValueType VT = TLI.getValueType(PN->getType()); - unsigned NumElements; - if (VT != MVT::Vector) - NumElements = TLI.getNumElements(VT); - else { - MVT::ValueType VT1,VT2; - NumElements = - TLI.getPackedTypeBreakdown(cast<PackedType>(PN->getType()), - VT1, VT2); + Reg = RegOut; + } else { + Reg = FuncInfo.ValueMap[PHIOp]; + if (Reg == 0) { + assert(isa<AllocaInst>(PHIOp) && + FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(PHIOp)) && + "Didn't codegen value into a register!??"); + Reg = FuncInfo.CreateRegForValue(PHIOp); + UnorderedChains.push_back( + SDL.CopyValueToVirtualRegister(PHIOp, Reg)); } - for (unsigned i = 0, e = NumElements; i != e; ++i) - PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg+i)); } + + // Remember that this register needs to added to the machine PHI node as + // the input for this MBB. + MVT::ValueType VT = TLI.getValueType(PN->getType()); + unsigned NumElements; + if (VT != MVT::Vector) + NumElements = TLI.getNumElements(VT); + else { + MVT::ValueType VT1,VT2; + NumElements = + TLI.getPackedTypeBreakdown(cast<PackedType>(PN->getType()), + VT1, VT2); + } + for (unsigned i = 0, e = NumElements; i != e; ++i) + PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg+i)); + } } ConstantsOut.clear(); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits