[llvm] r226598 - Reapply: Teach SROA how to update debug info for fragmented variables.
Adrian Prantl
aprantl at apple.com
Fri Jan 23 07:59:04 PST 2015
> On Jan 23, 2015, at 2:15 AM, Hao Liu <Hao.Liu at arm.com> wrote:
>
> Hi Adrian,
>
> I observe a crash caused by this commit on our internal tests. Without "-g"
> the test can be built successfully. This original case is a little difficult
> to be simplified. I will work on reproducer.
That would be great!
> Just let you know so that maybe you can find the root cause and fix it.
In order to diagnose the problem, it might be sufficient information if you could just to just invoke ->dump() on the type that is passed into isUnsignedDIType(). We may simply need to add another TAG to this list.
thanks,
-- adrian
>
> clang-3.7: ./llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:592: bool
> isUnsignedDIType(llvm::DwarfDebug*, llvm::DIType): Assertion `T ==
> dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type || T ==
> dwarf::DW_TAG_volatile_type || T == dwarf::DW_TAG_restrict_type || T ==
> dwarf::DW_TAG_enumeration_type' failed.
> #0 0x1d27f90 llvm::sys::PrintStackTrace(_IO_FILE*)
> ./llvm/lib/Support/Unix/Signals.inc:423:0
> #1 0x1d2822b PrintStackTraceSignalHandler(void*)
> ./llvm/lib/Support/Unix/Signals.inc:481:0
> #2 0x1d26e4d SignalHandler(int) ./llvm/lib/Support/Unix/Signals.inc:198:0
> #3 0x7ffaa3f5f340 __restore_rt
> (/lib/x86_64-linux-gnu/libpthread.so.0+0x10340)
> #4 0x7ffaa3186cc9 gsignal
> /build/buildd/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:
> 0
> #5 0x7ffaa318a0d8 abort /build/buildd/eglibc-2.19/stdlib/abort.c:91:0
> #6 0x7ffaa317fb86 __assert_fail_base
> /build/buildd/eglibc-2.19/assert/assert.c:92:0
> #7 0x7ffaa317fc32 (/lib/x86_64-linux-gnu/libc.so.6+0x2fc32)
> #8 0x207f2b5 isUnsignedDIType(llvm::DwarfDebug*, llvm::DIType)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:593:0
> #9 0x207f300 isUnsignedDIType(llvm::DwarfDebug*, llvm::DIType)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:594:0
> #10 0x207f8a4 llvm::DwarfUnit::addConstantValue(llvm::DIE&,
> llvm::MachineOperand const&, llvm::DIType)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:686:0
> #11 0x20ad32e
> llvm::DwarfCompileUnit::constructVariableDIEImpl(llvm::DbgVariable const&,
> bool) ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:508:0
> #12 0x20ad081
> llvm::DwarfCompileUnit::constructVariableDIE(llvm::DbgVariable&, bool)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:472:0
> #13 0x20ad50f
> llvm::DwarfCompileUnit::constructVariableDIE(llvm::DbgVariable&,
> llvm::LexicalScope const&, llvm::DIE*&)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:535:0
> #14 0x20ad623
> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&, unsigned int*)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:546:0
> #15 0x20ac41c llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:346:0
> #16 0x20ad6f0
> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&, unsigned int*)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
> #17 0x20ac41c llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:346:0
> #18 0x20ad6f0
> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&, unsigned int*)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
> #19 0x20ac3cd llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:333:0
> #20 0x20ad6f0
> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&, unsigned int*)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
> #21 0x20ac41c llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:346:0
> #22 0x20ad6f0
> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&, unsigned int*)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
> #23 0x20ac41c llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:346:0
> #24 0x20ad6f0
> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
> std::default_delete<llvm::DIE> > >&, unsigned int*)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
> #25 0x20ada2d
> llvm::DwarfCompileUnit::createAndAddScopeChildren(llvm::LexicalScope*,
> llvm::DIE&) ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:593:0
> #26 0x20ad8f1
> llvm::DwarfCompileUnit::constructSubprogramScopeDIE(llvm::LexicalScope*)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:577:0
> #27 0x20562e7 llvm::DwarfDebug::endFunction(llvm::MachineFunction const*)
> ./llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:1306:0
> #28 0x203ec5a llvm::AsmPrinter::EmitFunctionBody()
> ./llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:887:0
> #29 0x12c03dd llvm::AsmPrinter::runOnMachineFunction(llvm::MachineFunction&)
> ./llvm/include/llvm/CodeGen/AsmPrinter.h:189:0
> #30 0x12c0604 (anonymous
> namespace)::AArch64AsmPrinter::runOnMachineFunction(llvm::MachineFunction&)
> ./llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp:89:0
> #31 0x1661c9d llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
> ./llvm/lib/CodeGen/MachineFunctionPass.cpp:34:0
> #32 0x198a476 llvm::FPPassManager::runOnFunction(llvm::Function&)
> ./llvm/lib/IR/LegacyPassManager.cpp:1530:0
> #33 0x198a5e6 llvm::FPPassManager::runOnModule(llvm::Module&)
> ./llvm/lib/IR/LegacyPassManager.cpp:1550:0
> #34 0x198a904 (anonymous
> namespace)::MPPassManager::runOnModule(llvm::Module&)
> ./llvm/lib/IR/LegacyPassManager.cpp:1608:0
> #35 0x198afa8 llvm::legacy::PassManagerImpl::run(llvm::Module&)
> ./llvm/lib/IR/LegacyPassManager.cpp:1715:0
> #36 0x198b1c7 llvm::legacy::PassManager::run(llvm::Module&)
> ./llvm/lib/IR/LegacyPassManager.cpp:1749:0
> #37 0x2292b3b (anonymous
> namespace)::EmitAssemblyHelper::EmitAssembly(clang::BackendAction,
> llvm::raw_ostream*) ./llvm/tools/clang/lib/CodeGen/BackendUtil.cpp:634:0
> #38 0x2292c0a clang::EmitBackendOutput(clang::DiagnosticsEngine&,
> clang::CodeGenOptions const&, clang::TargetOptions const&,
> clang::LangOptions const&, llvm::StringRef, llvm::Module*,
> clang::BackendAction, llvm::raw_ostream*)
> ./llvm/tools/clang/lib/CodeGen/BackendUtil.cpp:650:0
> #39 0x22785ec
> clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&)
> ./llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp:178:0
> #40 0x2caa57a clang::ParseAST(clang::Sema&, bool, bool)
> ./llvm/tools/clang/lib/Parse/ParseAST.cpp:153:0
> #41 0x1f24938 clang::ASTFrontendAction::ExecuteAction()
> ./llvm/tools/clang/lib/Frontend/FrontendAction.cpp:528:0
> #42 0x227aab7 clang::CodeGenAction::ExecuteAction()
> ./llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp:728:0
> #43 0x1f24413 clang::FrontendAction::Execute()
> ./llvm/tools/clang/lib/Frontend/FrontendAction.cpp:432:0
> #44 0x1eeda94 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)
> ./llvm/tools/clang/lib/Frontend/CompilerInstance.cpp:812:0
> #45 0x20356b5 clang::ExecuteCompilerInvocation(clang::CompilerInstance*)
> ./llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:222:0
> #46 0x10d8d66 cc1_main(llvm::ArrayRef<char const*>, char const*, void*)
> ./llvm/tools/clang/tools/driver/cc1_main.cpp:110:0
> #47 0x10d1522 ExecuteCC1Tool(llvm::ArrayRef<char const*>, llvm::StringRef) .
> /llvm/tools/clang/tools/driver/driver.cpp:369:0
> #48 0x10d1b04 main ./llvm/tools/clang/tools/driver/driver.cpp:415:0
> #49 0x7ffaa3171ec5 __libc_start_main
> /build/buildd/eglibc-2.19/csu/libc-start.c:321:0
> #50 0x10ce559 _start (./llvm/2build/bin/clang-3.7+0x10ce559)
>
>>> -----Original Message-----
>>> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
>>> bounces at cs.uiuc.edu] On Behalf Of Adrian Prantl
>>> Sent: 2015年1月21日 3:42
>>> To: llvm-commits at cs.uiuc.edu
>>> Subject: [llvm] r226598 - Reapply: Teach SROA how to update debug info for
>>> fragmented variables.
>>>
>>> Author: adrian
>>> Date: Tue Jan 20 13:42:22 2015
>>> New Revision: 226598
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=226598&view=rev
>>> Log:
>>> Reapply: Teach SROA how to update debug info for fragmented variables.
>>> This reapplies r225379.
>>>
>>> ChangeLog:
>>> - The assertion that this commit previously ran into about the inability
>>> to handle indirect variables has since been removed and the backend
>>> can handle this now.
>>> - Testcases were upgrade to the new MDLocation format.
>>> - Instead of keeping a DebugDeclares map, we now use
>>> llvm::FindAllocaDbgDeclare().
>>>
>>> Original commit message follows.
>>>
>>> Debug info: Teach SROA how to update debug info for fragmented variables.
>>> This allows us to generate debug info for extremely advanced code such as
>>>
>>> typedef struct { long int a; int b;} S;
>>>
>>> int foo(S s) {
>>> return s.b;
>>> }
>>>
>>> which at -O1 on x86_64 is codegen'd into
>>>
>>> define i32 @foo(i64 %s.coerce0, i32 %s.coerce1) #0 {
>>> ret i32 %s.coerce1, !dbg !24
>>> }
>>>
>>> with this patch we emit the following debug info for this
>>>
>>> TAG_formal_parameter [3]
>>> AT_location( 0x00000000
>>> 0x0000000000000000 - 0x0000000000000006: rdi, piece
>>> 0x00000008, rsi, piece 0x00000004
>>> 0x0000000000000006 - 0x0000000000000008: rdi, piece
>>> 0x00000008, rax, piece 0x00000004 )
>>> AT_name( "s" )
>>> AT_decl_file(
> "/Volumes/Data/llvm/_build.ninja.release/test.c" )
>>>
>>> Thanks to chandlerc, dblaikie, and echristo for their feedback on all
> previous
>>> iterations of this patch!
>>>
>>> Added:
>>> llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll
>>> llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll
>>> llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll
>>> Modified:
>>> llvm/trunk/lib/Transforms/Scalar/SROA.cpp
>>> llvm/trunk/test/DebugInfo/X86/array2.ll
>>>
>>> Modified: llvm/trunk/lib/Transforms/Scalar/SROA.cpp
>>> URL: http://llvm.org/viewvc/llvm-
>>> project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=226598&r1=226597
>>> &r2=226598&view=diff
>>> ===============================================================
>>> ===============
>>> --- llvm/trunk/lib/Transforms/Scalar/SROA.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp Tue Jan 20 13:42:22 2015
>>> @@ -1257,8 +1257,8 @@ private:
>>> friend class AllocaSliceRewriter;
>>>
>>> bool presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS);
>>> - bool rewritePartition(AllocaInst &AI, AllocaSlices &AS,
>>> - AllocaSlices::Partition &P);
>>> + AllocaInst *rewritePartition(AllocaInst &AI, AllocaSlices &AS,
>>> + AllocaSlices::Partition &P);
>>> bool splitAlloca(AllocaInst &AI, AllocaSlices &AS);
>>> bool runOnAlloca(AllocaInst &AI);
>>> void clobberUse(Use &U);
>>> @@ -3964,8 +3964,8 @@ bool SROA::presplitLoadsAndStores(Alloca
>>> /// appropriate new offsets. It also evaluates how successful the rewrite
> was
>>> /// at enabling promotion and if it was successful queues the alloca to be
> ///
>>> promoted.
>>> -bool SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
>>> - AllocaSlices::Partition &P) {
>>> +AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
>>> + AllocaSlices::Partition &P) {
>>> // Try to compute a friendly type for this partition of the alloca.
> This
>>> // won't always succeed, in which case we fall back to a legal integer
> type
>>> // or an i8 array of an appropriate size.
>>> @@ -4003,6 +4003,7 @@ bool SROA::rewritePartition(AllocaInst &
>>> NewAI = &AI;
>>> // FIXME: We should be able to bail at this point with "nothing
> changed".
>>> // FIXME: We might want to defer PHI speculation until after here.
>>> + // FIXME: return nullptr;
>>> } else {
>>> unsigned Alignment = AI.getAlignment();
>>> if (!Alignment) {
>>> @@ -4098,7 +4099,7 @@ bool SROA::rewritePartition(AllocaInst &
>>> PostPromotionWorklist.pop_back();
>>> }
>>>
>>> - return true;
>>> + return NewAI;
>>> }
>>>
>>> /// \brief Walks the slices of an alloca and form partitions based on
> them,
>>> @@ -4137,9 +4138,24 @@ bool SROA::splitAlloca(AllocaInst &AI, A
>>> if (!IsSorted)
>>> std::sort(AS.begin(), AS.end());
>>>
>>> + /// \brief Describes the allocas introduced by rewritePartition ///
>>> + in order to migrate the debug info.
>>> + struct Piece {
>>> + AllocaInst *Alloca;
>>> + uint64_t Offset;
>>> + uint64_t Size;
>>> + Piece(AllocaInst *AI, uint64_t O, uint64_t S)
>>> + : Alloca(AI), Offset(O), Size(S) {} }; SmallVector<Piece, 4>
>>> + Pieces;
>>> +
>>> // Rewrite each partition.
>>> for (auto &P : AS.partitions()) {
>>> - Changed |= rewritePartition(AI, AS, P);
>>> + if (AllocaInst *NewAI = rewritePartition(AI, AS, P)) {
>>> + Changed = true;
>>> + if (NewAI != &AI)
>>> + Pieces.push_back(Piece(NewAI, P.beginOffset(), P.size()));
>>> + }
>>> ++NumPartitions;
>>> }
>>>
>>> @@ -4147,6 +4163,28 @@ bool SROA::splitAlloca(AllocaInst &AI, A
>>> MaxPartitionsPerAlloca =
>>> std::max<unsigned>(NumPartitions, MaxPartitionsPerAlloca);
>>>
>>> + // Migrate debug information from the old alloca to the new alloca(s)
>>> + // and the individial partitions.
>>> + if (DbgDeclareInst *DbgDecl = FindAllocaDbgDeclare(&AI)) {
>>> + DIVariable Var(DbgDecl->getVariable());
>>> + DIExpression Expr(DbgDecl->getExpression());
>>> + DIBuilder DIB(*AI.getParent()->getParent()->getParent(),
>>> + /*AllowUnresolved*/ false);
>>> + bool IsSplit = Pieces.size() > 1;
>>> + for (auto Piece : Pieces) {
>>> + // Create a piece expression describing the new partition or reuse
> AI's
>>> + // expression if there is only one partition.
>>> + if (IsSplit)
>>> + Expr = DIB.createPieceExpression(Piece.Offset, Piece.Size);
>>> +
>>> + // Remove any existing dbg.declare intrinsic describing the same
> alloca.
>>> + if (DbgDeclareInst *OldDDI = FindAllocaDbgDeclare(Piece.Alloca))
>>> + OldDDI->eraseFromParent();
>>> +
>>> + Instruction *NewDDI = DIB.insertDeclare(Piece.Alloca, Var, Expr,
> &AI);
>>> + NewDDI->setDebugLoc(DbgDecl->getDebugLoc());
>>> + }
>>> + }
>>> return Changed;
>>> }
>>>
>>> @@ -4258,8 +4296,11 @@ void SROA::deleteDeadInstructions(
>>> DeadInsts.insert(U);
>>> }
>>>
>>> - if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
>>> + if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
>>> DeletedAllocas.insert(AI);
>>> + if (DbgDeclareInst *DbgDecl = FindAllocaDbgDeclare(AI))
>>> + DbgDecl->eraseFromParent();
>>> + }
>>>
>>> ++NumDeleted;
>>> I->eraseFromParent();
>>> @@ -4376,9 +4417,10 @@ bool SROA::runOnFunction(Function &F) {
>>>
>>> BasicBlock &EntryBB = F.getEntryBlock();
>>> for (BasicBlock::iterator I = EntryBB.begin(), E =
> std::prev(EntryBB.end());
>>> - I != E; ++I)
>>> + I != E; ++I) {
>>> if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
>>> Worklist.insert(AI);
>>> + }
>>>
>>> bool Changed = false;
>>> // A set of deleted alloca instruction pointers which should be removed
> from
>>>
>>> Modified: llvm/trunk/test/DebugInfo/X86/array2.ll
>>> URL: http://llvm.org/viewvc/llvm-
>>> project/llvm/trunk/test/DebugInfo/X86/array2.ll?rev=226598&r1=226597&r2
>>> =226598&view=diff
>>> ===============================================================
>>> ===============
>>> --- llvm/trunk/test/DebugInfo/X86/array2.ll (original)
>>> +++ llvm/trunk/test/DebugInfo/X86/array2.ll Tue Jan 20 13:42:22 2015
>>> @@ -13,12 +13,12 @@
>>> ; }
>>> ;
>>> ; RUN: opt %s -O2 -S -o - | FileCheck %s -; Test that we do not lower
>>> dbg.declares for arrays.
>>> +; Test that we correctly lower dbg.declares for arrays.
>>> ;
>>> ; CHECK: define i32 @main
>>> -; CHECK: call void @llvm.dbg.value
>>> -; CHECK: call void @llvm.dbg.value
>>> -; CHECK: call void @llvm.dbg.declare
>>> +; CHECK: call void @llvm.dbg.value(metadata i32 42, i64 0, metadata
>>> +![[ARRAY:[0-9]+]], metadata ![[EXPR:[0-9]+]]) ; CHECK: ![[ARRAY]] =
>>> +{{.*}}; [ DW_TAG_auto_variable ] [array] [line 6] ; CHECK: ![[EXPR]] =
>>> +{{.*}}; [ DW_TAG_expression ] [DW_OP_piece offset=0, size=4]
>>> target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>> target triple = "x86_64-apple-macosx10.9.0"
>>>
>>>
>>> Added: llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll
>>> URL: http://llvm.org/viewvc/llvm-
>>> project/llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll?rev=226598&view=auto
>>> ===============================================================
>>> ===============
>>> --- llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll (added)
>>> +++ llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll Tue Jan 20 13:42:22
>>> +++ 2015
>>> @@ -0,0 +1,97 @@
>>> +; RUN: opt %s -sroa -verify -S -o - | FileCheck %s ; ; Test that we can
>>> +partial emit debug info for aggregates repeatedly ; split up by SROA.
>>> +;
>>> +; // Compile with -O1
>>> +; typedef struct {
>>> +; int a;
>>> +; long int b;
>>> +; } Inner;
>>> +;
>>> +; typedef struct {
>>> +; Inner inner[2];
>>> +; } Outer;
>>> +;
>>> +; int foo(Outer outer) {
>>> +; Inner i1 = outer.inner[1];
>>> +; return i1.a;
>>> +; }
>>> +;
>>> +
>>> +; Verify that SROA creates a variable piece when splitting i1.
>>> +; CHECK: %[[I1:.*]] = alloca [12 x i8], align 4 ; CHECK: call void
>>> + at llvm.dbg.declare(metadata [12 x i8]* %[[I1]], metadata
>>> +![[VAR:[0-9]+]], metadata ![[PIECE1:[0-9]+]]) ; CHECK: call void
>>> + at llvm.dbg.value(metadata i32 %[[A:.*]], i64 0, metadata ![[VAR]],
>>> +metadata ![[PIECE2:[0-9]+]]) ; CHECK: ret i32 %[[A]] ; Read Var and
> Piece:
>>> +; CHECK: ![[VAR]] = {{.*}} ; [ DW_TAG_auto_variable ] [i1] [line 11] ;
>>> +CHECK: ![[PIECE1]] = {{.*}} ; [ DW_TAG_expression ] [DW_OP_piece
>>> +offset=4, size=12] ; CHECK: ![[PIECE2]] = {{.*}} ; [ DW_TAG_expression
>>> +] [DW_OP_piece offset=0, size=4]
>>> +
>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>> +target triple = "x86_64-apple-macosx10.9.0"
>>> +
>>> +%struct.Outer = type { [2 x %struct.Inner] } %struct.Inner = type {
>>> +i32, i64 }
>>> +
>>> +; Function Attrs: nounwind ssp uwtable
>>> +define i32 @foo(%struct.Outer* byval align 8 %outer) #0 {
>>> +entry:
>>> + %i1 = alloca %struct.Inner, align 8
>>> + call void @llvm.dbg.declare(metadata %struct.Outer* %outer, metadata
>>> +!25, metadata !2), !dbg !26
>>> + call void @llvm.dbg.declare(metadata %struct.Inner* %i1, metadata
>>> +!27, metadata !2), !dbg !28
>>> + %inner = getelementptr inbounds %struct.Outer* %outer, i32 0, i32 0,
>>> +!dbg !28
>>> + %arrayidx = getelementptr inbounds [2 x %struct.Inner]* %inner, i32
>>> +0, i64 1, !dbg !28
>>> + %0 = bitcast %struct.Inner* %i1 to i8*, !dbg !28
>>> + %1 = bitcast %struct.Inner* %arrayidx to i8*, !dbg !28
>>> + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 16, i32 8,
>>> +i1 false), !dbg !28
>>> + %a = getelementptr inbounds %struct.Inner* %i1, i32 0, i32 0, !dbg
>>> +!29
>>> + %2 = load i32* %a, align 4, !dbg !29
>>> + ret i32 %2, !dbg !29
>>> +}
>>> +
>>> +; Function Attrs: nounwind readnone
>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>> +
>>> +; Function Attrs: nounwind
>>> +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture
>>> +readonly, i64, i32, i1) #2
>>> +
>>> +attributes #0 = { nounwind ssp uwtable } attributes #1 = { nounwind
>>> +readnone } attributes #2 = { nounwind }
>>> +
>>> +!llvm.dbg.cu = !{!0}
>>> +!llvm.module.flags = !{!22, !23}
>>> +!llvm.ident = !{!24}
>>> +
>>> +!0 = !{!"0x11\0012\00clang version 3.5.0 \000\00\000\00\001", !1, !2,
>>> +!2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [ DW_TAG_compile_unit ]
>>> +[sroasplit-1.c] [DW_LANG_C99]
>>> +!1 = !{!"sroasplit-1.c", !""}
>>> +!2 = !{}
>>> +!3 = !{!4}
>>> +!4 = !{!"0x2e\00foo\00foo\00\0010\000\001\000\006\00256\000\0010", !1,
>>> +!5, !6, null, i32 (%struct.Outer*)* @foo, null, null, !2} ; [
>>> +DW_TAG_subprogram ] [ DW_TAG_subprogram ] [line 10] [def] [foo]
>>> +!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [ DW_TAG_file_type ]
>>> +[sroasplit-1.c]
>>> +!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null,
>>> +null, null} ; [ DW_TAG_subroutine_type ] [ DW_TAG_subroutine_type ]
>>> +[line 0, size 0, align 0, offset 0] [from ]
>>> +!7 = !{!8, !9}
>>> +!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [
>>> +DW_TAG_base_type ] [ DW_TAG_base_type ] [int] [line 0, size 32, align
>>> +32, offset 0, enc DW_ATE_signed]
>>> +!9 = !{!"0x16\00Outer\008\000\000\000\000", !1, null, !10} ; [
>>> +DW_TAG_typedef ] [ DW_TAG_typedef ] [Outer] [line 8, size 0, align 0,
>>> +offset 0] [from ]
>>> +!10 = !{!"0x13\00\006\00256\0064\000\000\000", !1, null, null, !11,
>>> +null, null, null} ; [ DW_TAG_structure_type ] [line 6, size 256, align
>>> +64, offset 0] [def] [from ]
>>> +!11 = !{!12}
>>> +!12 = !{!"0xd\00inner\007\00256\0064\000\000", !1, !10, !13} ; [
>>> +DW_TAG_member ] [inner] [line 7, size 256, align 64, offset 0] [from ]
>>> +!13 = !{!"0x1\00\000\00256\0064\000\000", null, null, !14, !20, i32 0,
>>> +null, null, null} ; [ DW_TAG_array_type ] [line 0, size 256, align 64,
>>> +offset 0] [from Inner]
>>> +!14 = !{!"0x16\00Inner\004\000\000\000\000", !1, null, !15} ; [
>>> +DW_TAG_typedef ] [ DW_TAG_typedef ] [Inner] [line 4, size 0, align 0,
>>> +offset 0] [from ]
>>> +!15 = !{!"0x13\00\001\00128\0064\000\000\000", !1, null, null, !16,
>>> +null, null, null} ; [ DW_TAG_structure_type ] [line 1, size 128, align
>>> +64, offset 0] [def] [from ]
>>> +!16 = !{!17, !18}
>>> +!17 = !{!"0xd\00a\002\0032\0032\000\000", !1, !15, !8} ; [
>>> +DW_TAG_member ] [a] [line 2, size 32, align 32, offset 0] [from int]
>>> +!18 = !{!"0xd\00b\003\0064\0064\0064\000", !1, !15, !19} ; [
>>> +DW_TAG_member ] [b] [line 3, size 64, align 64, offset 64] [from long
>>> +int]
>>> +!19 = !{!"0x24\00long int\000\0064\0064\000\000\005", null, null} ; [
>>> +DW_TAG_base_type ] [ DW_TAG_base_type ] [long int] [line 0, size 64,
>>> +align 64, offset 0, enc DW_ATE_signed]
>>> +!20 = !{!21}
>>> +!21 = !{!"0x21\000\002"} ; [ DW_TAG_subrange_type ] [0, 1]
>>> +!22 = !{i32 2, !"Dwarf Version", i32 2}
>>> +!23 = !{i32 1, !"Debug Info Version", i32 2}
>>> +!24 = !{!"clang version 3.5.0 "}
>>> +!25 = !{!"0x101\00outer\0016777226\000", !4, !5, !9} ; [
>>> +DW_TAG_arg_variable ] [ DW_TAG_arg_variable ] [outer] [line 10]
>>> +!26 = !MDLocation(line: 10, scope: !4)
>>> +!27 = !{!"0x100\00i1\0011\000", !4, !5, !14} ; [ DW_TAG_auto_variable ]
>>> +[ DW_TAG_auto_variable ] [i1] [line 11]
>>> +!28 = !MDLocation(line: 11, scope: !4)
>>> +!29 = !MDLocation(line: 12, scope: !4)
>>>
>>> Added: llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll
>>> URL: http://llvm.org/viewvc/llvm-
>>> project/llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll?rev=226598&view=auto
>>> ===============================================================
>>> ===============
>>> --- llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll (added)
>>> +++ llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll Tue Jan 20 13:42:22
>>> +++ 2015
>>> @@ -0,0 +1,102 @@
>>> +; RUN: opt %s -sroa -verify -S -o - | FileCheck %s ; ; Test that we can
>>> +partial emit debug info for aggregates repeatedly ; split up by SROA.
>>> +;
>>> +; // Compile with -O1
>>> +; typedef struct {
>>> +; int a;
>>> +; int b;
>>> +; } Inner;
>>> +;
>>> +; typedef struct {
>>> +; Inner inner[2];
>>> +; } Outer;
>>> +;
>>> +; int foo(Outer outer) {
>>> +; Inner i1 = outer.inner[1];
>>> +; return i1.a;
>>> +; }
>>> +;
>>> +
>>> +; Verify that SROA creates a variable piece when splitting i1.
>>> +; CHECK: call void @llvm.dbg.value(metadata i64 %outer.coerce0, i64 0,
>>> +metadata ![[O:[0-9]+]], metadata ![[PIECE1:[0-9]+]]), ; CHECK: call
>>> +void @llvm.dbg.value(metadata i64 %outer.coerce1, i64 0, metadata
>>> +![[O]], metadata ![[PIECE2:[0-9]+]]), ; CHECK: call void
>>> + at llvm.dbg.value({{.*}}, i64 0, metadata ![[I1:[0-9]+]], metadata
>>> +![[PIECE3:[0-9]+]]), ; CHECK-DAG: ![[O]] = {{.*}} [ DW_TAG_arg_variable
>>> +] [outer] [line 10] ; CHECK-DAG: ![[PIECE1]] = {{.*}} [
>>> +DW_TAG_expression ] [DW_OP_piece offset=0, size=8] ; CHECK-DAG:
>>> +![[PIECE2]] = {{.*}} [ DW_TAG_expression ] [DW_OP_piece offset=8,
>>> +size=8] ; CHECK-DAG: ![[I1]] = {{.*}} [ DW_TAG_auto_variable ] [i1]
>>> +[line 11] ; CHECK-DAG: ![[PIECE3]] = {{.*}} [ DW_TAG_expression ]
>>> +[DW_OP_piece offset=0, size=4]
>>> +
>>> +; ModuleID = 'sroasplit-2.c'
>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>> +target triple = "x86_64-apple-macosx10.9.0"
>>> +
>>> +%struct.Outer = type { [2 x %struct.Inner] } %struct.Inner = type {
>>> +i32, i32 }
>>> +
>>> +; Function Attrs: nounwind ssp uwtable
>>> +define i32 @foo(i64 %outer.coerce0, i64 %outer.coerce1) #0 {
>>> + %outer = alloca %struct.Outer, align 8
>>> + %i1 = alloca %struct.Inner, align 4
>>> + %1 = bitcast %struct.Outer* %outer to { i64, i64 }*
>>> + %2 = getelementptr { i64, i64 }* %1, i32 0, i32 0
>>> + store i64 %outer.coerce0, i64* %2
>>> + %3 = getelementptr { i64, i64 }* %1, i32 0, i32 1
>>> + store i64 %outer.coerce1, i64* %3
>>> + call void @llvm.dbg.declare(metadata %struct.Outer* %outer, metadata
>>> +!24, metadata !2), !dbg !25
>>> + call void @llvm.dbg.declare(metadata %struct.Inner* %i1, metadata
>>> +!26, metadata !2), !dbg !27
>>> + %4 = getelementptr inbounds %struct.Outer* %outer, i32 0, i32 0, !dbg
>>> +!27
>>> + %5 = getelementptr inbounds [2 x %struct.Inner]* %4, i32 0, i64 1,
>>> +!dbg !27
>>> + %6 = bitcast %struct.Inner* %i1 to i8*, !dbg !27
>>> + %7 = bitcast %struct.Inner* %5 to i8*, !dbg !27
>>> + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %6, i8* %7, i64 8, i32 4, i1
>>> +false), !dbg !27
>>> + %8 = getelementptr inbounds %struct.Inner* %i1, i32 0, i32 0, !dbg
>>> +!28
>>> + %9 = load i32* %8, align 4, !dbg !28
>>> + ret i32 %9, !dbg !28
>>> +}
>>> +
>>> +; Function Attrs: nounwind readnone
>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>> +
>>> +; Function Attrs: nounwind
>>> +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture
>>> +readonly, i64, i32, i1) #2
>>> +
>>> +attributes #0 = { nounwind ssp uwtable "no-frame-pointer-elim"="true" }
>>> +attributes #1 = { nounwind readnone } attributes #2 = { nounwind }
>>> +
>>> +!llvm.dbg.cu = !{!0}
>>> +!llvm.module.flags = !{!21, !22}
>>> +!llvm.ident = !{!23}
>>> +
>>> +!0 = !{!"0x11\0012\00clang version 3.5.0 \000\00\000\00\001", !1, !2,
>>> +!2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [ DW_TAG_compile_unit ]
>>> +[sroasplit-2.c] [DW_LANG_C99]
>>> +!1 = !{!"sroasplit-2.c", !""}
>>> +!2 = !{}
>>> +!3 = !{!4}
>>> +!4 = !{!"0x2e\00foo\00foo\00\0010\000\001\000\006\00256\000\0010", !1,
>>> +!5, !6, null, i32 (i64, i64)* @foo, null, null, !2} ; [
>>> +DW_TAG_subprogram ] [ DW_TAG_subprogram ] [line 10] [def] [foo]
>>> +!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [ DW_TAG_file_type ]
>>> +[sroasplit-2.c]
>>> +!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null,
>>> +null, null} ; [ DW_TAG_subroutine_type ] [ DW_TAG_subroutine_type ]
>>> +[line 0, size 0, align 0, offset 0] [from ]
>>> +!7 = !{!8, !9}
>>> +!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [
>>> +DW_TAG_base_type ] [ DW_TAG_base_type ] [int] [line 0, size 32, align
>>> +32, offset 0, enc DW_ATE_signed]
>>> +!9 = !{!"0x16\00Outer\008\000\000\000\000", !1, null, !10} ; [
>>> +DW_TAG_typedef ] [ DW_TAG_typedef ] [Outer] [line 8, size 0, align 0,
>>> +offset 0] [from ]
>>> +!10 = !{!"0x13\00\006\00128\0032\000\000\000", !1, null, null, !11,
>>> +null, null, null} ; [ DW_TAG_structure_type ] [line 6, size 128, align
>>> +32, offset 0] [def] [from ]
>>> +!11 = !{!12}
>>> +!12 = !{!"0xd\00inner\007\00128\0032\000\000", !1, !10, !13} ; [
>>> +DW_TAG_member ] [inner] [line 7, size 128, align 32, offset 0] [from ]
>>> +!13 = !{!"0x1\00\000\00128\0032\000\000", null, null, !14, !19, i32 0,
>>> +null, null, null} ; [ DW_TAG_array_type ] [line 0, size 128, align 32,
>>> +offset 0] [from Inner]
>>> +!14 = !{!"0x16\00Inner\004\000\000\000\000", !1, null, !15} ; [
>>> +DW_TAG_typedef ] [ DW_TAG_typedef ] [Inner] [line 4, size 0, align 0,
>>> +offset 0] [from ]
>>> +!15 = !{!"0x13\00\001\0064\0032\000\000\000", !1, null, null, !16,
>>> +null, null, null} ; [ DW_TAG_structure_type ] [line 1, size 64, align
>>> +32, offset 0] [def] [from ]
>>> +!16 = !{!17, !18}
>>> +!17 = !{!"0xd\00a\002\0032\0032\000\000", !1, !15, !8} ; [
>>> +DW_TAG_member ] [a] [line 2, size 32, align 32, offset 0] [from int]
>>> +!18 = !{!"0xd\00b\003\0032\0032\0032\000", !1, !15, !8} ; [
>>> +DW_TAG_member ] [b] [line 3, size 32, align 32, offset 32] [from int]
>>> +!19 = !{!20}
>>> +!20 = !{!"0x21\000\002"} ; [ DW_TAG_subrange_type ] [0, 1]
>>> +!21 = !{i32 2, !"Dwarf Version", i32 2}
>>> +!22 = !{i32 1, !"Debug Info Version", i32 2}
>>> +!23 = !{!"clang version 3.5.0 "}
>>> +!24 = !{!"0x101\00outer\0016777226\000", !4, !5, !9} ; [
>>> +DW_TAG_arg_variable ] [ DW_TAG_arg_variable ] [outer] [line 10]
>>> +!25 = !MDLocation(line: 10, scope: !4)
>>> +!26 = !{!"0x100\00i1\0011\000", !4, !5, !14} ; [ DW_TAG_auto_variable ]
>>> +[ DW_TAG_auto_variable ] [i1] [line 11]
>>> +!27 = !MDLocation(line: 11, scope: !4)
>>> +!28 = !MDLocation(line: 12, scope: !4)
>>>
>>> Added: llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll
>>> URL: http://llvm.org/viewvc/llvm-
>>> project/llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll?rev=226598&view=auto
>>> ===============================================================
>>> ===============
>>> --- llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll (added)
>>> +++ llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll Tue Jan 20 13:42:22
>>> +++ 2015
>>> @@ -0,0 +1,63 @@
>>> +; RUN: opt %s -sroa -verify -S -o - | FileCheck %s ; ModuleID =
>>> +'test.c'
>>> +; Test that SROA updates the debug info correctly if an alloca was
>>> +rewritten but ; not partitioned into multiple allocas.
>>> +;
>>> +; CHECK: call void @llvm.dbg.value(metadata float %s.coerce, i64 0,
>>> +metadata ![[VAR:[0-9]+]], metadata ![[EXPR:[0-9]+]]) ; CHECK: ![[VAR]]
>>> += {{.*}} [ DW_TAG_arg_variable ] [s] [line 3] ; CHECK: ![[EXPR]] =
>>> +{{.*}} [ DW_TAG_expression ] ; CHECK-NOT: DW_OP_piece
>>> +
>>> +;
>>> +; struct S { float f; };
>>> +;
>>> +; float foo(struct S s) {
>>> +; return s.f;
>>> +; }
>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>> +target triple = "x86_64-apple-macosx10.10.0"
>>> +
>>> +%struct.S = type { float }
>>> +
>>> +; Function Attrs: nounwind ssp uwtable
>>> +define float @foo(float %s.coerce) #0 {
>>> +entry:
>>> + %s = alloca %struct.S, align 4
>>> + %coerce.dive = getelementptr %struct.S* %s, i32 0, i32 0
>>> + store float %s.coerce, float* %coerce.dive, align 1
>>> + call void @llvm.dbg.declare(metadata %struct.S* %s, metadata !16,
>>> +metadata !17), !dbg !18
>>> + %f = getelementptr inbounds %struct.S* %s, i32 0, i32 0, !dbg !19
>>> + %0 = load float* %f, align 4, !dbg !19
>>> + ret float %0, !dbg !19
>>> +}
>>> +
>>> +; Function Attrs: nounwind readnone
>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>> +
>>> +attributes #0 = { nounwind ssp uwtable } attributes #1 = { nounwind
>>> +readnone }
>>> +
>>> +!llvm.dbg.cu = !{!0}
>>> +!llvm.module.flags = !{!12, !13, !14}
>>> +!llvm.ident = !{!15}
>>> +
>>> +!0 = !{!"0x11\0012\00clang version 3.6.0 \000\00\000\00\001", !1, !2,
>>> +!2, !3, !2, !2} ; [ DW_TAG_compile_unit ]
>>> +[/Volumes/Data/llvm/_build.ninja.debug/test.c] [DW_LANG_C99]
>>> +!1 = !{!"test.c", !"/Volumes/Data/llvm/_build.ninja.debug"}
>>> +!2 = !{}
>>> +!3 = !{!4}
>>> +!4
>>> = !{!"0x2e\00foo\00foo\00\003\000\001\000\000\00256\000\003", !1, !5, !6,
>>> null, float (float)* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line
> 3] [def]
>>> [foo]
>>> +!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ]
>>> [/Volumes/Data/llvm/_build.ninja.debug/test.c]
>>> +!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !7, null,
>>> +null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0,
>>> +offset 0] [from ]
>>> +!7 = !{!8, !9}
>>> +!8 = !{!"0x24\00float\000\0032\0032\000\000\004", null, null} ; [
>>> +DW_TAG_base_type ] [float] [line 0, size 32, align 32, offset 0, enc
>>> +DW_ATE_float]
>>> +!9 = !{!"0x13\00S\001\0032\0032\000\000\000", !1, null, null, !10,
>>> +null, null, null} ; [ DW_TAG_structure_type ] [S] [line 1, size 32,
>>> +align 32, offset 0] [def] [from ]
>>> +!10 = !{!11}
>>> +!11 = !{!"0xd\00f\001\0032\0032\000\000", !1, !9, !8} ; [ DW_TAG_member
>>> +] [f] [line 1, size 32, align 32, offset 0] [from float]
>>> +!12 = !{i32 2, !"Dwarf Version", i32 2}
>>> +!13 = !{i32 2, !"Debug Info Version", i32 2}
>>> +!14 = !{i32 1, !"PIC Level", i32 2}
>>> +!15 = !{!"clang version 3.6.0 "}
>>> +!16 = !{!"0x101\00s\0016777219\000", !4, !5, !9} ; [ DW_TAG_arg_variable
> ]
>>> [s] [line 3]
>>> +!17 = !{!"0x102"} ; [ DW_TAG_expression ]
>>> +!18 = !MDLocation(line: 3, column: 20, scope: !4)
>>> +!19 = !MDLocation(line: 4, column: 2, scope: !4)
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
>
>
More information about the llvm-commits
mailing list