Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -1224,6 +1224,17 @@ /// IR. This side-table holds the missing use edges. DenseMap DbgDeclares; + struct Piece { + AllocaInst *Alloca; + uint64_t Offset; + uint64_t Size; + Piece(AllocaInst *AI, uint64_t O, uint64_t S) + : Alloca(AI), Offset(O), Size(S) {} + }; + /// \brief Describes the allocas introduced by rewritePartition in order to + /// migrate the debug info. + std::vector Pieces; + public: SROA(bool RequiresDomTree = true) : FunctionPass(ID), RequiresDomTree(RequiresDomTree), C(nullptr), @@ -3498,26 +3509,8 @@ AI.getName() + ".sroa." + Twine(P.begin() - AS.begin()), &AI); ++NumNewAllocas; - // Migrate debug information from the old alloca to the new alloca - // and the individial slices. - if (DbgDeclareInst *DbgDecl = DbgDeclares.lookup(&AI)) { - DIVariable Var(DbgDecl->getVariable()); - DIExpression Piece; - DIBuilder DIB(*AI.getParent()->getParent()->getParent(), - /*AllowUnresolved*/ false); - // Create a piece expression describing the slice, if the new slize is - // smaller than the old alloca or the old alloca already was described - // with a piece. It would be even better to just compare against the size - // of the type described in the debug info, but then we would need to - // build an expensive DIRefMap. - if (P.size() < DL->getTypeAllocSize(AI.getAllocatedType()) || - DIExpression(DbgDecl->getExpression()).isVariablePiece()) - Piece = DIB.createPieceExpression(P.beginOffset(), P.size()); - Instruction *NewDDI = DIB.insertDeclare(NewAI, Var, Piece, &AI); - NewDDI->setDebugLoc(DbgDecl->getDebugLoc()); - DbgDeclares.insert(std::make_pair(NewAI, cast(NewDDI))); - DeadInsts.insert(DbgDecl); - } + // Remember the alloca so we can update the debug info for it. + Pieces.push_back( Piece(NewAI, P.beginOffset(), P.size()) ); } DEBUG(dbgs() << "Rewriting alloca partition " @@ -3611,6 +3604,7 @@ unsigned NumPartitions = 0; bool Changed = false; + Pieces.clear(); // Rewrite each parttion. for (auto &P : AS.partitions()) { @@ -3622,6 +3616,26 @@ MaxPartitionsPerAlloca = std::max(NumPartitions, MaxPartitionsPerAlloca); + // Migrate debug information from the old alloca to the new alloca(s) + // and the individial partitions. + if (DbgDeclareInst *DbgDecl = DbgDeclares.lookup(&AI)) { + DIVariable Var(DbgDecl->getVariable()); + DIExpression Expr(DbgDecl->getExpression()); + DIBuilder DIB(*AI.getParent()->getParent()->getParent(), + /*AllowUnresolved*/ false); + bool didSplit = Pieces.size() > 1; + for (auto Piece : Pieces) { + // Create a piece expression describing the new partition or reuse AI's + // expression if there is only one partition. + if (didSplit) + Expr = DIB.createPieceExpression(Piece.Offset, Piece.Size); + Instruction *NewDDI = DIB.insertDeclare(Piece.Alloca, Var, Expr, &AI); + NewDDI->setDebugLoc(DbgDecl->getDebugLoc()); + DbgDeclares.insert(std::make_pair(Piece.Alloca, + cast(NewDDI))); + DeadInsts.insert(DbgDecl); + } + } return Changed; }