Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAGISel.cpp updated: 1.233 -> 1.234 --- Log message: Sink noop copies into the basic block that uses them. This reduces the number of cross-block live ranges, and allows the bb-at-a-time selector to always coallesce these away, at isel time. This reduces the load on the coallescer and register allocator. For example on a codec on X86, we went from: 1643 asm-printer - Number of machine instrs printed 419 liveintervals - Number of loads/stores folded into instructions 1144 liveintervals - Number of identity moves eliminated after coalescing 1022 liveintervals - Number of interval joins performed 282 liveintervals - Number of intervals after coalescing 1304 liveintervals - Number of original intervals 86 regalloc - Number of times we had to backtrack 1.90232 regalloc - Ratio of intervals processed over total intervals 40 spiller - Number of values reused 182 spiller - Number of loads added 121 spiller - Number of stores added 132 spiller - Number of register spills 6 twoaddressinstruction - Number of instructions commuted to coalesce 360 twoaddressinstruction - Number of two-address instructions to: 1636 asm-printer - Number of machine instrs printed 403 liveintervals - Number of loads/stores folded into instructions 1155 liveintervals - Number of identity moves eliminated after coalescing 1033 liveintervals - Number of interval joins performed 279 liveintervals - Number of intervals after coalescing 1312 liveintervals - Number of original intervals 76 regalloc - Number of times we had to backtrack 1.88998 regalloc - Ratio of intervals processed over total intervals 1 spiller - Number of copies elided 41 spiller - Number of values reused 191 spiller - Number of loads added 114 spiller - Number of stores added 128 spiller - Number of register spills 4 twoaddressinstruction - Number of instructions commuted to coalesce 356 twoaddressinstruction - Number of two-address instructions On this testcase, this change provides a modest reduction in spill code, regalloc iterations, and total instructions emitted. It increases the number of register coallesces. --- Diffs of the changes: (+77 -4) SelectionDAGISel.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 77 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.233 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.234 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.233 Tue May 2 22:48:02 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu May 4 20:04:50 2006 @@ -2763,6 +2763,49 @@ return V = Ptr; } +/// OptimizeNoopCopyExpression - We have determined that the specified cast +/// instruction is a noop copy (e.g. it's casting from one pointer type to +/// another, int->uint, or int->sbyte on PPC. +static void OptimizeNoopCopyExpression(CastInst *CI) { + BasicBlock *DefBB = CI->getParent(); + + /// InsertedCasts - Only insert a cast in each block once. + std::map<BasicBlock*, CastInst*> InsertedCasts; + + for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end(); + UI != E; ) { + Use &TheUse = UI.getUse(); + Instruction *User = cast<Instruction>(*UI); + + // Figure out which BB this cast is used in. For PHI's this is the + // appropriate predecessor block. + BasicBlock *UserBB = User->getParent(); + if (PHINode *PN = dyn_cast<PHINode>(User)) { + unsigned OpVal = UI.getOperandNo()/2; + UserBB = PN->getIncomingBlock(OpVal); + } + + // Preincrement use iterator so we don't invalidate it. + ++UI; + + // If this user is in the same block as the cast, don't change the cast. + if (UserBB == DefBB) continue; + + // If we have already inserted a cast into this block, use it. + CastInst *&InsertedCast = InsertedCasts[UserBB]; + + if (!InsertedCast) { + BasicBlock::iterator InsertPt = UserBB->begin(); + while (isa<PHINode>(InsertPt)) ++InsertPt; + + InsertedCast = + new CastInst(CI->getOperand(0), CI->getType(), "", InsertPt); + } + + // Replace a use of the cast with a use of the new casat. + TheUse = InsertedCast; + } +} /// OptimizeGEPExpression - Since we are doing basic-block-at-a-time instruction /// selection, we want to be a bit careful about some things. In particular, if @@ -2890,8 +2933,10 @@ // constants, this way the load of the constant into a vreg will not be placed // into MBBs that are used some other way. // - // In this pass we also look for GEP instructions that are used across basic - // blocks and rewrites them to improve basic-block-at-a-time selection. + // In this pass we also look for GEP and cast instructions that are used + // across basic blocks and rewrite them to improve basic-block-at-a-time + // selection. + // // for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { PHINode *PN; @@ -2901,9 +2946,37 @@ if (isa<Constant>(PN->getIncomingValue(i))) SplitCriticalEdge(PN->getIncomingBlock(i), BB); - for (BasicBlock::iterator E = BB->end(); BBI != E; ) - if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(BBI++)) + for (BasicBlock::iterator E = BB->end(); BBI != E; ) { + Instruction *I = BBI++; + if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) { OptimizeGEPExpression(GEPI, TLI.getTargetData()); + } else if (CastInst *CI = dyn_cast<CastInst>(I)) { + // If this is a noop copy, sink it into user blocks to reduce the number + // of virtual registers that must be created and coallesced. + MVT::ValueType SrcVT = TLI.getValueType(CI->getOperand(0)->getType()); + MVT::ValueType DstVT = TLI.getValueType(CI->getType()); + + // This is an fp<->int conversion? + if (MVT::isInteger(SrcVT) != MVT::isInteger(DstVT)) + continue; + + // If this is an extension, it will be a zero or sign extension, which + // isn't a noop. + if (SrcVT < DstVT) continue; + + // If these values will be promoted, find out what they will be promoted + // to. This helps us consider truncates on PPC as noop copies when they + // are. + if (TLI.getTypeAction(SrcVT) == TargetLowering::Promote) + SrcVT = TLI.getTypeToTransformTo(SrcVT); + if (TLI.getTypeAction(DstVT) == TargetLowering::Promote) + DstVT = TLI.getTypeToTransformTo(DstVT); + + // If, after promotion, these are the same types, this is a noop copy. + if (SrcVT == DstVT) + OptimizeNoopCopyExpression(CI); + } + } } FunctionLoweringInfo FuncInfo(TLI, Fn, MF); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits