From: Chris Lattner Date: Thu, 8 Dec 2005 08:00:12 +0000 (+0000) Subject: improve code insertion in two ways: X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c78b0b740bcf2e00a8871090709c3571fe442f07;p=oota-llvm.git improve code insertion in two ways: 1. Only forward subst offsets into loads and stores, not into arbitrary things, where it will likely become a load. 2. If the source is a cast from pointer, forward subst the cast as well, allowing us to fold the cast away (improving cases when the cast is from an alloca or global). This hasn't been fully tested, but does appear to further reduce register pressure and improve code. Lets let the testers grind on it a bit. :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24640 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index c6cc60ac0c4..23a9954aca2 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1276,6 +1276,13 @@ static Value *InsertGEPComputeCode(Value *&V, BasicBlock *BB, Instruction *GEPI, while (isa(InsertPt)) ++InsertPt; } + // If Ptr is itself a cast, but in some other BB, emit a copy of the cast into + // BB so that there is only one value live across basic blocks (the cast + // operand). + if (CastInst *CI = dyn_cast(Ptr)) + if (CI->getParent() != BB && isa(CI->getOperand(0)->getType())) + Ptr = new CastInst(CI->getOperand(0), CI->getType(), "", InsertPt); + // Add the offset, cast it to the right type. Ptr = BinaryOperator::createAdd(Ptr, PtrOffset, "", InsertPt); Ptr = new CastInst(Ptr, GEPI->getType(), "", InsertPt); @@ -1371,32 +1378,31 @@ static void OptimizeGEPExpression(GetElementPtrInst *GEPI, // Okay, we have now emitted all of the variable index parts to the BB that // the GEP is defined in. Loop over all of the using instructions, inserting // an "add Ptr, ConstantOffset" into each block that uses it and update the - // instruction to use the newly computed value, making GEPI dead. + // instruction to use the newly computed value, making GEPI dead. When the + // user is a load or store instruction address, we emit the add into the user + // block, otherwise we use a canonical version right next to the gep (these + // won't be foldable as addresses, so we might as well share the computation). + std::map InsertedExprs; while (!GEPI->use_empty()) { Instruction *User = cast(GEPI->use_back()); - - // Handle PHI's specially, as we need to insert code in the predecessor - // blocks for uses, not in the PHI block. - if (PHINode *PN = dyn_cast(User)) { - for (PHINode::op_iterator OI = PN->op_begin(), E = PN->op_end(); - OI != E; OI += 2) { - if (*OI == GEPI) { - BasicBlock *Pred = cast(OI[1]); - *OI = InsertGEPComputeCode(InsertedExprs[Pred], Pred, GEPI, - Ptr, PtrOffset); - } - } - continue; - } - - // Otherwise, insert the code in the User's block so it can be folded into - // any users in that block. - Value *V = InsertGEPComputeCode(InsertedExprs[User->getParent()], + + // If this use is not foldable into the addressing mode, use a version + // emitted in the GEP block. + Value *NewVal; + if (!isa(User) && + (!isa(User) || User->getOperand(0) == GEPI)) { + NewVal = InsertGEPComputeCode(InsertedExprs[DefBB], DefBB, GEPI, + Ptr, PtrOffset); + } else { + // Otherwise, insert the code in the User's block so it can be folded into + // any users in that block. + NewVal = InsertGEPComputeCode(InsertedExprs[User->getParent()], User->getParent(), GEPI, Ptr, PtrOffset); - User->replaceUsesOfWith(GEPI, V); } + User->replaceUsesOfWith(GEPI, NewVal); + } // Finally, the GEP is dead, remove it. GEPI->eraseFromParent();