Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

impl -gline-tables-only #1861

Merged
merged 19 commits into from
Nov 12, 2016
Merged

Conversation

rtbo
Copy link
Contributor

@rtbo rtbo commented Oct 27, 2016

implementation of -gline-tables-only flag per #1844

@LemonBoy
Copy link
Contributor

The tests are failing due to this llvm change.
Using auto would help the readability.

}
llvm_unreachable("unknown DebugEmissionKind");
#else
return global.params.symdebug < 2 ?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes the level 0 emit the line informations too. As you can see here it should be possible to have the same effect by setting EmitDebugInfo to false.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Level 0 should not output any debug info, also not line numbers, so that needs to be fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

err... somehow i thought the OP was commenting on his own code. Sorry to duplicate your comment @LemonBoy :(

@JohanEngelen
Copy link
Member

We have to be careful if we are changing the meaning of the (integer) value of global.params.symdebug, which is a parameter possibly used by the DDMD FE.

Have you thought a little about what the behavior should be of cmdline parameters and orderings like this?
-g -gline-tables-only
-g -gline-tables-only -g
-gline-tables-only -g
-gline-tables-only -gc
-gline-tables-only -gc -gline-tables-only

@rtbo
Copy link
Contributor Author

rtbo commented Oct 29, 2016

In regards to cmdline parameters ordering it is the latest of the -g* params that prevail.
No change from previous behavior when there was only -g and -gc.
A warning or error would be more appropriate I guess in case of multiple -g* params given.

@rtbo
Copy link
Contributor Author

rtbo commented Oct 29, 2016

there are still a few lines of code like this in driver/linker.cpp:

  // because of a LLVM bug, see LDC issue 442
  if (global.params.symdebug) {
    args.push_back("/LARGEADDRESSAWARE:NO");
  } else {
    args.push_back("/LARGEADDRESSAWARE");
  }

  // output debug information
  if (global.params.symdebug) {
    args.push_back("/DEBUG");
  }

Not sure which args must be passed to the linker with -gline-tables-only.

@JohanEngelen
Copy link
Member

A warning or error would be more appropriate I guess in case of multiple -g* params given.

I think it can be helpful to allow multiple -g flags without complaining about it. I just wanted to check that you had thought about what the behavior should be (in contrast to what it is at the moment). I think Clang does the same as what you are doing btw, so should be fine.

This still needs a number of tests!

@rtbo
Copy link
Contributor Author

rtbo commented Oct 30, 2016

CircleCI fails due to this change in llvm.
Unrelated to -gline-tables-only.

@rtbo
Copy link
Contributor Author

rtbo commented Oct 31, 2016

This still needs a number of tests!

Tested with llvm-3.6.2 and llvm-3.9.1, this simple test do not pass

// RUN: %ldc -gline-tables-only --output-ll -of%t.ll %s && FileCheck %s < %t.ll
// Checks that ldc with -gline-tables-only do not emit debug info

int main()
{
    immutable int fact=6;
    int res=1;
    for(int i=1; i<=fact; i++) res *= i;
    return res;
}

// CHECK-NOT: DW_TAG

Also tested the 2 following tests, adapted from clang, none of them pass:

// RUN: %ldc -gline-tables-only --output-ll -of%t.ll %s && FileCheck %s < %t.ll
// Checks that ldc with "-gline-tables-only" emits metadata for
// compile unit, subprogram and file.

int main() {
  // CHECK: ret i32 0, !dbg
  return 0;
}

// CHECK: !llvm.dbg.cu = !{!0}
// CHECK: !DICompileUnit(
// CHECK: !DISubprogram(
// CHECK: !DIFile(
// RUN: %ldc -gline-tables-only --output-ll -c %s -of%t.ll && FileCheck %s < %t.ll
// Checks that ldc with "-gline-tables-only" doesn't emit debug info
// for variables and types.

// CHECK-NOT: DW_TAG_variable
int global = 42;

// CHECK-NOT: DW_TAG_typedef
// CHECK-NOT: DW_TAG_const_type
// CHECK-NOT: DW_TAG_pointer_type
// CHECK-NOT: DW_TAG_array_type
alias constCharPtrArray = const(char)*[10];

// CHECK-NOT: DW_TAG_structure_type
struct S {
  // CHECK-NOT: DW_TAG_member
  char a;
  double b;
  constCharPtrArray c;
}

// CHECK-NOT: DW_TAG_enumerator
// CHECK-NOT: DW_TAG_enumeration_type
enum E { ZERO = 0, ONE = 1 }

// CHECK-NOT: DILocalVariable
int sum(int p, int q) {
  int r = p + q;
  S s;
  E e;
  return r;
}

@JohanEngelen
Copy link
Member

Need help with those tests @rtbo ?

@rtbo
Copy link
Contributor Author

rtbo commented Nov 2, 2016

Need help with those tests @rtbo ?

I've figured out for the dwarf tags. tests/debuginfo/gline_tables_only2.d is still failing the same.

@rtbo
Copy link
Contributor Author

rtbo commented Nov 3, 2016

Oops, cadbac0 also strips almost all metadata, which removes all effects of -gline-tables-only.

rtbo added 2 commits November 3, 2016 22:57
 - check for type attributes absence
 - on LDC compile unit is not the first metadata
@rtbo
Copy link
Contributor Author

rtbo commented Nov 3, 2016

Better now.
Still have noise dwarf emission for functions return types (makes debuginfo/gline_tables_only2.d fail).

@rtbo
Copy link
Contributor Author

rtbo commented Nov 4, 2016

Passes with llvm-3.9 only

@rtbo
Copy link
Contributor Author

rtbo commented Nov 4, 2016

Reason of test failure is that emitted metadata in IR code is far different form one version of LLVM to another.
Here is metadata emitted with llvm-3.9.1:

!llvm.module.flags = !{!0, !1}
!llvm.dbg.cu = !{!3}
!llvm.ident = !{!5}

!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = !{i32 6, !"Linker Options", !2}
!2 = !{}
!3 = distinct !DICompileUnit(language: DW_LANG_D, file: !4, producer: "LDC (http://wiki.dlang.org/LDC)", isOptimized: false, runtimeVersion: 1, emissionKind: LineTablesOnly, enums: !2)
!4 = !DIFile(filename: "factorial.d", directory: "/opt/dev/test/factorial")
!5 = !{!"ldc version e9a486"}
!6 = distinct !DISubprogram(name: "D main", linkageName: "_Dmain", scope: null, file: !4, line: 2, type: !7, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !3, variables: !2)
!7 = !DISubroutineType(types: !2)
!8 = !DILocation(line: 4, column: 5, scope: !6)
!9 = !DILocation(line: 5, column: 5, scope: !6)
!10 = !DILocation(line: 6, column: 9, scope: !11)
!11 = distinct !DILexicalBlock(scope: !6, file: !4, line: 6, column: 5)
!12 = !DILocation(line: 6, column: 5, scope: !13)
!13 = distinct !DILexicalBlock(scope: !11, file: !4, line: 6, column: 5)
!14 = !DILocation(line: 7, column: 9, scope: !13)
!15 = !DILocation(line: 8, column: 5, scope: !6)
!16 = distinct !DISubprogram(name: "__entrypoint.main", linkageName: "main", scope: null, file: !17, line: 6, type: !7, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !3, variables: !2)
!17 = !DIFile(filename: "__entrypoint.d", directory: "/opt/dev/test/factorial")
!18 = !DILocation(line: 6, column: 15, scope: !16)
!19 = !DILocation(line: 8, column: 15, scope: !16)

and here for same code with llvm-3.6.2:

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!3}

!0 = !{i32 2, !"Debug Info Version", i32 2}
!1 = !{i32 6, !"Linker Options", !2}
!2 = !{}
!3 = !{!"ldc version e9a486"}
!4 = !MDLocation(line: 4, column: 5, scope: !5)
!5 = !{!"0x2e\00D main\00D main\00_Dmain\002\000\001\000\000\00256\000\002", !6, null, !7, null, i32 ({ i64, { i64, i8* }* })* @_Dmain, null, null, !2} ; [ DW_TAG_subprogram ] [line 2] [def] [D main]
!6 = !{!"factorial.d", !"/opt/dev/test/factorial"}
!7 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!8 = !MDLocation(line: 5, column: 5, scope: !5)
!9 = !MDLocation(line: 6, column: 9, scope: !10)
!10 = !{!"0xb\006\005\000", !6, !5}               ; [ DW_TAG_lexical_block ] [/opt/dev/test/factorial/factorial.d]
!11 = !MDLocation(line: 6, column: 5, scope: !12)
!12 = !{!"0xb\006\005\001", !6, !10}              ; [ DW_TAG_lexical_block ] [/opt/dev/test/factorial/factorial.d]
!13 = !MDLocation(line: 7, column: 9, scope: !12)
!14 = !MDLocation(line: 8, column: 5, scope: !5)
!15 = !MDLocation(line: 6, column: 15, scope: !16)
!16 = !{!"0x2e\00__entrypoint.main\00__entrypoint.main\00main\006\000\001\000\000\00256\000\006", !17, null, !7, null, i32 (i32, i8**)* @main, null, null, !2} ; [ DW_TAG_subprogram ] [line 6] [def] [__entrypoint.main]
!17 = !{!"__entrypoint.d", !"/opt/dev/test/factorial"}
!18 = !MDLocation(line: 8, column: 15, scope: !16)

I limited the tests to llvm >= 3.9 at the moment. (Shortest path, I admit).
Is there a good reason to make more tests for other llvm versions? My point is that a regression will be seen in the llvm-3.9 tests anyway.
And are the tests for 3.9 enough in the first place?

@JohanEngelen
Copy link
Member

I think testing for >=3.9 is fine.

@kinke kinke mentioned this pull request Nov 7, 2016
typedef llvm::DIBuilder::DebugEmissionKind DebugEmissionKind;
#endif

DebugEmissionKind getDebugEmissionKind()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may be able to get rid of the typedef (using is preferred btw) when using auto as return type here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto return type needs a tail expression, which makes code messy with the switch.
using is used in f65b73c.

@@ -724,19 +777,28 @@ void ldc::DIBuilder::EmitCompileUnit(Module *m) {
IR->module.addModuleFlag(llvm::Module::Warning, "Debug Info Version",
llvm::DEBUG_METADATA_VERSION);


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing code vestige. Correction sneaked in 3761775.

@@ -857,10 +920,9 @@ ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
auto paramsArray = DBuilder.getOrCreateArray(params);
#endif
#if LDC_LLVM_VER >= 308
ldc::DISubroutineType DIFnType = DBuilder.createSubroutineType(paramsArray);
ldc::DISubroutineType DIFnType = DBuilder.createSubroutineType(paramsArray);
Copy link
Member

@kinke kinke Nov 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[My] clang-format disagrees; same for line 925.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#else
ldc::DISubroutineType DIFnType =
DBuilder.createSubroutineType(file, paramsArray);
ldc::DISubroutineType DIFnType = DBuilder.createSubroutineType(file, paramsArray);
Copy link
Member

@kinke kinke Nov 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Longer than 80 chars. Using auto keeps it in a single line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -1174,7 +1236,7 @@ void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar,
}

void ldc::DIBuilder::Finalize() {
if (!mustEmitDebugInfo())
if (!mustEmitFullDebugInfo() && !mustEmitLocationsDebugInfo())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only !mustEmitLocationsDebugInfo() as used everywhere else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intent was to make obvious that Finalize must be called for all debug info cases. But yes, it comes to the same. ba5002a

// CHECK: !DICompileUnit(
// CHECK: !DISubprogram(
// CHECK: !DIFile(
// CHECK-NOT: DW_AT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing trailing newline (I know I'm pedantic). Are you aware that the non-existence of DW_AT is restricted to all lines following the previous !DIFile( match?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I was not aware. Thanks for pointing it out.
9c122f2.

@JohanEngelen JohanEngelen merged commit 3b63eff into ldc-developers:master Nov 12, 2016
@JohanEngelen
Copy link
Member

Great stuff.
Nice work on the tests.

(squashed and merged)

@rtbo rtbo deleted the gline-tables-only branch November 12, 2016 19:59
dnadlinger pushed a commit that referenced this pull request Nov 24, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants