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

Missing !dbg locations in generated LLVM IR #3904

Merged
merged 4 commits into from Jan 20, 2017

Conversation

ysbaddaden
Copy link
Contributor

This allows to compile the Crystal compiler itself using Crystal 0.20.4 with the default debug configuration (always generate line numbers) against LLVM 3.9, which requires a !dbg location to be defined for every inlinable calls (among other cases).

I separated each commit, so each correction can be reviewed more easily.

fixes #3890

@ysbaddaden
Copy link
Contributor Author

ysbaddaden commented Jan 16, 2017

I can also build/run the compiler and std specs with those fixes. Hopefully, there aren't that much more cases...?

@spalladino spalladino added this to the Next milestone Jan 16, 2017
@@ -638,7 +638,7 @@ module Crystal
end
end

Call.new(cond, "===", right_side).at(obj)
Call.new(cond, "===", right_side)
Copy link
Contributor

Choose a reason for hiding this comment

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

Quick question: why is this no longer needed? (asking just out of curiosity, as I'm not particularly familiar with this part of the compiler)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Other paths don't set it, and we always override it in expand.

@spalladino
Copy link
Contributor

@ysbaddaden the build seems to be failing. I think that after that's fixed we are good to merge this PR.

@bcardiff
Copy link
Member

I restarted the build. I was unable to repro the failures even with jhass docker image used in ci.

Note: jhass docker images use LLVM 3.8

@@ -103,7 +103,7 @@ module Crystal
break if end_token?
end

Expressions.from(exps)
Expressions.from(exps).at(exps.first)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

CI fails because of this patch.

The root problem is that the following:

def foo
rescue # or ensure
end

Is being expanded to:

def foo
  begin # <= missing location
  rescue
  end
end

but the generated begin block is missing a location, then LLVM 3.9 module validation fails because some calls to fun like __crystal_get_exception or __crystal_raise are missing a !dbg location. The above fixes the bug, by making sure the body has a position (set to be the one of its first expression).

  • Maybe that should be done at some other place? Like at the place where the begin block is injected. The problem is, I have no idea where :'(
  • Maybe we should fix the failing cases?

I don't know what to do, 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.

Note that I reproduce the CI failure locally (Ubuntu 14.04, LLVM 3.9 apt repository).

Copy link
Member

@asterite asterite Jan 20, 2017

Choose a reason for hiding this comment

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

The specs seem to get fixed with this patch:

diff --git a/src/compiler/crystal/syntax/ast.cr b/src/compiler/crystal/syntax/ast.cr
index 687d6df..1cd9538 100644
--- a/src/compiler/crystal/syntax/ast.cr
+++ b/src/compiler/crystal/syntax/ast.cr
@@ -138,6 +138,10 @@ module Crystal
       @expressions.last
     end
 
+    def location
+      @location || @expressions.first?.try &.location
+    end
+
     def end_location
       @end_location || @expressions.last?.try &.end_location
     end
diff --git a/src/compiler/crystal/syntax/parser.cr b/src/compiler/crystal/syntax/parser.cr
index 127ab72..1d3883e 100644
--- a/src/compiler/crystal/syntax/parser.cr
+++ b/src/compiler/crystal/syntax/parser.cr
@@ -103,7 +103,7 @@ module Crystal
         break if end_token?
       end
 
-      Expressions.from(exps).at(exps.first)
+      Expressions.from(exps)
     end
 
     def parse_multi_assign

Expressions already had an overload for end_location that returned that of the last expression, but we were missing one for location as well.

I didn't check if it still fixed the missing !dbg issue, but I guess it does.

C struct setters automatically convert the assigned value, but
failed to provide a location for the conversion (the setters are
automatically generated).
@ysbaddaden
Copy link
Contributor Author

ysbaddaden commented Jan 20, 2017

@asterite you nailed it! Now I can build Crystal in release mode with llvm 3.9 and specs are passing.

@spalladino
Copy link
Contributor

Awesome! This deserves a release ;-)

@spalladino spalladino merged commit b5f0e5a into crystal-lang:master Jan 20, 2017
@ysbaddaden ysbaddaden deleted the fix-missing-dbg-locations branch January 20, 2017 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't build Crystal in release mode (LLVM >= 3.9)
4 participants