diff options
Diffstat (limited to 'llvm/lib/Transforms/Vectorize/LoopVectorize.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 75 | 
1 files changed, 74 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 579f20f181b..5a37c0e1b49 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -326,6 +326,49 @@ private:    EdgeMaskCache MaskCache;  }; +/// \brief Set/reset the debug location in the IR builder using the RAII idiom. +class DebugLocSetter { +  IRBuilder<> &Builder; +  DebugLoc OldDL; + +  DebugLocSetter(const DebugLocSetter&); +  DebugLocSetter &operator=(const DebugLocSetter&); + +public: +  /// \brief Set the debug location in the IRBuilder 'B' using the instruction +  /// 'Inst'. +  DebugLocSetter(IRBuilder<> &B, Instruction *Inst) : Builder(B) { +    OldDL = Builder.getCurrentDebugLocation(); +    // Handle null instructions gracefully. This is so we can use a dyn_cast on +    // values without nowing it is an instruction. +    if (Inst) +      Builder.SetCurrentDebugLocation(Inst->getDebugLoc()); +  } + +  ~DebugLocSetter() { +    Builder.SetCurrentDebugLocation(OldDL); +  } +}; + +/// \brief Look for a meaningful debug location on the instruction or it's +/// operands. +static Instruction *getDebugLocFromInstOrOperands(Instruction *I) { +  if (!I) +    return I; + +  DebugLoc Empty; +  if (I->getDebugLoc() != Empty) +    return I; + +  for (User::op_iterator OI = I->op_begin(), OE = I->op_end(); OI != OE; ++OI) { +    if (Instruction *OpInst = dyn_cast<Instruction>(*OI)) +      if (OpInst->getDebugLoc() != Empty) +        return OpInst; +  } + +  return I; +} +  /// \brief Check if conditionally executed loads are hoistable.  ///  /// This class has two functions: isHoistableLoad and canHoistAllLoads. @@ -1195,6 +1238,7 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr,    // Handle consecutive loads/stores.    GetElementPtrInst *Gep = dyn_cast<GetElementPtrInst>(Ptr);    if (Gep && Legal->isInductionVariable(Gep->getPointerOperand())) { +    DebugLocSetter SetDL(Builder, Gep);      Value *PtrOperand = Gep->getPointerOperand();      Value *FirstBasePtr = getVectorValue(PtrOperand)[0];      FirstBasePtr = Builder.CreateExtractElement(FirstBasePtr, Zero); @@ -1205,6 +1249,7 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr,      Gep2->setName("gep.indvar.base");      Ptr = Builder.Insert(Gep2);    } else if (Gep) { +    DebugLocSetter SetDL(Builder, Gep);      assert(SE->isLoopInvariant(SE->getSCEV(Gep->getPointerOperand()),                                 OrigLoop) && "Base ptr must be invariant"); @@ -1237,6 +1282,7 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr,    } else {      // Use the induction element ptr.      assert(isa<PHINode>(Ptr) && "Invalid induction ptr"); +    DebugLocSetter SetDL(Builder, cast<Instruction>(Ptr));      VectorParts &PtrVal = getVectorValue(Ptr);      Ptr = Builder.CreateExtractElement(PtrVal[0], Zero);    } @@ -1245,6 +1291,7 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr,    if (SI) {      assert(!Legal->isUniform(SI->getPointerOperand()) &&             "We do not allow storing to uniform addresses"); +    DebugLocSetter SetDL(Builder, SI);      // We don't want to update the value in the map as it might be used in      // another expression. So don't use a reference type for "StoredVal".      VectorParts StoredVal = getVectorValue(SI->getValueOperand()); @@ -1269,6 +1316,9 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr,      return;    } +  // Handle loads. +  assert(LI && "Must have a load instruction"); +  DebugLocSetter SetDL(Builder, LI);    for (unsigned Part = 0; Part < UF; ++Part) {      // Calculate the pointer for the specific unroll-part.      Value *PartPtr = Builder.CreateGEP(Ptr, Builder.getInt32(Part * VF)); @@ -1292,6 +1342,8 @@ void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr) {    // Holds vector parameters or scalars, in case of uniform vals.    SmallVector<VectorParts, 4> Params; +  DebugLocSetter SetDL(Builder, Instr); +    // Find all of the vectorized parameters.    for (unsigned op = 0, e = Instr->getNumOperands(); op != e; ++op) {      Value *SrcOp = Instr->getOperand(op); @@ -1519,6 +1571,7 @@ InnerLoopVectorizer::createEmptyLoop(LoopVectorizationLegality *Legal) {    Builder.SetInsertPoint(VecBody->getFirstInsertionPt());    // Generate the induction variable. +  DebugLocSetter SetDL(Builder, getDebugLocFromInstOrOperands(OldInduction));    Induction = Builder.CreatePHI(IdxTy, 2, "index");    // The loop step is equal to the vectorization factor (num of SIMD elements)    // times the unroll factor (num of SIMD instructions). @@ -1527,6 +1580,8 @@ InnerLoopVectorizer::createEmptyLoop(LoopVectorizationLegality *Legal) {    // This is the IR builder that we use to add all of the logic for bypassing    // the new vector loop.    IRBuilder<> BypassBuilder(BypassBlock->getTerminator()); +  DebugLocSetter SetDLByPass(BypassBuilder, +                             getDebugLocFromInstOrOperands(OldInduction));    // We may need to extend the index in case there is a type mismatch.    // We know that the count starts at zero and does not overflow. @@ -2066,6 +2121,8 @@ InnerLoopVectorizer::vectorizeLoop(LoopVectorizationLegality *Legal) {      for (unsigned part = 0; part < UF; ++part) {        // This PHINode contains the vectorized reduction variable, or        // the initial value vector, if we bypass the vector loop. +      DebugLocSetter SetDL(Builder, RdxDesc.LoopExitInstr); +        VectorParts &RdxExitVal = getVectorValue(RdxDesc.LoopExitInstr);        PHINode *NewPhi = Builder.CreatePHI(VecTy, 2, "rdx.vec.exit.phi");        Value *StartVal = (part == 0) ? VectorStart : Identity; @@ -2079,6 +2136,8 @@ InnerLoopVectorizer::vectorizeLoop(LoopVectorizationLegality *Legal) {      Value *ReducedPartRdx = RdxParts[0];      unsigned Op = getReductionBinOp(RdxDesc.Kind);      for (unsigned part = 1; part < UF; ++part) { +      DebugLocSetter SetDL(Builder, dyn_cast<Instruction>(RdxParts[part])); +        if (Op != Instruction::ICmp && Op != Instruction::FCmp)          ReducedPartRdx = Builder.CreateBinOp((Instruction::BinaryOps)Op,                                               RdxParts[part], ReducedPartRdx, @@ -2096,6 +2155,7 @@ InnerLoopVectorizer::vectorizeLoop(LoopVectorizationLegality *Legal) {      Value *TmpVec = ReducedPartRdx;      SmallVector<Constant*, 32> ShuffleMask(VF, 0);      for (unsigned i = VF; i != 1; i >>= 1) { +      DebugLocSetter SetDL(Builder, dyn_cast<Instruction>(ReducedPartRdx));        // Move the upper half of the vector to the lower half.        for (unsigned j = 0; j != i/2; ++j)          ShuffleMask[j] = Builder.getInt32(i/2 + j); @@ -2118,7 +2178,11 @@ InnerLoopVectorizer::vectorizeLoop(LoopVectorizationLegality *Legal) {      }      // The result is in the first element of the vector. -    Value *Scalar0 = Builder.CreateExtractElement(TmpVec, Builder.getInt32(0)); +    Value *Scalar0; +    { +      DebugLocSetter SetDL(Builder, dyn_cast<Instruction>(ReducedPartRdx)); +      Scalar0 = Builder.CreateExtractElement(TmpVec, Builder.getInt32(0)); +    }      // Now, we need to fix the users of the reduction variable      // inside and outside of the scalar remainder loop. @@ -2253,6 +2317,7 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal,        // Check for PHI nodes that are lowered to vector selects.        if (P->getParent() != OrigLoop->getHeader()) { +        DebugLocSetter SetDL(Builder, P);          // We know that all PHIs in non header blocks are converted into          // selects, so we don't have to worry about the insertion order and we          // can just use the builder. @@ -2295,6 +2360,8 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal,        LoopVectorizationLegality::InductionInfo II =          Legal->getInductionVars()->lookup(P); +      DebugLocSetter SetDL(Builder, P); +        switch (II.IK) {        case LoopVectorizationLegality::IK_NoInduction:          llvm_unreachable("Unknown induction"); @@ -2402,6 +2469,7 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal,      case Instruction::Xor: {        // Just widen binops.        BinaryOperator *BinOp = dyn_cast<BinaryOperator>(it); +      DebugLocSetter SetDL(Builder, BinOp);        VectorParts &A = getVectorValue(it->getOperand(0));        VectorParts &B = getVectorValue(it->getOperand(1)); @@ -2428,6 +2496,7 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal,        // instruction with a scalar condition. Otherwise, use vector-select.        bool InvariantCond = SE->isLoopInvariant(SE->getSCEV(it->getOperand(0)),                                                 OrigLoop); +      DebugLocSetter SetDL(Builder, it);        // The condition can be loop invariant  but still defined inside the        // loop. This means that we can't just use the original 'cond' value. @@ -2452,6 +2521,7 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal,        // Widen compares. Generate vector compares.        bool FCmp = (it->getOpcode() == Instruction::FCmp);        CmpInst *Cmp = dyn_cast<CmpInst>(it); +      DebugLocSetter SetDL(Builder, it);        VectorParts &A = getVectorValue(it->getOperand(0));        VectorParts &B = getVectorValue(it->getOperand(1));        for (unsigned Part = 0; Part < UF; ++Part) { @@ -2482,6 +2552,7 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal,      case Instruction::FPTrunc:      case Instruction::BitCast: {        CastInst *CI = dyn_cast<CastInst>(it); +      DebugLocSetter SetDL(Builder, it);        /// Optimize the special case where the source is the induction        /// variable. Notice that we can only optimize the 'trunc' case        /// because: a. FP conversions lose precision, b. sext/zext may wrap, @@ -2509,6 +2580,8 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal,        if (isa<DbgInfoIntrinsic>(it))          break; +      DebugLocSetter SetDL(Builder, it); +        Module *M = BB->getParent()->getParent();        CallInst *CI = cast<CallInst>(it);        Intrinsic::ID ID = getIntrinsicIDForCall(CI, TLI);  | 

