VPBasicBlock::iterator InsertPt = VPBasicBlock::iterator();
VPInstruction *createInstruction(unsigned Opcode,
- ArrayRef<VPValue *> Operands) {
- VPInstruction *Instr = new VPInstruction(Opcode, Operands);
+ ArrayRef<VPValue *> Operands, DebugLoc DL) {
+ VPInstruction *Instr = new VPInstruction(Opcode, Operands, DL);
if (BB)
BB->insert(Instr, InsertPt);
return Instr;
}
VPInstruction *createInstruction(unsigned Opcode,
- std::initializer_list<VPValue *> Operands) {
- return createInstruction(Opcode, ArrayRef<VPValue *>(Operands));
+ std::initializer_list<VPValue *> Operands,
+ DebugLoc DL) {
+ return createInstruction(Opcode, ArrayRef<VPValue *>(Operands), DL);
}
public:
/// its underlying Instruction.
VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands,
Instruction *Inst = nullptr) {
- VPInstruction *NewVPInst = createInstruction(Opcode, Operands);
+ DebugLoc DL;
+ if (Inst)
+ DL = Inst->getDebugLoc();
+ VPInstruction *NewVPInst = createInstruction(Opcode, Operands, DL);
NewVPInst->setUnderlyingValue(Inst);
return NewVPInst;
}
+ VPValue *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands,
+ DebugLoc DL) {
+ return createInstruction(Opcode, Operands, DL);
+ }
- VPValue *createNot(VPValue *Operand) {
- return createInstruction(VPInstruction::Not, {Operand});
+ VPValue *createNot(VPValue *Operand, DebugLoc DL) {
+ return createInstruction(VPInstruction::Not, {Operand}, DL);
}
- VPValue *createAnd(VPValue *LHS, VPValue *RHS) {
- return createInstruction(Instruction::BinaryOps::And, {LHS, RHS});
+ VPValue *createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL) {
+ return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, DL);
}
- VPValue *createOr(VPValue *LHS, VPValue *RHS) {
- return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS});
+ VPValue *createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL) {
+ return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS}, DL);
}
- VPValue *createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal) {
- return createNaryOp(Instruction::Select, {Cond, TrueVal, FalseVal});
+ VPValue *createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal,
+ DebugLoc DL) {
+ return createNaryOp(Instruction::Select, {Cond, TrueVal, FalseVal}, DL);
}
//===--------------------------------------------------------------------===//
assert(EdgeMask && "No Edge Mask found for condition");
if (BI->getSuccessor(0) != Dst)
- EdgeMask = Builder.createNot(EdgeMask);
+ EdgeMask = Builder.createNot(EdgeMask, BI->getDebugLoc());
if (SrcMask) { // Otherwise block in-mask is all-one, no need to AND.
// The condition is 'SrcMask && EdgeMask', which is equivalent to
// EdgeMask is poison. Using 'and' here introduces undefined behavior.
VPValue *False = Plan->getOrAddVPValue(
ConstantInt::getFalse(BI->getCondition()->getType()));
- EdgeMask = Builder.createSelect(SrcMask, EdgeMask, False);
+ EdgeMask =
+ Builder.createSelect(SrcMask, EdgeMask, False, BI->getDebugLoc());
}
return EdgeMaskCache[Edge] = EdgeMask;
continue;
}
- BlockMask = Builder.createOr(BlockMask, EdgeMask);
+ BlockMask = Builder.createOr(BlockMask, EdgeMask, {});
}
return BlockMaskCache[BB] = BlockMask;
void VPInstruction::generateInstruction(VPTransformState &State,
unsigned Part) {
IRBuilder<> &Builder = State.Builder;
+ Builder.SetCurrentDebugLocation(DL);
if (Instruction::isBinaryOp(getOpcode())) {
Value *A = State.get(getOperand(0), Part);
O << " ";
Operand->printAsOperand(O, SlotTracker);
}
+
+ if (DL) {
+ O << ", !dbg ";
+ DL.print(O);
+ }
}
#endif
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/Analysis/VectorUtils.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/InstructionCost.h"
#include <algorithm>
typedef unsigned char OpcodeTy;
OpcodeTy Opcode;
FastMathFlags FMF;
+ DebugLoc DL;
/// Utility method serving execute(): generates a single instance of the
/// modeled instruction.
void setUnderlyingInstr(Instruction *I) { setUnderlyingValue(I); }
public:
- VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands)
+ VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands, DebugLoc DL)
: VPRecipeBase(VPRecipeBase::VPInstructionSC, Operands),
- VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode) {}
+ VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode),
+ DL(DL) {}
- VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands)
- : VPInstruction(Opcode, ArrayRef<VPValue *>(Operands)) {}
+ VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands,
+ DebugLoc DL = {})
+ : VPInstruction(Opcode, ArrayRef<VPValue *>(Operands), DL) {}
/// Method to support type inquiry through isa, cast, and dyn_cast.
static inline bool classof(const VPValue *V) {
VPInstruction *clone() const {
SmallVector<VPValue *, 2> Operands(operands());
- return new VPInstruction(Opcode, Operands);
+ return new VPInstruction(Opcode, Operands, DL);
}
/// Method to support type inquiry through isa, cast, and dyn_cast.
case EdgeType::FALSE_EDGE:
// CurrBB is the False successor of PredBB - compute not of CBV.
- IntermediateVal = Builder.createNot(CBV);
+ IntermediateVal = Builder.createNot(CBV, {});
break;
}
// Now AND intermediate value with PredBB's block predicate if it has one.
VPValue *BP = PredBB->getPredicate();
if (BP)
- return Builder.createAnd(BP, IntermediateVal);
+ return Builder.createAnd(BP, IntermediateVal, {});
else
return IntermediateVal;
}
Worklist.pop_front();
// Create an OR of these values.
- VPValue *Or = Builder.createOr(LHS, RHS);
+ VPValue *Or = Builder.createOr(LHS, RHS, {});
// Push OR to the back of the worklist.
Worklist.push_back(Or);
return markFailed();
assert(CombinedOperands.size() > 0 && "Need more some operands");
- auto *VPI = new VPInstruction(Opcode, CombinedOperands);
- VPI->setUnderlyingInstr(cast<VPInstruction>(Values[0])->getUnderlyingInstr());
+ auto *Inst = cast<VPInstruction>(Values[0])->getUnderlyingInstr();
+ auto *VPI = new VPInstruction(Opcode, CombinedOperands, Inst->getDebugLoc());
+ VPI->setUnderlyingInstr(Inst);
LLVM_DEBUG(dbgs() << "Create VPInstruction " << *VPI << " "
<< *cast<VPInstruction>(Values[0]) << "\n");
; CHECK: vector.body:
; CHECK: %[[CMP1:.+]] = icmp slt <2 x i32> %[[VAL:.+]], <i32 100, i32 100>
; CHECK: %[[CMP2:.+]] = icmp sge <2 x i32> %[[VAL]], <i32 200, i32 200>
-; CHECK: %[[NOT:.+]] = xor <2 x i1> %[[CMP1]], <i1 true, i1 true>
-; CHECK: %[[AND:.+]] = select <2 x i1> %[[NOT]], <2 x i1> %[[CMP2]], <2 x i1> zeroinitializer
-; CHECK-NOT: !dbg
+; CHECK: %[[NOT:.+]] = xor <2 x i1> %[[CMP1]], <i1 true, i1 true>, !dbg [[DBG1:![0-9]+]]
+; CHECK: %[[AND:.+]] = select <2 x i1> %[[NOT]], <2 x i1> %[[CMP2]], <2 x i1> zeroinitializer, !dbg [[DBG2:![0-9]+]]
; CHECK: %[[OR:.+]] = or <2 x i1> %[[AND]], %[[CMP1]]
-; CHECK-NOT: !dbg
; CHECK: %[[EXTRACT:.+]] = extractelement <2 x i1> %[[OR]], i32 0
; CHECK: br i1 %[[EXTRACT]], label %[[THEN:[a-zA-Z0-9.]+]], label %[[FI:[a-zA-Z0-9.]+]]
; CHECK: [[THEN]]:
!6 = !DISubroutineType(types: !2)
!7 = !DILocation(line: 5, column: 21, scope: !5)
!8 = !DILocation(line: 5, column: 3, scope: !5)
+
+
+; CHECK: [[DBG1]] = !DILocation(line: 5, column: 21, scope: !26)
+; CHECK-NEXT: [[DBG2]] = !DILocation(line: 5, column: 3, scope: !26)
; CHECK-NEXT: Successor(s): if.then
; CHECK-EMPTY:
; CHECK-NEXT: if.then:
-; CHECK-NEXT: EMIT vp<[[NOT1:%.+]]> = not ir<%cmp1>
-; CHECK-NOT: !dbg
-; CHECK-NEXT: EMIT vp<[[SEL1:%.+]]> = select vp<[[NOT1]]> ir<%cmp2> ir<false>
-; CHECK-NOT: !dbg
+; CHECK-NEXT: EMIT vp<[[NOT1:%.+]]> = not ir<%cmp1>, !dbg /tmp/s.c:5:3
+; CHECK-NEXT: EMIT vp<[[SEL1:%.+]]> = select vp<[[NOT1]]> ir<%cmp2> ir<false>, !dbg /tmp/s.c:5:21
; CHECK-NEXT: EMIT vp<[[OR1:%.+]]> = or vp<[[SEL1]]> ir<%cmp1>
; CHECK-NEXT: Successor(s): pred.sdiv
; CHECK-EMPTY: