[llvm] r260746 - [codeview] Describe local variables in registers
Aaron Ballman via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 15 07:17:24 PST 2016
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