[llvm] r313400 - [DebugInfo] Insert DW_OP_deref when spilling indirect DBG_VALUEs

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 18 16:11:13 PDT 2017


I've reverted in r313589 since this caused asserts in the Chromium
build (see http://crbug.com/766261).

On Fri, Sep 15, 2017 at 2:54 PM, Reid Kleckner via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: rnk
> Date: Fri Sep 15 14:54:38 2017
> New Revision: 313400
>
> URL: http://llvm.org/viewvc/llvm-project?rev=313400&view=rev
> Log:
> [DebugInfo] Insert DW_OP_deref when spilling indirect DBG_VALUEs
>
> Summary:
> This comes up in optimized debug info for C++ programs that pass and
> return objects indirectly by address. In these programs,
> llvm.dbg.declare survives optimization, which causes us to emit indirect
> DBG_VALUE instructions. The fast register allocator knows to insert
> DW_OP_deref when spilling indirect DBG_VALUE instructions, but the
> LiveDebugVariables did not until this change.
>
> This fixes part of PR34513. I need to look into why this doesn't work at
> -O0 and I'll send follow up patches to handle that.
>
> Reviewers: aprantl, dblaikie, probinson
>
> Subscribers: qcolombet, hiraditya, llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D37911
>
> Added:
>     llvm/trunk/test/DebugInfo/X86/spill-indirect-nrvo.ll
>     llvm/trunk/test/DebugInfo/X86/spill-nontrivial-param.ll
> Modified:
>     llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp
>     llvm/trunk/test/DebugInfo/X86/bbjoin.ll
>
> Modified: llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp?rev=313400&r1=313399&r2=313400&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp (original)
> +++ llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp Fri Sep 15 14:54:38 2017
> @@ -108,8 +108,8 @@ class LDVImpl;
>  /// held by the same virtual register. The equivalence class is the transitive
>  /// closure of that relation.
>  class UserValue {
> -  const MDNode *Variable;   ///< The debug info variable we are part of.
> -  const MDNode *Expression; ///< Any complex address expression.
> +  const DILocalVariable *Variable; ///< The debug info variable we are part of.
> +  const DIExpression *Expression; ///< Any complex address expression.
>    bool IsIndirect;        ///< true if this is a register-indirect+offset value.
>    DebugLoc dl;            ///< The debug location for the variable. This is
>                            ///< used by dwarf writer to find lexical scope.
> @@ -132,8 +132,9 @@ class UserValue {
>    void coalesceLocation(unsigned LocNo);
>
>    /// insertDebugValue - Insert a DBG_VALUE into MBB at Idx for LocNo.
> -  void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, unsigned LocNo,
> -                        LiveIntervals &LIS, const TargetInstrInfo &TII);
> +  void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,
> +                        unsigned LocNo, bool Spilled, LiveIntervals &LIS,
> +                        const TargetInstrInfo &TII);
>
>    /// splitLocation - Replace OldLocNo ranges with NewRegs ranges where NewRegs
>    /// is live. Returns true if any changes were made.
> @@ -142,8 +143,8 @@ class UserValue {
>
>  public:
>    /// UserValue - Create a new UserValue.
> -  UserValue(const MDNode *var, const MDNode *expr, bool i, DebugLoc L,
> -            LocMap::Allocator &alloc)
> +  UserValue(const DILocalVariable *var, const DIExpression *expr, bool i,
> +            DebugLoc L, LocMap::Allocator &alloc)
>        : Variable(var), Expression(expr), IsIndirect(i), dl(std::move(L)),
>          leader(this), locInts(alloc) {}
>
> @@ -159,8 +160,8 @@ public:
>    UserValue *getNext() const { return next; }
>
>    /// match - Does this UserValue match the parameters?
> -  bool match(const MDNode *Var, const MDNode *Expr, const DILocation *IA,
> -             bool indirect) const {
> +  bool match(const DILocalVariable *Var, const DIExpression *Expr,
> +             const DILocation *IA, bool indirect) const {
>      return Var == Variable && Expr == Expression && dl->getInlinedAt() == IA &&
>             indirect == IsIndirect;
>    }
> @@ -262,12 +263,14 @@ public:
>                       LiveIntervals &LIS);
>
>    /// rewriteLocations - Rewrite virtual register locations according to the
> -  /// provided virtual register map.
> -  void rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI);
> +  /// provided virtual register map. Record which locations were spilled.
> +  void rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI,
> +                        BitVector &SpilledLocations);
>
>    /// emitDebugValues - Recreate DBG_VALUE instruction from data structures.
> -  void emitDebugValues(VirtRegMap *VRM,
> -                       LiveIntervals &LIS, const TargetInstrInfo &TRI);
> +  void emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
> +                       const TargetInstrInfo &TRI,
> +                       const BitVector &SpilledLocations);
>
>    /// getDebugLoc - Return DebugLoc of this UserValue.
>    DebugLoc getDebugLoc() { return dl;}
> @@ -297,11 +300,11 @@ class LDVImpl {
>    VRMap virtRegToEqClass;
>
>    /// Map user variable to eq class leader.
> -  using UVMap = DenseMap<const MDNode *, UserValue *>;
> +  using UVMap = DenseMap<const DILocalVariable *, UserValue *>;
>    UVMap userVarMap;
>
>    /// getUserValue - Find or create a UserValue.
> -  UserValue *getUserValue(const MDNode *Var, const MDNode *Expr,
> +  UserValue *getUserValue(const DILocalVariable *Var, const DIExpression *Expr,
>                            bool IsIndirect, const DebugLoc &DL);
>
>    /// lookupVirtReg - Find the EC leader for VirtReg or null.
> @@ -454,8 +457,9 @@ void UserValue::mapVirtRegs(LDVImpl *LDV
>        LDV->mapVirtReg(locations[i].getReg(), this);
>  }
>
> -UserValue *LDVImpl::getUserValue(const MDNode *Var, const MDNode *Expr,
> -                                 bool IsIndirect, const DebugLoc &DL) {
> +UserValue *LDVImpl::getUserValue(const DILocalVariable *Var,
> +                                 const DIExpression *Expr, bool IsIndirect,
> +                                 const DebugLoc &DL) {
>    UserValue *&Leader = userVarMap[Var];
>    if (Leader) {
>      UserValue *UV = Leader->getLeader();
> @@ -494,11 +498,11 @@ bool LDVImpl::handleDebugValue(MachineIn
>    }
>
>    // Get or create the UserValue for (variable,offset).
> -  bool IsIndirect = MI.isIndirectDebugValue();
> +  bool IsIndirect = MI.getOperand(1).isImm();
>    if (IsIndirect)
>      assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset");
> -  const MDNode *Var = MI.getDebugVariable();
> -  const MDNode *Expr = MI.getDebugExpression();
> +  const DILocalVariable *Var = MI.getDebugVariable();
> +  const DIExpression *Expr = MI.getDebugExpression();
>    //here.
>    UserValue *UV = getUserValue(Var, Expr, IsIndirect, MI.getDebugLoc());
>    UV->addDef(Idx, MI.getOperand(0));
> @@ -971,8 +975,10 @@ splitRegister(unsigned OldReg, ArrayRef<
>      static_cast<LDVImpl*>(pImpl)->splitRegister(OldReg, NewRegs);
>  }
>
> -void
> -UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI) {
> +void UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI,
> +                                 BitVector &SpilledLocations) {
> +  SpilledLocations.resize(locations.size());
> +
>    // Iterate over locations in reverse makes it easier to handle coalescing.
>    for (unsigned i = locations.size(); i ; --i) {
>      unsigned LocNo = i-1;
> @@ -991,6 +997,7 @@ UserValue::rewriteLocations(VirtRegMap &
>      } else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT) {
>        // FIXME: Translate SubIdx to a stackslot offset.
>        Loc = MachineOperand::CreateFI(VRM.getStackSlot(VirtReg));
> +      SpilledLocations.set(LocNo);
>      } else {
>        Loc.setReg(0);
>        Loc.setSubReg(0);
> @@ -1024,7 +1031,7 @@ findInsertLocation(MachineBasicBlock *MB
>  }
>
>  void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,
> -                                 unsigned LocNo,
> +                                 unsigned LocNo, bool Spilled,
>                                   LiveIntervals &LIS,
>                                   const TargetInstrInfo &TII) {
>    MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, LIS);
> @@ -1034,25 +1041,35 @@ void UserValue::insertDebugValue(Machine
>    assert(cast<DILocalVariable>(Variable)
>               ->isValidLocationForIntrinsic(getDebugLoc()) &&
>           "Expected inlined-at fields to agree");
> -  if (Loc.isReg())
> -    BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE),
> -            IsIndirect, Loc.getReg(), Variable, Expression);
> +
> +  // If the location was spilled, the new DBG_VALUE will be indirect. If the
> +  // original DBG_VALUE was indirect, we need to add DW_OP_deref to indicate
> +  // that the original virtual register was a pointer.
> +  bool NewIndirect = IsIndirect || Spilled;
> +  const DIExpression *Expr = Expression;
> +  if (Spilled && IsIndirect)
> +    Expr = DIExpression::prepend(Expr, DIExpression::WithDeref);
> +
> +  MachineInstrBuilder MIB =
> +      BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE))
> +          .add(Loc);
> +  if (NewIndirect)
> +    MIB.addImm(0U);
>    else
> -    BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE))
> -        .add(Loc)
> -        .addImm(0U)
> -        .addMetadata(Variable)
> -        .addMetadata(Expression);
> +    MIB.addReg(0U, RegState::Debug);
> +  MIB.addMetadata(Variable).addMetadata(Expr);
>  }
>
>  void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
> -                                const TargetInstrInfo &TII) {
> +                                const TargetInstrInfo &TII,
> +                                const BitVector &SpilledLocations) {
>    MachineFunction::iterator MFEnd = VRM->getMachineFunction().end();
>
>    for (LocMap::const_iterator I = locInts.begin(); I.valid();) {
>      SlotIndex Start = I.start();
>      SlotIndex Stop = I.stop();
>      unsigned LocNo = I.value();
> +    bool Spilled = LocNo != ~0U ? SpilledLocations.test(LocNo) : false;
>
>      // If the interval start was trimmed to the lexical scope insert the
>      // DBG_VALUE at the previous index (otherwise it appears after the
> @@ -1065,7 +1082,7 @@ void UserValue::emitDebugValues(VirtRegM
>      SlotIndex MBBEnd = LIS.getMBBEndIdx(&*MBB);
>
>      DEBUG(dbgs() << " BB#" << MBB->getNumber() << '-' << MBBEnd);
> -    insertDebugValue(&*MBB, Start, LocNo, LIS, TII);
> +    insertDebugValue(&*MBB, Start, LocNo, Spilled, LIS, TII);
>      // This interval may span multiple basic blocks.
>      // Insert a DBG_VALUE into each one.
>      while(Stop > MBBEnd) {
> @@ -1075,7 +1092,7 @@ void UserValue::emitDebugValues(VirtRegM
>          break;
>        MBBEnd = LIS.getMBBEndIdx(&*MBB);
>        DEBUG(dbgs() << " BB#" << MBB->getNumber() << '-' << MBBEnd);
> -      insertDebugValue(&*MBB, Start, LocNo, LIS, TII);
> +      insertDebugValue(&*MBB, Start, LocNo, Spilled, LIS, TII);
>      }
>      DEBUG(dbgs() << '\n');
>      if (MBB == MFEnd)
> @@ -1090,10 +1107,11 @@ void LDVImpl::emitDebugValues(VirtRegMap
>    if (!MF)
>      return;
>    const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
> +  BitVector SpilledLocations;
>    for (unsigned i = 0, e = userValues.size(); i != e; ++i) {
>      DEBUG(userValues[i]->print(dbgs(), TRI));
> -    userValues[i]->rewriteLocations(*VRM, *TRI);
> -    userValues[i]->emitDebugValues(VRM, *LIS, *TII);
> +    userValues[i]->rewriteLocations(*VRM, *TRI, SpilledLocations);
> +    userValues[i]->emitDebugValues(VRM, *LIS, *TII, SpilledLocations);
>    }
>    EmitDone = true;
>  }
>
> Modified: llvm/trunk/test/DebugInfo/X86/bbjoin.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/bbjoin.ll?rev=313400&r1=313399&r2=313400&view=diff
> ==============================================================================
> --- llvm/trunk/test/DebugInfo/X86/bbjoin.ll (original)
> +++ llvm/trunk/test/DebugInfo/X86/bbjoin.ll Fri Sep 15 14:54:38 2017
> @@ -11,12 +11,12 @@
>  ; }
>  ; CHECK: ![[X:.*]] = !DILocalVariable(name: "x",
>  ; CHECK: bb.0.entry:
> -; CHECK:   DBG_VALUE 23, 0, ![[X]],
> +; CHECK:   DBG_VALUE 23, debug-use _, ![[X]],
>  ; CHECK:   DBG_VALUE %rsp, 0, ![[X]], !DIExpression(DW_OP_plus_uconst, 4, DW_OP_deref),
>  ; CHECK: bb.1.if.then:
> -; CHECK:   DBG_VALUE 43, 0, ![[X]],
> +; CHECK:   DBG_VALUE 43, debug-use _, ![[X]],
>  ; CHECK: bb.2.if.end:
> -; CHECK-NOT:  DBG_VALUE 23, 0, ![[X]],
> +; CHECK-NOT:  DBG_VALUE 23, debug-use _, ![[X]],
>  ; CHECK:   RETQ %eax
>
>  target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>
> Added: llvm/trunk/test/DebugInfo/X86/spill-indirect-nrvo.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/spill-indirect-nrvo.ll?rev=313400&view=auto
> ==============================================================================
> --- llvm/trunk/test/DebugInfo/X86/spill-indirect-nrvo.ll (added)
> +++ llvm/trunk/test/DebugInfo/X86/spill-indirect-nrvo.ll Fri Sep 15 14:54:38 2017
> @@ -0,0 +1,103 @@
> +; RUN: llc < %s | FileCheck %s
> +; RUN: llc -O0 < %s | FileCheck %s
> +
> +; Make sure we insert DW_OP_deref when spilling indirect DBG_VALUE instructions.
> +
> +; C++ source:
> +; #define FORCE_SPILL() \
> +;   __asm volatile("" : : : \
> +;                    "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "r8", \
> +;                    "r9", "r10", "r11", "r12", "r13", "r14", "r15")
> +; struct string {
> +;   string();
> +;   string(int i);
> +;   ~string();
> +;   int i = 0;
> +; };
> +; string get_string() {
> +;   string result = 3;
> +;   FORCE_SPILL();
> +;   return result;
> +; }
> +
> +; CHECK-LABEL: _Z10get_stringv:
> +; CHECK: #DEBUG_VALUE: get_string:result <- [%RDI+0]
> +; CHECK: movq   %rdi, [[OFFS:[0-9]+]](%rsp)          # 8-byte Spill
> +; CHECK: #DEBUG_VALUE: get_string:result <- [DW_OP_plus_uconst [[OFFS]], DW_OP_deref] [%RSP+0]
> +; CHECK: callq  _ZN6stringC1Ei
> +; CHECK: #APP
> +; CHECK: #NO_APP
> +
> +; ModuleID = 't.cpp'
> +source_filename = "t.cpp"
> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64--linux"
> +
> +%struct.string = type { i32 }
> +
> +; Function Attrs: uwtable
> +define void @_Z10get_stringv(%struct.string* noalias sret %agg.result) #0 !dbg !7 {
> +entry:
> +  %nrvo = alloca i1, align 1
> +  store i1 false, i1* %nrvo, align 1, !dbg !24
> +  call void @llvm.dbg.declare(metadata %struct.string* %agg.result, metadata !23, metadata !DIExpression()), !dbg !25
> +  call void @_ZN6stringC1Ei(%struct.string* %agg.result, i32 3), !dbg !26
> +  call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"() #3, !dbg !27, !srcloc !28
> +  store i1 true, i1* %nrvo, align 1, !dbg !29
> +  %nrvo.val = load i1, i1* %nrvo, align 1, !dbg !30
> +  br i1 %nrvo.val, label %nrvo.skipdtor, label %nrvo.unused, !dbg !30
> +
> +nrvo.unused:                                      ; preds = %entry
> +  call void @_ZN6stringD1Ev(%struct.string* %agg.result), !dbg !30
> +  br label %nrvo.skipdtor, !dbg !30
> +
> +nrvo.skipdtor:                                    ; preds = %nrvo.unused, %entry
> +  ret void, !dbg !30
> +}
> +
> +; Function Attrs: nounwind readnone speculatable
> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
> +
> +declare void @_ZN6stringC1Ei(%struct.string*, i32) unnamed_addr
> +
> +declare void @_ZN6stringD1Ev(%struct.string*) unnamed_addr
> +
> +attributes #0 = { uwtable }
> +attributes #1 = { nounwind readnone speculatable }
> +attributes #3 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!3, !4, !5}
> +!llvm.ident = !{!6}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
> +!1 = !DIFile(filename: "t.cpp", directory: "C:\5Csrc\5Cllvm-project\5Cbuild")
> +!2 = !{}
> +!3 = !{i32 2, !"Dwarf Version", i32 4}
> +!4 = !{i32 2, !"Debug Info Version", i32 3}
> +!5 = !{i32 1, !"wchar_size", i32 4}
> +!6 = !{!"clang version 6.0.0 "}
> +!7 = distinct !DISubprogram(name: "get_string", linkageName: "_Z10get_stringv", scope: !1, file: !1, line: 13, type: !8, isLocal: false, isDefinition: true, scopeLine: 13, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !22)
> +!8 = !DISubroutineType(types: !9)
> +!9 = !{!10}
> +!10 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "string", file: !1, line: 7, size: 32, elements: !11, identifier: "_ZTS6string")
> +!11 = !{!12, !14, !18, !21}
> +!12 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !10, file: !1, line: 11, baseType: !13, size: 32)
> +!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
> +!14 = !DISubprogram(name: "string", scope: !10, file: !1, line: 8, type: !15, isLocal: false, isDefinition: false, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true)
> +!15 = !DISubroutineType(types: !16)
> +!16 = !{null, !17}
> +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
> +!18 = !DISubprogram(name: "string", scope: !10, file: !1, line: 9, type: !19, isLocal: false, isDefinition: false, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true)
> +!19 = !DISubroutineType(types: !20)
> +!20 = !{null, !17, !13}
> +!21 = !DISubprogram(name: "~string", scope: !10, file: !1, line: 10, type: !15, isLocal: false, isDefinition: false, scopeLine: 10, flags: DIFlagPrototyped, isOptimized: true)
> +!22 = !{!23}
> +!23 = !DILocalVariable(name: "result", scope: !7, file: !1, line: 14, type: !10)
> +!24 = !DILocation(line: 14, column: 3, scope: !7)
> +!25 = !DILocation(line: 14, column: 10, scope: !7)
> +!26 = !DILocation(line: 14, column: 19, scope: !7)
> +!27 = !DILocation(line: 15, column: 3, scope: !7)
> +!28 = !{i32 -2147471175}
> +!29 = !DILocation(line: 16, column: 3, scope: !7)
> +!30 = !DILocation(line: 17, column: 1, scope: !7)
>
> Added: llvm/trunk/test/DebugInfo/X86/spill-nontrivial-param.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/spill-nontrivial-param.ll?rev=313400&view=auto
> ==============================================================================
> --- llvm/trunk/test/DebugInfo/X86/spill-nontrivial-param.ll (added)
> +++ llvm/trunk/test/DebugInfo/X86/spill-nontrivial-param.ll Fri Sep 15 14:54:38 2017
> @@ -0,0 +1,89 @@
> +; RUN: llc < %s | FileCheck %s
> +
> +; Make sure we insert DW_OP_deref when spilling indirect DBG_VALUE instructions.
> +; In this example, 'nt' is passed by address because it is not trivially
> +; copyable. When we spill the physical argument register at the barrier, we need
> +; to insert DW_OP_deref.
> +
> +; #define FORCE_SPILL() \
> +;   __asm volatile("" : : : \
> +;                    "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "r8", \
> +;                    "r9", "r10", "r11", "r12", "r13", "r14", "r15")
> +; struct NonTrivial {
> +;   NonTrivial();
> +;   ~NonTrivial();
> +;   int i;
> +; };
> +; int foo(NonTrivial nt) {
> +;   FORCE_SPILL();
> +;   return nt.i;
> +; }
> +
> +; CHECK-LABEL: _Z3foo10NonTrivial:
> +; CHECK: #DEBUG_VALUE: foo:nt <- [%RDI+0]
> +; CHECK: movq    %rdi, -8(%rsp)          # 8-byte Spill
> +; CHECK: #DEBUG_VALUE: foo:nt <- [DW_OP_constu 8, DW_OP_minus, DW_OP_deref] [%RSP+0]
> +; CHECK: #APP
> +; CHECK: #NO_APP
> +; CHECK: movq    -8(%rsp), %rax          # 8-byte Reload
> +; CHECK: movl    (%rax), %eax
> +
> +; ModuleID = 't.cpp'
> +source_filename = "t.cpp"
> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64--linux"
> +
> +%struct.NonTrivial = type { i32 }
> +
> +; Function Attrs: nounwind uwtable
> +define i32 @_Z3foo10NonTrivial(%struct.NonTrivial* nocapture readonly %nt) local_unnamed_addr #0 !dbg !7 {
> +entry:
> +  tail call void @llvm.dbg.declare(metadata %struct.NonTrivial* %nt, metadata !20, metadata !DIExpression()), !dbg !21
> +  tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"() #2, !dbg !22, !srcloc !23
> +  %i = getelementptr inbounds %struct.NonTrivial, %struct.NonTrivial* %nt, i64 0, i32 0, !dbg !24
> +  %0 = load i32, i32* %i, align 4, !dbg !24, !tbaa !25
> +  ret i32 %0, !dbg !30
> +}
> +
> +; Function Attrs: nounwind readnone speculatable
> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
> +
> +attributes #0 = { nounwind uwtable }
> +attributes #1 = { nounwind readnone speculatable }
> +attributes #2 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!3, !4, !5}
> +!llvm.ident = !{!6}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
> +!1 = !DIFile(filename: "t.cpp", directory: "C:\5Csrc\5Cllvm-project\5Cbuild")
> +!2 = !{}
> +!3 = !{i32 2, !"Dwarf Version", i32 4}
> +!4 = !{i32 2, !"Debug Info Version", i32 3}
> +!5 = !{i32 1, !"wchar_size", i32 4}
> +!6 = !{!"clang version 6.0.0 "}
> +!7 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foo10NonTrivial", scope: !1, file: !1, line: 10, type: !8, isLocal: false, isDefinition: true, scopeLine: 10, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !19)
> +!8 = !DISubroutineType(types: !9)
> +!9 = !{!10, !11}
> +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
> +!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "NonTrivial", file: !1, line: 5, size: 32, elements: !12, identifier: "_ZTS10NonTrivial")
> +!12 = !{!13, !14, !18}
> +!13 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !11, file: !1, line: 8, baseType: !10, size: 32)
> +!14 = !DISubprogram(name: "NonTrivial", scope: !11, file: !1, line: 6, type: !15, isLocal: false, isDefinition: false, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: true)
> +!15 = !DISubroutineType(types: !16)
> +!16 = !{null, !17}
> +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
> +!18 = !DISubprogram(name: "~NonTrivial", scope: !11, file: !1, line: 7, type: !15, isLocal: false, isDefinition: false, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: true)
> +!19 = !{!20}
> +!20 = !DILocalVariable(name: "nt", arg: 1, scope: !7, file: !1, line: 10, type: !11)
> +!21 = !DILocation(line: 10, column: 20, scope: !7)
> +!22 = !DILocation(line: 11, column: 3, scope: !7)
> +!23 = !{i32 -2147471481}
> +!24 = !DILocation(line: 12, column: 13, scope: !7)
> +!25 = !{!26, !27, i64 0}
> +!26 = !{!"_ZTS10NonTrivial", !27, i64 0}
> +!27 = !{!"int", !28, i64 0}
> +!28 = !{!"omnipotent char", !29, i64 0}
> +!29 = !{!"Simple C++ TBAA"}
> +!30 = !DILocation(line: 12, column: 3, scope: !7)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list