<p dir="ltr">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.</p>
<p dir="ltr">Sent from phone</p>
<div class="gmail_quot<blockquote class=" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Fri, Feb 12, 2016 at 4:48 PM, Reid Kleckner via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: rnk<br>
> Date: Fri Feb 12 15:48:30 2016<br>
> New Revision: 260746<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=260746&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=260746&view=rev</a><br>
> Log:<br>
> [codeview] Describe local variables in registers<br>
><br>
> Added:<br>
>     llvm/trunk/test/DebugInfo/COFF/register-variables.ll<br>
> Modified:<br>
>     llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp<br>
>     llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=260746&r1=260745&r2=260746&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=260746&r1=260745&r2=260746&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Fri Feb 12 15:48:30 2016<br>
> @@ -105,18 +105,32 @@ unsigned CodeViewDebug::maybeRecordFile(<br>
>    return Insertion.first->second;<br>
>  }<br>
><br>
> -CodeViewDebug::InlineSite &CodeViewDebug::getInlineSite(const DILocation *Loc) {<br>
> -  const DILocation *InlinedAt = Loc->getInlinedAt();<br>
> +CodeViewDebug::InlineSite &<br>
> +CodeViewDebug::getInlineSite(const DILocation *InlinedAt,<br>
> +                             const DISubprogram *Inlinee) {<br>
>    auto Insertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()});<br>
>    InlineSite *Site = &Insertion.first->second;<br>
>    if (Insertion.second) {<br>
>      Site->SiteFuncId = NextFuncId++;<br>
> -    Site->Inlinee = Loc->getScope()->getSubprogram();<br>
> -    InlinedSubprograms.insert(Loc->getScope()->getSubprogram());<br>
> +    Site->Inlinee = Inlinee;<br>
> +    InlinedSubprograms.insert(Inlinee);<br>
>    }<br>
>    return *Site;<br>
>  }<br>
><br>
> +void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,<br>
> +                                        const DILocation *InlinedAt) {<br>
> +  if (InlinedAt) {<br>
> +    // This variable was inlined. Associate it with the InlineSite.<br>
> +    const DISubprogram *Inlinee = Var.DIVar->getScope()->getSubprogram();<br>
> +    InlineSite &Site = getInlineSite(InlinedAt, Inlinee);<br>
> +    Site.InlinedLocals.emplace_back(Var);<br>
> +  } else {<br>
> +    // This variable goes in the main ProcSym.<br>
> +    CurFn->Locals.emplace_back(Var);<br>
> +  }<br>
> +}<br>
> +<br>
>  static void addLocIfNotPresent(SmallVectorImpl<const DILocation *> &Locs,<br>
>                                 const DILocation *Loc) {<br>
>    auto B = Locs.begin(), E = Locs.end();<br>
> @@ -154,18 +168,19 @@ void CodeViewDebug::maybeRecordLocation(<br>
>    CurFn->LastLoc = DL;<br>
><br>
>    unsigned FuncId = CurFn->FuncId;<br>
> -  if (DL->getInlinedAt()) {<br>
> +  if (const DILocation *SiteLoc = DL->getInlinedAt()) {<br>
>      const DILocation *Loc = DL.get();<br>
><br>
>      // If this location was actually inlined from somewhere else, give it the ID<br>
>      // of the inline call site.<br>
> -    FuncId = getInlineSite(Loc).SiteFuncId;<br>
> +    FuncId =<br>
> +        getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId;<br>
><br>
>      // Ensure we have links in the tree of inline call sites.<br>
> -    const DILocation *SiteLoc;<br>
>      bool FirstLoc = true;<br>
>      while ((SiteLoc = Loc->getInlinedAt())) {<br>
> -      InlineSite &Site = getInlineSite(Loc);<br>
> +      InlineSite &Site =<br>
> +          getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());<br>
>        if (!FirstLoc)<br>
>          addLocIfNotPresent(Site.ChildSites, Loc);<br>
>        FirstLoc = false;<br>
> @@ -477,45 +492,148 @@ void CodeViewDebug::emitDebugInfoForFunc<br>
>    OS.EmitCVLinetableDirective(FI.FuncId, Fn, FI.End);<br>
>  }<br>
><br>
> -void CodeViewDebug::collectVariableInfoFromMMITable() {<br>
> -  for (const auto &VI : MMI->getVariableDbgInfo()) {<br>
> +CodeViewDebug::LocalVarDefRange<br>
> +CodeViewDebug::createDefRangeMem(uint16_t CVRegister, int Offset) {<br>
> +  LocalVarDefRange DR;<br>
> +  DR.InMemory = 1;<br>
<br>
This is causing compile warnings in MSVC because InMemory is a signed<br>
int, making its valid range [-1,0].<br>
<br>
> +  DR.DataOffset = Offset;<br>
> +  assert(DR.DataOffset == Offset && "truncation");<br>
> +  DR.StructOffset = 0;<br>
> +  DR.CVRegister = CVRegister;<br>
> +  return DR;<br>
> +}<br>
> +<br>
> +CodeViewDebug::LocalVarDefRange<br>
> +CodeViewDebug::createDefRangeReg(uint16_t CVRegister) {<br>
> +  LocalVarDefRange DR;<br>
> +  DR.InMemory = 0;<br>
> +  DR.DataOffset = 0;<br>
> +  DR.StructOffset = 0;<br>
> +  DR.CVRegister = CVRegister;<br>
> +  return DR;<br>
> +}<br>
> +<br>
> +void CodeViewDebug::collectVariableInfoFromMMITable(<br>
> +    DenseSet<InlinedVariable> &Processed) {<br>
> +  const TargetSubtargetInfo &TSI = Asm->MF->getSubtarget();<br>
> +  const TargetFrameLowering *TFI = TSI.getFrameLowering();<br>
> +  const TargetRegisterInfo *TRI = TSI.getRegisterInfo();<br>
> +<br>
> +  for (const MachineModuleInfo::VariableDbgInfo &VI :<br>
> +       MMI->getVariableDbgInfo()) {<br>
>      if (!VI.Var)<br>
>        continue;<br>
>      assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&<br>
>             "Expected inlined-at fields to agree");<br>
><br>
> +    Processed.insert(InlinedVariable(VI.Var, VI.Loc->getInlinedAt()));<br>
>      LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);<br>
><br>
>      // If variable scope is not found then skip this variable.<br>
>      if (!Scope)<br>
>        continue;<br>
><br>
> -    LocalVariable Var;<br>
> -    Var.DIVar = VI.Var;<br>
> -<br>
>      // Get the frame register used and the offset.<br>
>      unsigned FrameReg = 0;<br>
> -    const TargetSubtargetInfo &TSI = Asm->MF->getSubtarget();<br>
> -    const TargetFrameLowering *TFI = TSI.getFrameLowering();<br>
> -    const TargetRegisterInfo *TRI = TSI.getRegisterInfo();<br>
> -    Var.RegisterOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg);<br>
> -    Var.CVRegister = TRI->getCodeViewRegNum(FrameReg);<br>
> +    int FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg);<br>
> +    uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);<br>
><br>
>      // Calculate the label ranges.<br>
> +    LocalVarDefRange DefRange = createDefRangeMem(CVReg, FrameOffset);<br>
>      for (const InsnRange &Range : Scope->getRanges()) {<br>
>        const MCSymbol *Begin = getLabelBeforeInsn(Range.first);<br>
>        const MCSymbol *End = getLabelAfterInsn(Range.second);<br>
> -      Var.Ranges.push_back({Begin, End});<br>
> +      End = End ? End : Asm->getFunctionEnd();<br>
> +      DefRange.Ranges.emplace_back(Begin, End);<br>
>      }<br>
><br>
> -    if (VI.Loc->getInlinedAt()) {<br>
> -      // This variable was inlined. Associate it with the InlineSite.<br>
> -      InlineSite &Site = getInlineSite(VI.Loc);<br>
> -      Site.InlinedLocals.emplace_back(std::move(Var));<br>
> -    } else {<br>
> -      // This variable goes in the main ProcSym.<br>
> -      CurFn->Locals.emplace_back(std::move(Var));<br>
> +    LocalVariable Var;<br>
> +    Var.DIVar = VI.Var;<br>
> +    Var.DefRanges.emplace_back(std::move(DefRange));<br>
> +    recordLocalVariable(std::move(Var), VI.Loc->getInlinedAt());<br>
> +  }<br>
> +}<br>
> +<br>
> +void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {<br>
> +  DenseSet<InlinedVariable> Processed;<br>
> +  // Grab the variable info that was squirreled away in the MMI side-table.<br>
> +  collectVariableInfoFromMMITable(Processed);<br>
> +<br>
> +  const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo();<br>
> +<br>
> +  for (const auto &I : DbgValues) {<br>
> +    InlinedVariable IV = I.first;<br>
> +    if (Processed.count(IV))<br>
> +      continue;<br>
> +    const DILocalVariable *DIVar = IV.first;<br>
> +    const DILocation *InlinedAt = IV.second;<br>
> +<br>
> +    // Instruction ranges, specifying where IV is accessible.<br>
> +    const auto &Ranges = I.second;<br>
> +<br>
> +    LexicalScope *Scope = nullptr;<br>
> +    if (InlinedAt)<br>
> +      Scope = LScopes.findInlinedScope(DIVar->getScope(), InlinedAt);<br>
> +    else<br>
> +      Scope = LScopes.findLexicalScope(DIVar->getScope());<br>
> +    // If variable scope is not found then skip this variable.<br>
> +    if (!Scope)<br>
> +      continue;<br>
> +<br>
> +    LocalVariable Var;<br>
> +    Var.DIVar = DIVar;<br>
> +<br>
> +    // Calculate the definition ranges.<br>
> +    for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {<br>
> +      const InsnRange &Range = *I;<br>
> +      const MachineInstr *DVInst = Range.first;<br>
> +      assert(DVInst->isDebugValue() && "Invalid History entry");<br>
> +      const DIExpression *DIExpr = DVInst->getDebugExpression();<br>
> +<br>
> +      // Bail if there is a complex DWARF expression for now.<br>
> +      if (DIExpr && DIExpr->getNumElements() > 0)<br>
> +        continue;<br>
> +<br>
> +      // Handle the two cases we can handle: indirect in memory and in register.<br>
> +      bool IsIndirect = DVInst->getOperand(1).isImm();<br>
> +      unsigned CVReg = TRI->getCodeViewRegNum(DVInst->getOperand(0).getReg());<br>
> +      {<br>
> +        LocalVarDefRange DefRange;<br>
> +        if (IsIndirect) {<br>
> +          int64_t Offset = DVInst->getOperand(1).getImm();<br>
> +          DefRange = createDefRangeMem(CVReg, Offset);<br>
> +        } else {<br>
> +          DefRange = createDefRangeReg(CVReg);<br>
> +        }<br>
> +        if (Var.DefRanges.empty() ||<br>
> +            Var.DefRanges.back().isDifferentLocation(DefRange)) {<br>
> +          Var.DefRanges.emplace_back(std::move(DefRange));<br>
> +        }<br>
> +      }<br>
> +<br>
> +      // Compute the label range.<br>
> +      const MCSymbol *Begin = getLabelBeforeInsn(Range.first);<br>
> +      const MCSymbol *End = getLabelAfterInsn(Range.second);<br>
> +      if (!End) {<br>
> +        if (std::next(I) != E)<br>
> +          End = getLabelBeforeInsn(std::next(I)->first);<br>
> +        else<br>
> +          End = Asm->getFunctionEnd();<br>
> +      }<br>
> +<br>
> +      // If the last range end is our begin, just extend the last range.<br>
> +      // Otherwise make a new range.<br>
> +      SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &Ranges =<br>
> +          Var.DefRanges.back().Ranges;<br>
> +      if (!Ranges.empty() && Ranges.back().second == Begin)<br>
> +        Ranges.back().second = End;<br>
> +      else<br>
> +        Ranges.emplace_back(Begin, End);<br>
> +<br>
> +      // FIXME: Do more range combining.<br>
>      }<br>
> +<br>
> +    recordLocalVariable(std::move(Var), InlinedAt);<br>
>    }<br>
>  }<br>
><br>
> @@ -572,6 +690,8 @@ void CodeViewDebug::emitLocalVariable(co<br>
>    uint16_t Flags = 0;<br>
>    if (Var.DIVar->isParameter())<br>
>      Flags |= LocalSym::IsParameter;<br>
> +  if (Var.DefRanges.empty())<br>
> +    Flags |= LocalSym::IsOptimizedOut;<br>
><br>
>    OS.AddComment("TypeIndex");<br>
>    OS.EmitIntValue(TypeIndex::Int32().getIndex(), 4);<br>
> @@ -580,28 +700,42 @@ void CodeViewDebug::emitLocalVariable(co<br>
>    emitNullTerminatedString(OS, Var.DIVar->getName());<br>
>    OS.EmitLabel(LocalEnd);<br>
><br>
> -  // DefRangeRegisterRelSym record, see SymbolRecord.h for more info.  Omit the<br>
> -  // LocalVariableAddrRange field from the record. The directive will emit that.<br>
> -  DefRangeRegisterRelSym Sym{};<br>
> -  ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER_REL);<br>
> -  Sym.BaseRegister = Var.CVRegister;<br>
> -  Sym.Flags = 0; // Unclear what matters here.<br>
> -  Sym.BasePointerOffset = Var.RegisterOffset;<br>
> -  SmallString<sizeof(Sym) + sizeof(SymKind) - sizeof(LocalVariableAddrRange)><br>
> -      BytePrefix;<br>
> -  BytePrefix += StringRef(reinterpret_cast<const char *>(&SymKind),<br>
> -                          sizeof(SymKind));<br>
> -  BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),<br>
> -                          sizeof(Sym) - sizeof(LocalVariableAddrRange));<br>
> +  // Calculate the on disk prefix of the appropriate def range record. The<br>
> +  // records and on disk formats are described in SymbolRecords.h. BytePrefix<br>
> +  // should be big enough to hold all forms without memory allocation.<br>
> +  SmallString<20> BytePrefix;<br>
> +  for (const LocalVarDefRange &DefRange : Var.DefRanges) {<br>
> +    BytePrefix.clear();<br>
> +    // FIXME: Handle bitpieces.<br>
> +    if (DefRange.StructOffset != 0)<br>
> +      continue;<br>
><br>
> -  OS.EmitCVDefRangeDirective(Var.Ranges, BytePrefix);<br>
> +    if (DefRange.InMemory) {<br>
> +      DefRangeRegisterRelSym Sym{};<br>
> +      ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER_REL);<br>
> +      Sym.BaseRegister = DefRange.CVRegister;<br>
> +      Sym.Flags = 0; // Unclear what matters here.<br>
> +      Sym.BasePointerOffset = DefRange.DataOffset;<br>
> +      BytePrefix +=<br>
> +          StringRef(reinterpret_cast<const char *>(&SymKind), sizeof(SymKind));<br>
> +      BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),<br>
> +                              sizeof(Sym) - sizeof(LocalVariableAddrRange));<br>
> +    } else {<br>
> +      assert(DefRange.DataOffset == 0 && "unexpected offset into register");<br>
> +      DefRangeRegisterSym Sym{};<br>
> +      ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER);<br>
> +      Sym.Register = DefRange.CVRegister;<br>
> +      Sym.MayHaveNoName = 0; // Unclear what matters here.<br>
> +      BytePrefix +=<br>
> +          StringRef(reinterpret_cast<const char *>(&SymKind), sizeof(SymKind));<br>
> +      BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),<br>
> +                              sizeof(Sym) - sizeof(LocalVariableAddrRange));<br>
> +    }<br>
> +    OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix);<br>
> +  }<br>
>  }<br>
><br>
>  void CodeViewDebug::endFunction(const MachineFunction *MF) {<br>
> -  collectVariableInfoFromMMITable();<br>
> -<br>
> -  DebugHandlerBase::endFunction(MF);<br>
> -<br>
>    if (!Asm || !CurFn)  // We haven't created any debug info for this function.<br>
>      return;<br>
><br>
> @@ -609,6 +743,10 @@ void CodeViewDebug::endFunction(const Ma<br>
>    assert(FnDebugInfo.count(GV));<br>
>    assert(CurFn == &FnDebugInfo[GV]);<br>
><br>
> +  collectVariableInfo(getDISubprogram(GV));<br>
> +<br>
> +  DebugHandlerBase::endFunction(MF);<br>
> +<br>
>    // Don't emit anything if we don't have any line tables.<br>
>    if (!CurFn->HaveLineInfo) {<br>
>      FnDebugInfo.erase(GV);<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=260746&r1=260745&r2=260746&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=260746&r1=260745&r2=260746&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h (original)<br>
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h Fri Feb 12 15:48:30 2016<br>
> @@ -35,13 +35,40 @@ class LexicalScope;<br>
>  class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {<br>
>    MCStreamer &OS;<br>
><br>
> +  /// Represents the most general definition range.<br>
> +  struct LocalVarDefRange {<br>
> +    /// Indicates that variable data is stored in memory relative to the<br>
> +    /// specified register.<br>
> +    int InMemory : 1;<br>
> +<br>
> +    /// Offset of variable data in memory.<br>
> +    int DataOffset : 31;<br>
<br>
Would it make sense to declare both of these as unsigned instead of<br>
int? It seems like they should both be positive.<br>
<br>
~Aaron<br>
<br>
> +<br>
> +    /// Offset of the data into the user level struct. If zero, no splitting<br>
> +    /// occurred.<br>
> +    uint16_t StructOffset;<br>
> +<br>
> +    /// Register containing the data or the register base of the memory<br>
> +    /// location containing the data.<br>
> +    uint16_t CVRegister;<br>
> +<br>
> +    /// Compares all location fields. This includes all fields except the label<br>
> +    /// ranges.<br>
> +    bool isDifferentLocation(LocalVarDefRange &O) {<br>
> +      return InMemory != O.InMemory || DataOffset != O.DataOffset ||<br>
> +             StructOffset != O.StructOffset || CVRegister != O.CVRegister;<br>
> +    }<br>
> +<br>
> +    SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges;<br>
> +  };<br>
> +<br>
> +  static LocalVarDefRange createDefRangeMem(uint16_t CVRegister, int Offset);<br>
> +  static LocalVarDefRange createDefRangeReg(uint16_t CVRegister);<br>
> +<br>
>    /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific.<br>
>    struct LocalVariable {<br>
>      const DILocalVariable *DIVar = nullptr;<br>
> -    SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges;<br>
> -    unsigned CVRegister = 0;<br>
> -    int RegisterOffset = 0;<br>
> -    // FIXME: Add support for DIExpressions.<br>
> +    SmallVector<LocalVarDefRange, 1> DefRanges;<br>
>    };<br>
><br>
>    struct InlineSite {<br>
> @@ -74,7 +101,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe<br>
><br>
>    unsigned NextFuncId = 0;<br>
><br>
> -  InlineSite &getInlineSite(const DILocation *Loc);<br>
> +  InlineSite &getInlineSite(const DILocation *InlinedAt,<br>
> +                            const DISubprogram *Inlinee);<br>
><br>
>    static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children,<br>
>                                          const FunctionInfo &FI,<br>
> @@ -123,7 +151,15 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe<br>
>    void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt,<br>
>                             const InlineSite &Site);<br>
><br>
> -  void collectVariableInfoFromMMITable();<br>
> +  typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;<br>
> +<br>
> +  void collectVariableInfo(const DISubprogram *SP);<br>
> +<br>
> +  void collectVariableInfoFromMMITable(DenseSet<InlinedVariable> &Processed);<br>
> +<br>
> +  /// Records information about a local variable in the appropriate scope. In<br>
> +  /// particular, locals from inlined code live inside the inlining site.<br>
> +  void recordLocalVariable(LocalVariable &&Var, const DILocation *Loc);<br>
><br>
>    void emitLocalVariable(const LocalVariable &Var);<br>
><br>
><br>
> Added: llvm/trunk/test/DebugInfo/COFF/register-variables.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/register-variables.ll?rev=260746&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/register-variables.ll?rev=260746&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/DebugInfo/COFF/register-variables.ll (added)<br>
> +++ llvm/trunk/test/DebugInfo/COFF/register-variables.ll Fri Feb 12 15:48:30 2016<br>
> @@ -0,0 +1,291 @@<br>
> +; RUN: llc < %s | FileCheck %s --check-prefix=ASM<br>
> +; RUN: llc < %s -filetype=obj | llvm-readobj -codeview - | FileCheck %s --check-prefix=OBJ<br>
> +<br>
> +; Generated from:<br>
> +; volatile int x;<br>
> +; int getint(void);<br>
> +; void putint(int);<br>
> +; static inline int inlineinc(int a) {<br>
> +;   int b = a + 1;<br>
> +;   ++x;<br>
> +;   return b;<br>
> +; }<br>
> +; void f(int p) {<br>
> +;   if (p) {<br>
> +;     int a = getint();<br>
> +;     int b = inlineinc(a);<br>
> +;     putint(b);<br>
> +;   } else {<br>
> +;     int c = getint();<br>
> +;     putint(c);<br>
> +;   }<br>
> +; }<br>
> +<br>
> +; ASM: f:                                      # @f<br>
> +; ASM: .Lfunc_begin0:<br>
> +; ASM: # BB#0:                                 # %entry<br>
> +; ASM:         pushq   %rsi<br>
> +; ASM:         subq    $32, %rsp<br>
> +; ASM:         #DEBUG_VALUE: f:p <- %ECX<br>
> +; ASM:         movl    %ecx, %esi<br>
> +; ASM: [[p_ecx_esi:\.Ltmp.*]]:<br>
> +; ASM:         #DEBUG_VALUE: f:p <- %ESI<br>
> +; ASM:         callq   getint<br>
> +; ASM: [[after_getint:\.Ltmp.*]]:<br>
> +; ASM:         #DEBUG_VALUE: a <- %EAX<br>
> +; ASM:         #DEBUG_VALUE: inlineinc:a <- %EAX<br>
> +; ASM:         #DEBUG_VALUE: c <- %EAX<br>
> +; ASM:         testl   %esi, %esi<br>
> +; ASM:         je      .LBB0_2<br>
> +; ASM: # BB#1:                                 # %if.then<br>
> +; ASM:         #DEBUG_VALUE: c <- %EAX<br>
> +; ASM:         #DEBUG_VALUE: inlineinc:a <- %EAX<br>
> +; ASM:         #DEBUG_VALUE: a <- %EAX<br>
> +; ASM:         #DEBUG_VALUE: f:p <- %ESI<br>
> +; ASM:         incl    %eax<br>
> +; ASM: [[after_inc_eax:\.Ltmp.*]]:<br>
> +; ASM:         #DEBUG_VALUE: inlineinc:b <- %EAX<br>
> +; ASM:         #DEBUG_VALUE: b <- %EAX<br>
> +; ASM:         incl    x(%rip)<br>
> +; ASM: [[after_if:\.Ltmp.*]]:<br>
> +; ASM: .LBB0_2:                                # %if.else<br>
> +; ASM:         #DEBUG_VALUE: f:p <- %ESI<br>
> +; ASM:         movl    %eax, %ecx<br>
> +; ASM:         addq    $32, %rsp<br>
> +; ASM:         popq    %rsi<br>
> +; ASM: [[func_end:\.Ltmp.*]]:<br>
> +; ASM:         rex64 jmp       putint          # TAILCALL<br>
> +<br>
> +; ASM:         .short  4414                    # Record kind: S_LOCAL<br>
> +; ASM:         .asciz  "p"<br>
> +; ASM:         .cv_def_range    .Lfunc_begin0 [[p_ecx_esi]], "A\021\022\000\000\000"<br>
> +; ASM:         .cv_def_range    [[p_ecx_esi]] [[func_end]], "A\021\027\000\000\000"<br>
> +; ASM:         .short  4414                    # Record kind: S_LOCAL<br>
> +; ASM:         .asciz  "a"<br>
> +; ASM:         .cv_def_range    [[after_getint]] [[after_inc_eax]], "A\021\021\000\000\000"<br>
> +; ASM:         .short  4414                    # Record kind: S_LOCAL<br>
> +; ASM:         .asciz  "c"<br>
> +; ASM:         .cv_def_range    [[after_getint]] [[after_inc_eax]], "A\021\021\000\000\000"<br>
> +; ASM:         .short  4414                    # Record kind: S_LOCAL<br>
> +; ASM:         .asciz  "b"<br>
> +; ASM:         .cv_def_range    [[after_inc_eax]] [[after_if]], "A\021\021\000\000\000"<br>
> +<br>
> +; ASM:         .short  4429                    # Record kind: S_INLINESITE<br>
> +; ASM:         .short  4414                    # Record kind: S_LOCAL<br>
> +; ASM:         .asciz  "a"<br>
> +; ASM:         .cv_def_range    [[after_getint]] [[after_inc_eax]], "A\021\021\000\000\000"<br>
> +; ASM:         .short  4414                    # Record kind: S_LOCAL<br>
> +; ASM:         .asciz  "b"<br>
> +; ASM:         .cv_def_range    [[after_inc_eax]] [[after_if]], "A\021\021\000\000\000"<br>
> +; ASM:         .short  4430                    # Record kind: S_INLINESITE_END<br>
> +<br>
> +; OBJ: Subsection [<br>
> +; OBJ:   SubSectionType: Symbols (0xF1)<br>
> +; OBJ:   ProcStart {<br>
> +; OBJ:     DisplayName: f<br>
> +; OBJ:   }<br>
> +; OBJ:   Local {<br>
> +; OBJ:     Type: int (0x74)<br>
> +; OBJ:     Flags [ (0x1)<br>
> +; OBJ:       IsParameter (0x1)<br>
> +; OBJ:     ]<br>
> +; OBJ:     VarName: p<br>
> +; OBJ:   }<br>
> +; OBJ:   DefRangeRegister {<br>
> +; OBJ:     Register: 18<br>
> +; OBJ:     LocalVariableAddrRange {<br>
> +; OBJ:       OffsetStart: .text+0x0<br>
> +; OBJ:       ISectStart: 0x0<br>
> +; OBJ:       Range: 0x7<br>
> +; OBJ:     }<br>
> +; OBJ:   }<br>
> +; OBJ:   DefRangeRegister {<br>
> +; OBJ:     Register: 23<br>
> +; OBJ:     LocalVariableAddrRange {<br>
> +; OBJ:       OffsetStart: .text+0x7<br>
> +; OBJ:       ISectStart: 0x0<br>
> +; OBJ:       Range: 0x18<br>
> +; OBJ:     }<br>
> +; OBJ:   }<br>
> +; OBJ:   Local {<br>
> +; OBJ:     Type: int (0x74)<br>
> +; OBJ:     Flags [ (0x0)<br>
> +; OBJ:     ]<br>
> +; OBJ:     VarName: a<br>
> +; OBJ:   }<br>
> +; OBJ:   DefRangeRegister {<br>
> +; OBJ:     Register: 17<br>
> +; OBJ:     LocalVariableAddrRange {<br>
> +; OBJ:       OffsetStart: .text+0xC<br>
> +; OBJ:       ISectStart: 0x0<br>
> +; OBJ:       Range: 0x6<br>
> +; OBJ:     }<br>
> +; OBJ:   }<br>
> +; OBJ:   Local {<br>
> +; OBJ:     Type: int (0x74)<br>
> +; OBJ:     Flags [ (0x0)<br>
> +; OBJ:     ]<br>
> +; OBJ:     VarName: c<br>
> +; OBJ:   }<br>
> +; OBJ:   DefRangeRegister {<br>
> +; OBJ:     Register: 17<br>
> +; OBJ:     LocalVariableAddrRange {<br>
> +; OBJ:       OffsetStart: .text+0xC<br>
> +; OBJ:       ISectStart: 0x0<br>
> +; OBJ:       Range: 0x6<br>
> +; OBJ:     }<br>
> +; OBJ:   }<br>
> +; OBJ:   Local {<br>
> +; OBJ:     Type: int (0x74)<br>
> +; OBJ:     Flags [ (0x0)<br>
> +; OBJ:     ]<br>
> +; OBJ:     VarName: b<br>
> +; OBJ:   }<br>
> +; OBJ:   DefRangeRegister {<br>
> +; OBJ:     Register: 17<br>
> +; OBJ:     LocalVariableAddrRange {<br>
> +; OBJ:       OffsetStart: .text+0x12<br>
> +; OBJ:       ISectStart: 0x0<br>
> +; OBJ:       Range: 0x6<br>
> +; OBJ:     }<br>
> +; OBJ:   }<br>
> +; OBJ:   InlineSite {<br>
> +; OBJ:     PtrParent: 0x0<br>
> +; OBJ:     PtrEnd: 0x0<br>
> +; OBJ:     Inlinee: inlineinc (0x1003)<br>
> +; OBJ:   }<br>
> +; OBJ:   Local {<br>
> +; OBJ:     Type: int (0x74)<br>
> +; OBJ:     Flags [ (0x1)<br>
> +; OBJ:       IsParameter (0x1)<br>
> +; OBJ:     ]<br>
> +; OBJ:     VarName: a<br>
> +; OBJ:   }<br>
> +; OBJ:   DefRangeRegister {<br>
> +; OBJ:     Register: 17<br>
> +; OBJ:     LocalVariableAddrRange {<br>
> +; OBJ:       OffsetStart: .text+0xC<br>
> +; OBJ:       ISectStart: 0x0<br>
> +; OBJ:       Range: 0x6<br>
> +; OBJ:     }<br>
> +; OBJ:   }<br>
> +; OBJ:   Local {<br>
> +; OBJ:     Type: int (0x74)<br>
> +; OBJ:     Flags [ (0x0)<br>
> +; OBJ:     ]<br>
> +; OBJ:     VarName: b<br>
> +; OBJ:   }<br>
> +; OBJ:   DefRangeRegister {<br>
> +; OBJ:     Register: 17<br>
> +; OBJ:     LocalVariableAddrRange {<br>
> +; OBJ:       OffsetStart: .text+0x12<br>
> +; OBJ:       ISectStart: 0x0<br>
> +; OBJ:       Range: 0x6<br>
> +; OBJ:     }<br>
> +; OBJ:   }<br>
> +; OBJ:   InlineSiteEnd {<br>
> +; OBJ:   }<br>
> +; OBJ:   ProcEnd<br>
> +; OBJ: ]<br>
> +<br>
> +; ModuleID = 't.cpp'<br>
> +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"<br>
> +target triple = "x86_64-pc-windows-msvc18.0.0"<br>
> +<br>
> +@x = internal global i32 0, align 4<br>
> +<br>
> +; Function Attrs: nounwind uwtable<br>
> +define void @f(i32 %p) #0 !dbg !4 {<br>
> +entry:<br>
> +  tail call void @llvm.dbg.value(metadata i32 %p, i64 0, metadata !9, metadata !29), !dbg !30<br>
> +  %tobool = icmp eq i32 %p, 0, !dbg !31<br>
> +  %call2 = tail call i32 @getint() #3, !dbg !32<br>
> +  br i1 %tobool, label %if.else, label %if.then, !dbg !33<br>
> +<br>
> +if.then:                                          ; preds = %entry<br>
> +  tail call void @llvm.dbg.value(metadata i32 %call2, i64 0, metadata !10, metadata !29), !dbg !34<br>
> +  tail call void @llvm.dbg.value(metadata i32 %call2, i64 0, metadata !20, metadata !29), !dbg !35<br>
> +  %add.i = add nsw i32 %call2, 1, !dbg !37<br>
> +  tail call void @llvm.dbg.value(metadata i32 %add.i, i64 0, metadata !21, metadata !29), !dbg !38<br>
> +  %0 = load volatile i32, i32* @x, align 4, !dbg !39, !tbaa !40<br>
> +  %inc.i = add nsw i32 %0, 1, !dbg !39<br>
> +  store volatile i32 %inc.i, i32* @x, align 4, !dbg !39, !tbaa !40<br>
> +  tail call void @llvm.dbg.value(metadata i32 %add.i, i64 0, metadata !13, metadata !29), !dbg !44<br>
> +  tail call void @putint(i32 %add.i) #3, !dbg !45<br>
> +  br label %if.end, !dbg !46<br>
> +<br>
> +if.else:                                          ; preds = %entry<br>
> +  tail call void @llvm.dbg.value(metadata i32 %call2, i64 0, metadata !14, metadata !29), !dbg !47<br>
> +  tail call void @putint(i32 %call2) #3, !dbg !48<br>
> +  br label %if.end<br>
> +<br>
> +if.end:                                           ; preds = %if.else, %if.then<br>
> +  ret void, !dbg !49<br>
> +}<br>
> +<br>
> +declare i32 @getint() #1<br>
> +<br>
> +declare void @putint(i32) #1<br>
> +<br>
> +; Function Attrs: nounwind readnone<br>
> +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2<br>
> +<br>
> +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" }<br>
> +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" }<br>
> +attributes #2 = { nounwind readnone }<br>
> +attributes #3 = { nounwind }<br>
> +<br>
> +!<a href="http://llvm.dbg.cu" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
> +!llvm.module.flags = !{!25, !26, !27}<br>
> +!llvm.ident = !{!28}<br>
> +<br>
> +!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)<br>
> +!1 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvm\5Cbuild")<br>
> +!2 = !{}<br>
> +!3 = !{!4, !16}<br>
> +!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)<br>
> +!5 = !DISubroutineType(types: !6)<br>
> +!6 = !{null, !7}<br>
> +!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)<br>
> +!8 = !{!9, !10, !13, !14}<br>
> +!9 = !DILocalVariable(name: "p", arg: 1, scope: !4, file: !1, line: 9, type: !7)<br>
> +!10 = !DILocalVariable(name: "a", scope: !11, file: !1, line: 11, type: !7)<br>
> +!11 = distinct !DILexicalBlock(scope: !12, file: !1, line: 10, column: 10)<br>
> +!12 = distinct !DILexicalBlock(scope: !4, file: !1, line: 10, column: 7)<br>
> +!13 = !DILocalVariable(name: "b", scope: !11, file: !1, line: 12, type: !7)<br>
> +!14 = !DILocalVariable(name: "c", scope: !15, file: !1, line: 15, type: !7)<br>
> +!15 = distinct !DILexicalBlock(scope: !12, file: !1, line: 14, column: 10)<br>
> +!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)<br>
> +!17 = !DISubroutineType(types: !18)<br>
> +!18 = !{!7, !7}<br>
> +!19 = !{!20, !21}<br>
> +!20 = !DILocalVariable(name: "a", arg: 1, scope: !16, file: !1, line: 4, type: !7)<br>
> +!21 = !DILocalVariable(name: "b", scope: !16, file: !1, line: 5, type: !7)<br>
> +!22 = !{!23}<br>
> +!23 = !DIGlobalVariable(name: "x", scope: !0, file: !1, line: 1, type: !24, isLocal: false, isDefinition: true, variable: i32* @x)<br>
> +!24 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !7)<br>
> +!25 = !{i32 2, !"CodeView", i32 1}<br>
> +!26 = !{i32 2, !"Debug Info Version", i32 3}<br>
> +!27 = !{i32 1, !"PIC Level", i32 2}<br>
> +!28 = !{!"clang version 3.9.0 (trunk 260617) (llvm/trunk 260619)"}<br>
> +!29 = !DIExpression()<br>
> +!30 = !DILocation(line: 9, column: 12, scope: !4)<br>
> +!31 = !DILocation(line: 10, column: 7, scope: !12)<br>
> +!32 = !DILocation(line: 15, column: 13, scope: !15)<br>
> +!33 = !DILocation(line: 10, column: 7, scope: !4)<br>
> +!34 = !DILocation(line: 11, column: 9, scope: !11)<br>
> +!35 = !DILocation(line: 4, column: 33, scope: !16, inlinedAt: !36)<br>
> +!36 = distinct !DILocation(line: 12, column: 13, scope: !11)<br>
> +!37 = !DILocation(line: 5, column: 13, scope: !16, inlinedAt: !36)<br>
> +!38 = !DILocation(line: 5, column: 7, scope: !16, inlinedAt: !36)<br>
> +!39 = !DILocation(line: 6, column: 3, scope: !16, inlinedAt: !36)<br>
> +!40 = !{!41, !41, i64 0}<br>
> +!41 = !{!"int", !42, i64 0}<br>
> +!42 = !{!"omnipotent char", !43, i64 0}<br>
> +!43 = !{!"Simple C/C++ TBAA"}<br>
> +!44 = !DILocation(line: 12, column: 9, scope: !11)<br>
> +!45 = !DILocation(line: 13, column: 5, scope: !11)<br>
> +!46 = !DILocation(line: 14, column: 3, scope: !11)<br>
> +!47 = !DILocation(line: 15, column: 9, scope: !15)<br>
> +!48 = !DILocation(line: 16, column: 5, scope: !15)<br>
> +!49 = !DILocation(line: 18, column: 1, scope: !4)<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</div>