[llvm] r260746 - [codeview] Describe local variables in registers

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 15 10:11:06 PST 2016


No, offset is negative when rbp is used. I'm not sure the bitfield will
pack in MSVC if you change the bool to unsigned.

Sent from phone
On Fri, Feb 12, 2016 at 4:48 PM, Reid Kleckner via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: rnk
> Date: Fri Feb 12 15:48:30 2016
> New Revision: 260746
>
> URL: http://llvm.org/viewvc/llvm-project?rev=260746&view=rev
> Log:
> [codeview] Describe local variables in registers
>
> Added:
>     llvm/trunk/test/DebugInfo/COFF/register-variables.ll
> Modified:
>     llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
> URL:
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=260746&r1=260745&r2=260746&view=diff
>
==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Fri Feb 12
15:48:30 2016
> @@ -105,18 +105,32 @@ unsigned CodeViewDebug::maybeRecordFile(
>    return Insertion.first->second;
>  }
>
> -CodeViewDebug::InlineSite &CodeViewDebug::getInlineSite(const DILocation
*Loc) {
> -  const DILocation *InlinedAt = Loc->getInlinedAt();
> +CodeViewDebug::InlineSite &
> +CodeViewDebug::getInlineSite(const DILocation *InlinedAt,
> +                             const DISubprogram *Inlinee) {
>    auto Insertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()});
>    InlineSite *Site = &Insertion.first->second;
>    if (Insertion.second) {
>      Site->SiteFuncId = NextFuncId++;
> -    Site->Inlinee = Loc->getScope()->getSubprogram();
> -    InlinedSubprograms.insert(Loc->getScope()->getSubprogram());
> +    Site->Inlinee = Inlinee;
> +    InlinedSubprograms.insert(Inlinee);
>    }
>    return *Site;
>  }
>
> +void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
> +                                        const DILocation *InlinedAt) {
> +  if (InlinedAt) {
> +    // This variable was inlined. Associate it with the InlineSite.
> +    const DISubprogram *Inlinee = Var.DIVar->getScope()->getSubprogram();
> +    InlineSite &Site = getInlineSite(InlinedAt, Inlinee);
> +    Site.InlinedLocals.emplace_back(Var);
> +  } else {
> +    // This variable goes in the main ProcSym.
> +    CurFn->Locals.emplace_back(Var);
> +  }
> +}
> +
>  static void addLocIfNotPresent(SmallVectorImpl<const DILocation *> &Locs,
>                                 const DILocation *Loc) {
>    auto B = Locs.begin(), E = Locs.end();
> @@ -154,18 +168,19 @@ void CodeViewDebug::maybeRecordLocation(
>    CurFn->LastLoc = DL;
>
>    unsigned FuncId = CurFn->FuncId;
> -  if (DL->getInlinedAt()) {
> +  if (const DILocation *SiteLoc = DL->getInlinedAt()) {
>      const DILocation *Loc = DL.get();
>
>      // If this location was actually inlined from somewhere else, give
it the ID
>      // of the inline call site.
> -    FuncId = getInlineSite(Loc).SiteFuncId;
> +    FuncId =
> +        getInlineSite(SiteLoc,
Loc->getScope()->getSubprogram()).SiteFuncId;
>
>      // Ensure we have links in the tree of inline call sites.
> -    const DILocation *SiteLoc;
>      bool FirstLoc = true;
>      while ((SiteLoc = Loc->getInlinedAt())) {
> -      InlineSite &Site = getInlineSite(Loc);
> +      InlineSite &Site =
> +          getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());
>        if (!FirstLoc)
>          addLocIfNotPresent(Site.ChildSites, Loc);
>        FirstLoc = false;
> @@ -477,45 +492,148 @@ void CodeViewDebug::emitDebugInfoForFunc
>    OS.EmitCVLinetableDirective(FI.FuncId, Fn, FI.End);
>  }
>
> -void CodeViewDebug::collectVariableInfoFromMMITable() {
> -  for (const auto &VI : MMI->getVariableDbgInfo()) {
> +CodeViewDebug::LocalVarDefRange
> +CodeViewDebug::createDefRangeMem(uint16_t CVRegister, int Offset) {
> +  LocalVarDefRange DR;
> +  DR.InMemory = 1;

This is causing compile warnings in MSVC because InMemory is a signed
int, making its valid range [-1,0].

> +  DR.DataOffset = Offset;
> +  assert(DR.DataOffset == Offset && "truncation");
> +  DR.StructOffset = 0;
> +  DR.CVRegister = CVRegister;
> +  return DR;
> +}
> +
> +CodeViewDebug::LocalVarDefRange
> +CodeViewDebug::createDefRangeReg(uint16_t CVRegister) {
> +  LocalVarDefRange DR;
> +  DR.InMemory = 0;
> +  DR.DataOffset = 0;
> +  DR.StructOffset = 0;
> +  DR.CVRegister = CVRegister;
> +  return DR;
> +}
> +
> +void CodeViewDebug::collectVariableInfoFromMMITable(
> +    DenseSet<InlinedVariable> &Processed) {
> +  const TargetSubtargetInfo &TSI = Asm->MF->getSubtarget();
> +  const TargetFrameLowering *TFI = TSI.getFrameLowering();
> +  const TargetRegisterInfo *TRI = TSI.getRegisterInfo();
> +
> +  for (const MachineModuleInfo::VariableDbgInfo &VI :
> +       MMI->getVariableDbgInfo()) {
>      if (!VI.Var)
>        continue;
>      assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
>             "Expected inlined-at fields to agree");
>
> +    Processed.insert(InlinedVariable(VI.Var, VI.Loc->getInlinedAt()));
>      LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
>
>      // If variable scope is not found then skip this variable.
>      if (!Scope)
>        continue;
>
> -    LocalVariable Var;
> -    Var.DIVar = VI.Var;
> -
>      // Get the frame register used and the offset.
>      unsigned FrameReg = 0;
> -    const TargetSubtargetInfo &TSI = Asm->MF->getSubtarget();
> -    const TargetFrameLowering *TFI = TSI.getFrameLowering();
> -    const TargetRegisterInfo *TRI = TSI.getRegisterInfo();
> -    Var.RegisterOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot,
FrameReg);
> -    Var.CVRegister = TRI->getCodeViewRegNum(FrameReg);
> +    int FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot,
FrameReg);
> +    uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);
>
>      // Calculate the label ranges.
> +    LocalVarDefRange DefRange = createDefRangeMem(CVReg, FrameOffset);
>      for (const InsnRange &Range : Scope->getRanges()) {
>        const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
>        const MCSymbol *End = getLabelAfterInsn(Range.second);
> -      Var.Ranges.push_back({Begin, End});
> +      End = End ? End : Asm->getFunctionEnd();
> +      DefRange.Ranges.emplace_back(Begin, End);
>      }
>
> -    if (VI.Loc->getInlinedAt()) {
> -      // This variable was inlined. Associate it with the InlineSite.
> -      InlineSite &Site = getInlineSite(VI.Loc);
> -      Site.InlinedLocals.emplace_back(std::move(Var));
> -    } else {
> -      // This variable goes in the main ProcSym.
> -      CurFn->Locals.emplace_back(std::move(Var));
> +    LocalVariable Var;
> +    Var.DIVar = VI.Var;
> +    Var.DefRanges.emplace_back(std::move(DefRange));
> +    recordLocalVariable(std::move(Var), VI.Loc->getInlinedAt());
> +  }
> +}
> +
> +void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
> +  DenseSet<InlinedVariable> Processed;
> +  // Grab the variable info that was squirreled away in the MMI
side-table.
> +  collectVariableInfoFromMMITable(Processed);
> +
> +  const TargetRegisterInfo *TRI =
Asm->MF->getSubtarget().getRegisterInfo();
> +
> +  for (const auto &I : DbgValues) {
> +    InlinedVariable IV = I.first;
> +    if (Processed.count(IV))
> +      continue;
> +    const DILocalVariable *DIVar = IV.first;
> +    const DILocation *InlinedAt = IV.second;
> +
> +    // Instruction ranges, specifying where IV is accessible.
> +    const auto &Ranges = I.second;
> +
> +    LexicalScope *Scope = nullptr;
> +    if (InlinedAt)
> +      Scope = LScopes.findInlinedScope(DIVar->getScope(), InlinedAt);
> +    else
> +      Scope = LScopes.findLexicalScope(DIVar->getScope());
> +    // If variable scope is not found then skip this variable.
> +    if (!Scope)
> +      continue;
> +
> +    LocalVariable Var;
> +    Var.DIVar = DIVar;
> +
> +    // Calculate the definition ranges.
> +    for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
> +      const InsnRange &Range = *I;
> +      const MachineInstr *DVInst = Range.first;
> +      assert(DVInst->isDebugValue() && "Invalid History entry");
> +      const DIExpression *DIExpr = DVInst->getDebugExpression();
> +
> +      // Bail if there is a complex DWARF expression for now.
> +      if (DIExpr && DIExpr->getNumElements() > 0)
> +        continue;
> +
> +      // Handle the two cases we can handle: indirect in memory and in
register.
> +      bool IsIndirect = DVInst->getOperand(1).isImm();
> +      unsigned CVReg =
TRI->getCodeViewRegNum(DVInst->getOperand(0).getReg());
> +      {
> +        LocalVarDefRange DefRange;
> +        if (IsIndirect) {
> +          int64_t Offset = DVInst->getOperand(1).getImm();
> +          DefRange = createDefRangeMem(CVReg, Offset);
> +        } else {
> +          DefRange = createDefRangeReg(CVReg);
> +        }
> +        if (Var.DefRanges.empty() ||
> +            Var.DefRanges.back().isDifferentLocation(DefRange)) {
> +          Var.DefRanges.emplace_back(std::move(DefRange));
> +        }
> +      }
> +
> +      // Compute the label range.
> +      const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
> +      const MCSymbol *End = getLabelAfterInsn(Range.second);
> +      if (!End) {
> +        if (std::next(I) != E)
> +          End = getLabelBeforeInsn(std::next(I)->first);
> +        else
> +          End = Asm->getFunctionEnd();
> +      }
> +
> +      // If the last range end is our begin, just extend the last range.
> +      // Otherwise make a new range.
> +      SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>>
&Ranges =
> +          Var.DefRanges.back().Ranges;
> +      if (!Ranges.empty() && Ranges.back().second == Begin)
> +        Ranges.back().second = End;
> +      else
> +        Ranges.emplace_back(Begin, End);
> +
> +      // FIXME: Do more range combining.
>      }
> +
> +    recordLocalVariable(std::move(Var), InlinedAt);
>    }
>  }
>
> @@ -572,6 +690,8 @@ void CodeViewDebug::emitLocalVariable(co
>    uint16_t Flags = 0;
>    if (Var.DIVar->isParameter())
>      Flags |= LocalSym::IsParameter;
> +  if (Var.DefRanges.empty())
> +    Flags |= LocalSym::IsOptimizedOut;
>
>    OS.AddComment("TypeIndex");
>    OS.EmitIntValue(TypeIndex::Int32().getIndex(), 4);
> @@ -580,28 +700,42 @@ void CodeViewDebug::emitLocalVariable(co
>    emitNullTerminatedString(OS, Var.DIVar->getName());
>    OS.EmitLabel(LocalEnd);
>
> -  // DefRangeRegisterRelSym record, see SymbolRecord.h for more info.
Omit the
> -  // LocalVariableAddrRange field from the record. The directive will
emit that.
> -  DefRangeRegisterRelSym Sym{};
> -  ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER_REL);
> -  Sym.BaseRegister = Var.CVRegister;
> -  Sym.Flags = 0; // Unclear what matters here.
> -  Sym.BasePointerOffset = Var.RegisterOffset;
> -  SmallString<sizeof(Sym) + sizeof(SymKind) -
sizeof(LocalVariableAddrRange)>
> -      BytePrefix;
> -  BytePrefix += StringRef(reinterpret_cast<const char *>(&SymKind),
> -                          sizeof(SymKind));
> -  BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),
> -                          sizeof(Sym) - sizeof(LocalVariableAddrRange));
> +  // Calculate the on disk prefix of the appropriate def range record.
The
> +  // records and on disk formats are described in SymbolRecords.h.
BytePrefix
> +  // should be big enough to hold all forms without memory allocation.
> +  SmallString<20> BytePrefix;
> +  for (const LocalVarDefRange &DefRange : Var.DefRanges) {
> +    BytePrefix.clear();
> +    // FIXME: Handle bitpieces.
> +    if (DefRange.StructOffset != 0)
> +      continue;
>
> -  OS.EmitCVDefRangeDirective(Var.Ranges, BytePrefix);
> +    if (DefRange.InMemory) {
> +      DefRangeRegisterRelSym Sym{};
> +      ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER_REL);
> +      Sym.BaseRegister = DefRange.CVRegister;
> +      Sym.Flags = 0; // Unclear what matters here.
> +      Sym.BasePointerOffset = DefRange.DataOffset;
> +      BytePrefix +=
> +          StringRef(reinterpret_cast<const char *>(&SymKind),
sizeof(SymKind));
> +      BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),
> +                              sizeof(Sym) -
sizeof(LocalVariableAddrRange));
> +    } else {
> +      assert(DefRange.DataOffset == 0 && "unexpected offset into
register");
> +      DefRangeRegisterSym Sym{};
> +      ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER);
> +      Sym.Register = DefRange.CVRegister;
> +      Sym.MayHaveNoName = 0; // Unclear what matters here.
> +      BytePrefix +=
> +          StringRef(reinterpret_cast<const char *>(&SymKind),
sizeof(SymKind));
> +      BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),
> +                              sizeof(Sym) -
sizeof(LocalVariableAddrRange));
> +    }
> +    OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix);
> +  }
>  }
>
>  void CodeViewDebug::endFunction(const MachineFunction *MF) {
> -  collectVariableInfoFromMMITable();
> -
> -  DebugHandlerBase::endFunction(MF);
> -
>    if (!Asm || !CurFn)  // We haven't created any debug info for this
function.
>      return;
>
> @@ -609,6 +743,10 @@ void CodeViewDebug::endFunction(const Ma
>    assert(FnDebugInfo.count(GV));
>    assert(CurFn == &FnDebugInfo[GV]);
>
> +  collectVariableInfo(getDISubprogram(GV));
> +
> +  DebugHandlerBase::endFunction(MF);
> +
>    // Don't emit anything if we don't have any line tables.
>    if (!CurFn->HaveLineInfo) {
>      FnDebugInfo.erase(GV);
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
> URL:
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=260746&r1=260745&r2=260746&view=diff
>
==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h Fri Feb 12 15:48:30
2016
> @@ -35,13 +35,40 @@ class LexicalScope;
>  class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
>    MCStreamer &OS;
>
> +  /// Represents the most general definition range.
> +  struct LocalVarDefRange {
> +    /// Indicates that variable data is stored in memory relative to the
> +    /// specified register.
> +    int InMemory : 1;
> +
> +    /// Offset of variable data in memory.
> +    int DataOffset : 31;

Would it make sense to declare both of these as unsigned instead of
int? It seems like they should both be positive.

~Aaron

> +
> +    /// Offset of the data into the user level struct. If zero, no
splitting
> +    /// occurred.
> +    uint16_t StructOffset;
> +
> +    /// Register containing the data or the register base of the memory
> +    /// location containing the data.
> +    uint16_t CVRegister;
> +
> +    /// Compares all location fields. This includes all fields except
the label
> +    /// ranges.
> +    bool isDifferentLocation(LocalVarDefRange &O) {
> +      return InMemory != O.InMemory || DataOffset != O.DataOffset ||
> +             StructOffset != O.StructOffset || CVRegister !=
O.CVRegister;
> +    }
> +
> +    SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges;
> +  };
> +
> +  static LocalVarDefRange createDefRangeMem(uint16_t CVRegister, int
Offset);
> +  static LocalVarDefRange createDefRangeReg(uint16_t CVRegister);
> +
>    /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific.
>    struct LocalVariable {
>      const DILocalVariable *DIVar = nullptr;
> -    SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges;
> -    unsigned CVRegister = 0;
> -    int RegisterOffset = 0;
> -    // FIXME: Add support for DIExpressions.
> +    SmallVector<LocalVarDefRange, 1> DefRanges;
>    };
>
>    struct InlineSite {
> @@ -74,7 +101,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
>
>    unsigned NextFuncId = 0;
>
> -  InlineSite &getInlineSite(const DILocation *Loc);
> +  InlineSite &getInlineSite(const DILocation *InlinedAt,
> +                            const DISubprogram *Inlinee);
>
>    static void collectInlineSiteChildren(SmallVectorImpl<unsigned>
&Children,
>                                          const FunctionInfo &FI,
> @@ -123,7 +151,15 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
>    void emitInlinedCallSite(const FunctionInfo &FI, const DILocation
*InlinedAt,
>                             const InlineSite &Site);
>
> -  void collectVariableInfoFromMMITable();
> +  typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
> +
> +  void collectVariableInfo(const DISubprogram *SP);
> +
> +  void collectVariableInfoFromMMITable(DenseSet<InlinedVariable>
&Processed);
> +
> +  /// Records information about a local variable in the appropriate
scope. In
> +  /// particular, locals from inlined code live inside the inlining site.
> +  void recordLocalVariable(LocalVariable &&Var, const DILocation *Loc);
>
>    void emitLocalVariable(const LocalVariable &Var);
>
>
> Added: llvm/trunk/test/DebugInfo/COFF/register-variables.ll
> URL:
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/register-variables.ll?rev=260746&view=auto
>
==============================================================================
> --- llvm/trunk/test/DebugInfo/COFF/register-variables.ll (added)
> +++ llvm/trunk/test/DebugInfo/COFF/register-variables.ll Fri Feb 12
15:48:30 2016
> @@ -0,0 +1,291 @@
> +; RUN: llc < %s | FileCheck %s --check-prefix=ASM
> +; RUN: llc < %s -filetype=obj | llvm-readobj -codeview - | FileCheck %s
--check-prefix=OBJ
> +
> +; Generated from:
> +; volatile int x;
> +; int getint(void);
> +; void putint(int);
> +; static inline int inlineinc(int a) {
> +;   int b = a + 1;
> +;   ++x;
> +;   return b;
> +; }
> +; void f(int p) {
> +;   if (p) {
> +;     int a = getint();
> +;     int b = inlineinc(a);
> +;     putint(b);
> +;   } else {
> +;     int c = getint();
> +;     putint(c);
> +;   }
> +; }
> +
> +; ASM: f:                                      # @f
> +; ASM: .Lfunc_begin0:
> +; ASM: # BB#0:                                 # %entry
> +; ASM:         pushq   %rsi
> +; ASM:         subq    $32, %rsp
> +; ASM:         #DEBUG_VALUE: f:p <- %ECX
> +; ASM:         movl    %ecx, %esi
> +; ASM: [[p_ecx_esi:\.Ltmp.*]]:
> +; ASM:         #DEBUG_VALUE: f:p <- %ESI
> +; ASM:         callq   getint
> +; ASM: [[after_getint:\.Ltmp.*]]:
> +; ASM:         #DEBUG_VALUE: a <- %EAX
> +; ASM:         #DEBUG_VALUE: inlineinc:a <- %EAX
> +; ASM:         #DEBUG_VALUE: c <- %EAX
> +; ASM:         testl   %esi, %esi
> +; ASM:         je      .LBB0_2
> +; ASM: # BB#1:                                 # %if.then
> +; ASM:         #DEBUG_VALUE: c <- %EAX
> +; ASM:         #DEBUG_VALUE: inlineinc:a <- %EAX
> +; ASM:         #DEBUG_VALUE: a <- %EAX
> +; ASM:         #DEBUG_VALUE: f:p <- %ESI
> +; ASM:         incl    %eax
> +; ASM: [[after_inc_eax:\.Ltmp.*]]:
> +; ASM:         #DEBUG_VALUE: inlineinc:b <- %EAX
> +; ASM:         #DEBUG_VALUE: b <- %EAX
> +; ASM:         incl    x(%rip)
> +; ASM: [[after_if:\.Ltmp.*]]:
> +; ASM: .LBB0_2:                                # %if.else
> +; ASM:         #DEBUG_VALUE: f:p <- %ESI
> +; ASM:         movl    %eax, %ecx
> +; ASM:         addq    $32, %rsp
> +; ASM:         popq    %rsi
> +; ASM: [[func_end:\.Ltmp.*]]:
> +; ASM:         rex64 jmp       putint          # TAILCALL
> +
> +; ASM:         .short  4414                    # Record kind: S_LOCAL
> +; ASM:         .asciz  "p"
> +; ASM:         .cv_def_range    .Lfunc_begin0 [[p_ecx_esi]],
"A\021\022\000\000\000"
> +; ASM:         .cv_def_range    [[p_ecx_esi]] [[func_end]],
"A\021\027\000\000\000"
> +; ASM:         .short  4414                    # Record kind: S_LOCAL
> +; ASM:         .asciz  "a"
> +; ASM:         .cv_def_range    [[after_getint]] [[after_inc_eax]],
"A\021\021\000\000\000"
> +; ASM:         .short  4414                    # Record kind: S_LOCAL
> +; ASM:         .asciz  "c"
> +; ASM:         .cv_def_range    [[after_getint]] [[after_inc_eax]],
"A\021\021\000\000\000"
> +; ASM:         .short  4414                    # Record kind: S_LOCAL
> +; ASM:         .asciz  "b"
> +; ASM:         .cv_def_range    [[after_inc_eax]] [[after_if]],
"A\021\021\000\000\000"
> +
> +; ASM:         .short  4429                    # Record kind:
S_INLINESITE
> +; ASM:         .short  4414                    # Record kind: S_LOCAL
> +; ASM:         .asciz  "a"
> +; ASM:         .cv_def_range    [[after_getint]] [[after_inc_eax]],
"A\021\021\000\000\000"
> +; ASM:         .short  4414                    # Record kind: S_LOCAL
> +; ASM:         .asciz  "b"
> +; ASM:         .cv_def_range    [[after_inc_eax]] [[after_if]],
"A\021\021\000\000\000"
> +; ASM:         .short  4430                    # Record kind:
S_INLINESITE_END
> +
> +; OBJ: Subsection [
> +; OBJ:   SubSectionType: Symbols (0xF1)
> +; OBJ:   ProcStart {
> +; OBJ:     DisplayName: f
> +; OBJ:   }
> +; OBJ:   Local {
> +; OBJ:     Type: int (0x74)
> +; OBJ:     Flags [ (0x1)
> +; OBJ:       IsParameter (0x1)
> +; OBJ:     ]
> +; OBJ:     VarName: p
> +; OBJ:   }
> +; OBJ:   DefRangeRegister {
> +; OBJ:     Register: 18
> +; OBJ:     LocalVariableAddrRange {
> +; OBJ:       OffsetStart: .text+0x0
> +; OBJ:       ISectStart: 0x0
> +; OBJ:       Range: 0x7
> +; OBJ:     }
> +; OBJ:   }
> +; OBJ:   DefRangeRegister {
> +; OBJ:     Register: 23
> +; OBJ:     LocalVariableAddrRange {
> +; OBJ:       OffsetStart: .text+0x7
> +; OBJ:       ISectStart: 0x0
> +; OBJ:       Range: 0x18
> +; OBJ:     }
> +; OBJ:   }
> +; OBJ:   Local {
> +; OBJ:     Type: int (0x74)
> +; OBJ:     Flags [ (0x0)
> +; OBJ:     ]
> +; OBJ:     VarName: a
> +; OBJ:   }
> +; OBJ:   DefRangeRegister {
> +; OBJ:     Register: 17
> +; OBJ:     LocalVariableAddrRange {
> +; OBJ:       OffsetStart: .text+0xC
> +; OBJ:       ISectStart: 0x0
> +; OBJ:       Range: 0x6
> +; OBJ:     }
> +; OBJ:   }
> +; OBJ:   Local {
> +; OBJ:     Type: int (0x74)
> +; OBJ:     Flags [ (0x0)
> +; OBJ:     ]
> +; OBJ:     VarName: c
> +; OBJ:   }
> +; OBJ:   DefRangeRegister {
> +; OBJ:     Register: 17
> +; OBJ:     LocalVariableAddrRange {
> +; OBJ:       OffsetStart: .text+0xC
> +; OBJ:       ISectStart: 0x0
> +; OBJ:       Range: 0x6
> +; OBJ:     }
> +; OBJ:   }
> +; OBJ:   Local {
> +; OBJ:     Type: int (0x74)
> +; OBJ:     Flags [ (0x0)
> +; OBJ:     ]
> +; OBJ:     VarName: b
> +; OBJ:   }
> +; OBJ:   DefRangeRegister {
> +; OBJ:     Register: 17
> +; OBJ:     LocalVariableAddrRange {
> +; OBJ:       OffsetStart: .text+0x12
> +; OBJ:       ISectStart: 0x0
> +; OBJ:       Range: 0x6
> +; OBJ:     }
> +; OBJ:   }
> +; OBJ:   InlineSite {
> +; OBJ:     PtrParent: 0x0
> +; OBJ:     PtrEnd: 0x0
> +; OBJ:     Inlinee: inlineinc (0x1003)
> +; OBJ:   }
> +; OBJ:   Local {
> +; OBJ:     Type: int (0x74)
> +; OBJ:     Flags [ (0x1)
> +; OBJ:       IsParameter (0x1)
> +; OBJ:     ]
> +; OBJ:     VarName: a
> +; OBJ:   }
> +; OBJ:   DefRangeRegister {
> +; OBJ:     Register: 17
> +; OBJ:     LocalVariableAddrRange {
> +; OBJ:       OffsetStart: .text+0xC
> +; OBJ:       ISectStart: 0x0
> +; OBJ:       Range: 0x6
> +; OBJ:     }
> +; OBJ:   }
> +; OBJ:   Local {
> +; OBJ:     Type: int (0x74)
> +; OBJ:     Flags [ (0x0)
> +; OBJ:     ]
> +; OBJ:     VarName: b
> +; OBJ:   }
> +; OBJ:   DefRangeRegister {
> +; OBJ:     Register: 17
> +; OBJ:     LocalVariableAddrRange {
> +; OBJ:       OffsetStart: .text+0x12
> +; OBJ:       ISectStart: 0x0
> +; OBJ:       Range: 0x6
> +; OBJ:     }
> +; OBJ:   }
> +; OBJ:   InlineSiteEnd {
> +; OBJ:   }
> +; OBJ:   ProcEnd
> +; OBJ: ]
> +
> +; ModuleID = 't.cpp'
> +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64-pc-windows-msvc18.0.0"
> +
> + at x = internal global i32 0, align 4
> +
> +; Function Attrs: nounwind uwtable
> +define void @f(i32 %p) #0 !dbg !4 {
> +entry:
> +  tail call void @llvm.dbg.value(metadata i32 %p, i64 0, metadata !9,
metadata !29), !dbg !30
> +  %tobool = icmp eq i32 %p, 0, !dbg !31
> +  %call2 = tail call i32 @getint() #3, !dbg !32
> +  br i1 %tobool, label %if.else, label %if.then, !dbg !33
> +
> +if.then:                                          ; preds = %entry
> +  tail call void @llvm.dbg.value(metadata i32 %call2, i64 0, metadata
!10, metadata !29), !dbg !34
> +  tail call void @llvm.dbg.value(metadata i32 %call2, i64 0, metadata
!20, metadata !29), !dbg !35
> +  %add.i = add nsw i32 %call2, 1, !dbg !37
> +  tail call void @llvm.dbg.value(metadata i32 %add.i, i64 0, metadata
!21, metadata !29), !dbg !38
> +  %0 = load volatile i32, i32* @x, align 4, !dbg !39, !tbaa !40
> +  %inc.i = add nsw i32 %0, 1, !dbg !39
> +  store volatile i32 %inc.i, i32* @x, align 4, !dbg !39, !tbaa !40
> +  tail call void @llvm.dbg.value(metadata i32 %add.i, i64 0, metadata
!13, metadata !29), !dbg !44
> +  tail call void @putint(i32 %add.i) #3, !dbg !45
> +  br label %if.end, !dbg !46
> +
> +if.else:                                          ; preds = %entry
> +  tail call void @llvm.dbg.value(metadata i32 %call2, i64 0, metadata
!14, metadata !29), !dbg !47
> +  tail call void @putint(i32 %call2) #3, !dbg !48
> +  br label %if.end
> +
> +if.end:                                           ; preds = %if.else,
%if.then
> +  ret void, !dbg !49
> +}
> +
> +declare i32 @getint() #1
> +
> +declare void @putint(i32) #1
> +
> +; Function Attrs: nounwind readnone
> +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2
> +
> +attributes #0 = { nounwind uwtable "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="false"
"no-infs-fp-math"="false" "no-nans-fp-math"="false"
"stack-protector-buffer-size"="8" "target-cpu"="x86-64"
"target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false"
"use-soft-float"="false" }
> +attributes #1 = { "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="false"
"no-infs-fp-math"="false" "no-nans-fp-math"="false"
"stack-protector-buffer-size"="8" "target-cpu"="x86-64"
"target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false"
"use-soft-float"="false" }
> +attributes #2 = { nounwind readnone }
> +attributes #3 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!25, !26, !27}
> +!llvm.ident = !{!28}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer:
"clang version 3.9.0 (trunk 260617) (llvm/trunk 260619)", isOptimized:
true, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3,
globals: !22)
> +!1 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvm\5Cbuild")
> +!2 = !{}
> +!3 = !{!4, !16}
> +!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 9,
type: !5, isLocal: false, isDefinition: true, scopeLine: 9, flags:
DIFlagPrototyped, isOptimized: true, variables: !8)
> +!5 = !DISubroutineType(types: !6)
> +!6 = !{null, !7}
> +!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding:
DW_ATE_signed)
> +!8 = !{!9, !10, !13, !14}
> +!9 = !DILocalVariable(name: "p", arg: 1, scope: !4, file: !1, line: 9,
type: !7)
> +!10 = !DILocalVariable(name: "a", scope: !11, file: !1, line: 11, type:
!7)
> +!11 = distinct !DILexicalBlock(scope: !12, file: !1, line: 10, column:
10)
> +!12 = distinct !DILexicalBlock(scope: !4, file: !1, line: 10, column: 7)
> +!13 = !DILocalVariable(name: "b", scope: !11, file: !1, line: 12, type:
!7)
> +!14 = !DILocalVariable(name: "c", scope: !15, file: !1, line: 15, type:
!7)
> +!15 = distinct !DILexicalBlock(scope: !12, file: !1, line: 14, column:
10)
> +!16 = distinct !DISubprogram(name: "inlineinc", scope: !1, file: !1,
line: 4, type: !17, isLocal: true, isDefinition: true, scopeLine: 4, flags:
DIFlagPrototyped, isOptimized: true, variables: !19)
> +!17 = !DISubroutineType(types: !18)
> +!18 = !{!7, !7}
> +!19 = !{!20, !21}
> +!20 = !DILocalVariable(name: "a", arg: 1, scope: !16, file: !1, line: 4,
type: !7)
> +!21 = !DILocalVariable(name: "b", scope: !16, file: !1, line: 5, type:
!7)
> +!22 = !{!23}
> +!23 = !DIGlobalVariable(name: "x", scope: !0, file: !1, line: 1, type:
!24, isLocal: false, isDefinition: true, variable: i32* @x)
> +!24 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !7)
> +!25 = !{i32 2, !"CodeView", i32 1}
> +!26 = !{i32 2, !"Debug Info Version", i32 3}
> +!27 = !{i32 1, !"PIC Level", i32 2}
> +!28 = !{!"clang version 3.9.0 (trunk 260617) (llvm/trunk 260619)"}
> +!29 = !DIExpression()
> +!30 = !DILocation(line: 9, column: 12, scope: !4)
> +!31 = !DILocation(line: 10, column: 7, scope: !12)
> +!32 = !DILocation(line: 15, column: 13, scope: !15)
> +!33 = !DILocation(line: 10, column: 7, scope: !4)
> +!34 = !DILocation(line: 11, column: 9, scope: !11)
> +!35 = !DILocation(line: 4, column: 33, scope: !16, inlinedAt: !36)
> +!36 = distinct !DILocation(line: 12, column: 13, scope: !11)
> +!37 = !DILocation(line: 5, column: 13, scope: !16, inlinedAt: !36)
> +!38 = !DILocation(line: 5, column: 7, scope: !16, inlinedAt: !36)
> +!39 = !DILocation(line: 6, column: 3, scope: !16, inlinedAt: !36)
> +!40 = !{!41, !41, i64 0}
> +!41 = !{!"int", !42, i64 0}
> +!42 = !{!"omnipotent char", !43, i64 0}
> +!43 = !{!"Simple C/C++ TBAA"}
> +!44 = !DILocation(line: 12, column: 9, scope: !11)
> +!45 = !DILocation(line: 13, column: 5, scope: !11)
> +!46 = !DILocation(line: 14, column: 3, scope: !11)
> +!47 = !DILocation(line: 15, column: 9, scope: !15)
> +!48 = !DILocation(line: 16, column: 5, scope: !15)
> +!49 = !DILocation(line: 18, column: 1, scope: !4)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160215/fedfe5e5/attachment.html>


More information about the llvm-commits mailing list