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

Aaron Ballman via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 15 10:16:51 PST 2016


On Mon, Feb 15, 2016 at 1:11 PM, Reid Kleckner <rnk at google.com> wrote:
> 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.

Then I guess the assignment should be InMemory = -1.

~Aaron

>
> 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


More information about the llvm-commits mailing list