Skip to content

Commit

Permalink
[GH #853] Enable proper llvm probes
Browse files Browse the repository at this point in the history
enable compilation probes
add the --llvm-config option and handle it
print the detected version (silent 1 as fallback)
detect static llvm libs
handle the debian testing default case (appended -version)
handle the llvm 3.2 new --version format
set proper llvm_{c,cxx,ld}flags and llvm_libs config keys for opsc_llvm integration
try given cc for a llvm-gcc or clang compatible compiler
check the output of -emit-llvm by file magic inspection
  ld: warning: cannot find entry symbol 'mit-llvm'
  • Loading branch information
Reini Urban committed Oct 2, 2012
1 parent 87ac5ce commit 132f7c7
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 34 deletions.
105 changes: 75 additions & 30 deletions config/auto/llvm.pm
Expand Up @@ -46,13 +46,21 @@ sub runstep {
# runstep() with a value of 1. If a given probe does not rule out LLVM,
# we will proceed onward.

my ($llvm_bindir, $llvm_config);
for my $bin (qw(llvm-config llvm-config-3.0 llvm-config-2.9 llvm-config-2.8)) {
$llvm_bindir = capture_output( $bin, "--bindir" ) || '';
my $llvm_config = $conf->options->get( 'llvm-config' );
my $llvm_bindir;
if ( $llvm_config and -e "$llvm_config" ) {
$llvm_bindir = capture_output( $llvm_config, "--bindir" ) || '';
chomp $llvm_bindir;
if ( $llvm_bindir ) {
$llvm_config = $bin;
last;
}
else {
for my $ver ('',qw(-3.2 -3.1 -3.0 -2.9 -2.8 -2.7)) {
my $bin = 'llvm-config'.$ver;
$llvm_bindir = capture_output( $bin, "--bindir" ) || '';
chomp $llvm_bindir;
if ( $llvm_bindir ) {
$llvm_config = $bin;
last;
}
}
}
if (! $llvm_bindir ) {
Expand All @@ -65,20 +73,25 @@ sub runstep {
chomp(@output = `"$llvm_bindir/lli" --version`);
my $rv = $self->version_check($conf, \@output, $verbose);
return 1 unless $rv;
my $version = $rv;

# Find lib
my $ldd = `ldd "$llvm_bindir/lli"`;
if ($ldd =~ /(libLLVM[^ ]+)(.*)/m){
my $lib = $1;
my $path = (split(' ',$2))[1];
$conf->data->set( llvm_shared => $path );
if ($lib =~ /lib(LLVM.*)\.(so|dll)/){
$conf->data->set( llvm_ldflags => "-l$1" );
}
# Find flags
my ($cflags, $cxxflags, $ldflags, $libs);
if ($ldflags = $self->_llvm_config($llvm_config, '--ldflags')) {
$conf->data->set( llvm_ldflags => $ldflags );
}
if ($libs = $self->_llvm_config($llvm_config, '--libs')) {
$conf->data->set( llvm_libs => $libs );
}
if ($cflags = $self->_llvm_config($llvm_config, '--cflags')) {
$conf->data->set( llvm_cflags => $cflags );
}
if ($cxxflags = $self->_llvm_config($llvm_config, '--cxxflags')) {
$conf->data->set( llvm_cxxflags => $cxxflags );
}

$self->_handle_result($conf, $rv);
return 1;
# $self->_handle_result($conf, $version);
# return 1;

# Having gotten this far, we will take a simple C file, compile it into
# an LLVM bitcode file, execute it as bitcode, then compile it to native
Expand All @@ -92,11 +105,22 @@ sub runstep {
my $bcfile = qq|$stem.bc|;
my $sfile = qq|$stem.s|;
my $nativefile = qq|$stem.native|;
eval {
system(qq{llvm-gcc -O3 -emit-llvm $fullcfile -c -o $bcfile});
};
$rv = '';
if ($@) {
unlink $bcfile;
for my $cc ($conf->data->get('cc'),
"$llvm_bindir/clang", "$llvm_bindir/llvm-gcc",
qw(llvm-gcc clang))
{
# Note: gcc and g++ with -c just skips over -emit-llvm and produce native code
# without -c: ld: warning: cannot find entry symbol 'mit-llvm'
eval {
system(qq{$cc -emit-llvm -O3 $fullcfile -c -o $bcfile});
};
if (!$@ and -e $bcfile and $self->_check_bcfile($bcfile)) {
$conf->data->set( llvm_gcc => $cc );
last;
}
}
if (! $conf->data->get( 'llvm_gcc' )) {
$rv = $self->_handle_failure_to_compile_into_bitcode(
$conf,
$verbose,
Expand All @@ -109,7 +133,7 @@ sub runstep {
else {
my $output;
eval {
$output = capture_output( 'lli', $bcfile );
$output = capture_output( "$llvm_bindir/lli", $bcfile );
};
if ( $@ or $output !~ /hello world/ ) {
$rv = $self->_handle_failure_to_execute_bitcode( $conf, $verbose );
Expand All @@ -120,7 +144,7 @@ sub runstep {
}
else {
eval {
system(qq{llc $bcfile -o $sfile});
system(qq{"$llvm_bindir/llc" $bcfile -o $sfile});
};
if ( $@ or (! -e $sfile) ) {
$rv = $self->_handle_failure_to_compile_to_assembly(
Expand Down Expand Up @@ -152,7 +176,7 @@ sub runstep {
$output = capture_output(qq{./$nativefile});
};
$self->_handle_native_assembly_output(
$conf, $output, $verbose
$conf, $output, $verbose, $version
);
}
}
Expand All @@ -166,10 +190,26 @@ sub runstep {
return 1;
}

sub _check_bcfile {
my ($self, $bcfile) = @_;
open my $fh, '<', $bcfile or return;
my $read = read $fh, my $bytes, 2;
my $result = 1 if $read == 2 and $bytes eq 'BC';
close $fh;
return $result;
}

sub _llvm_config {
my ($self, $llvm_config, $arg) = @_;
my $result = `"$llvm_config" $arg`;
chomp $result;
return $result;
}

sub version_check {
my ($self, $conf, $outputref, $verbose) = @_;
my $version;
if ( $outputref->[1] =~ m/llvm\sversion\s(\d+\.\d+)/s ) {
if ( $outputref->[1] =~ m/llvm\sversion\s(\d+\.\d+)/is ) {
$version = $1;
if ($version < $self->{lli_min_version}) {
if ($verbose) {
Expand Down Expand Up @@ -227,7 +267,12 @@ sub _handle_failure_to_assemble_assembly {
sub _handle_result {
my ($self, $conf, $result) = @_;
if ( $result ) {
$self->set_result( "yes" );
if ($result == 1) {
$self->set_result( "yes" );
}
else {
$self->set_result( "yes, ".$result );
}
$conf->data->set( has_llvm => 1 );
}
else {
Expand All @@ -238,14 +283,14 @@ sub _handle_result {
}

sub _handle_native_assembly_output {
my ($self, $conf, $output, $verbose) = @_;
my ($self, $conf, $output, $verbose, $rv) = @_;
if ( $@ or ( $output !~ /hello world/ ) ) {
print "Unable to execute native assembly program successfully\n"
if $verbose;
$self->_handle_result( $conf, 0 );
}
else {
$self->_handle_result( $conf, 1 );
$self->_handle_result( $conf, $rv );
}
}

Expand All @@ -265,7 +310,7 @@ sub _cleanup_llvm_files {

=head1 AUTHOR
James E Keenan
James E Keenan, Reini Urban
=cut

Expand Down
3 changes: 2 additions & 1 deletion lib/Parrot/Configure/Options/Conf/Shared.pm
@@ -1,4 +1,4 @@
# Copyright (C) 2007-2009, Parrot Foundation.
# Copyright (C) 2007-2012, Parrot Foundation.
package Parrot::Configure::Options::Conf::Shared;

use strict;
Expand Down Expand Up @@ -47,6 +47,7 @@ our @shared_valid_options = qw{
libs
link
linkflags
llvm-config
localstatedir
m
make
Expand Down
15 changes: 12 additions & 3 deletions t/steps/auto/llvm-01.t
@@ -1,11 +1,11 @@
#!perl
# Copyright (C) 2001-2011, Parrot Foundation.
# Copyright (C) 2001-2012, Parrot Foundation.
# auto/llvm-01.t

use strict;
use warnings;
use File::Temp qw( tempdir );
use Test::More tests => 56;
use Test::More tests => 58;
use Carp;
use lib qw( lib t/configure/testlib );
use_ok('config::auto::llvm');
Expand Down Expand Up @@ -252,11 +252,20 @@ my $output = '';
local $@ = '';
$output = 'hello world';
$verbose = 0;
ok( $step->_handle_native_assembly_output( $conf, $output, $verbose ),
ok( $step->_handle_native_assembly_output( $conf, $output, $verbose, 1 ),
"_handle_native_assembly_output() returned true value" );
is( $step->result(), 'yes', "Got expected 'yes' result" );
}

{
local $@ = '';
$output = 'hello world';
$verbose = 0;
ok( $step->_handle_native_assembly_output( $conf, $output, $verbose, 2.7 ),
"_handle_native_assembly_output() returned true value" );
is( $step->result(), 'yes, 2.7', "Got expected 'yes' result" );
}

{
local $@ = 'error';
$output = 'hello world';
Expand Down

0 comments on commit 132f7c7

Please sign in to comment.