From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/www/demo/DemoInfo.html | 83 ++++++ clang/www/demo/cathead.png | Bin 0 -> 21602 bytes clang/www/demo/index.cgi | 461 ++++++++++++++++++++++++++++++ clang/www/demo/syntax.css | 4 + clang/www/demo/what is this directory.txt | 15 + 5 files changed, 563 insertions(+) create mode 100644 clang/www/demo/DemoInfo.html create mode 100644 clang/www/demo/cathead.png create mode 100644 clang/www/demo/index.cgi create mode 100644 clang/www/demo/syntax.css create mode 100644 clang/www/demo/what is this directory.txt (limited to 'clang/www/demo') diff --git a/clang/www/demo/DemoInfo.html b/clang/www/demo/DemoInfo.html new file mode 100644 index 0000000..54a5afa --- /dev/null +++ b/clang/www/demo/DemoInfo.html @@ -0,0 +1,83 @@ + + + + +Demo page information + + + + + +

Demo page information

+ +

Press "back" or click here to return to the demo +page.

+ +

Hints and Advice

+ + + + +

Demangle C++ names with C++ filt

+ +

+Select this option if you want to run the output LLVM IR through "c++filt", +which converts 'mangled' C++ names to their unmangled version. +Note that LLVM code produced will not be lexically valid, but it will +be easier to understand. +

+ +

Run link-time optimizer

+ +

+Select this option to run the LLVM link-time optimizer, which is designed to +optimize across files in your application. Since the demo page doesn't allow +you to upload multiple files at once, and does not link in any libraries, we +configured the demo page optimizer to assume there are no calls +coming in from outside the source file, allowing it to optimize more +aggressively.

+ +

Note that you have to define 'main' in your program for this +to make much of a difference. +

+ +

Show detailed pass statistics

+ +

+Select this option to enable compilation timings and statistics from various +optimizers.

+ + +

Analyze generated bytecode

+ +

+Select this option to run the llvm-bcanalyzer tool +on the generated bytecode, which introspects into the format of the .bc file +itself.

+ + +

Show C++ API code

+ +

+Select this option to run the llvm2cpp tool +on the generated bytecode, which auto generates the C++ API calls that could +be used to create the .bc file. +

+ + + + diff --git a/clang/www/demo/cathead.png b/clang/www/demo/cathead.png new file mode 100644 index 0000000..3bf1a45 Binary files /dev/null and b/clang/www/demo/cathead.png differ diff --git a/clang/www/demo/index.cgi b/clang/www/demo/index.cgi new file mode 100644 index 0000000..901b009 --- /dev/null +++ b/clang/www/demo/index.cgi @@ -0,0 +1,461 @@ +#!/usr/dcs/software/supported/bin/perl -w +# LLVM Web Demo script +# + +use strict; +use CGI; +use POSIX; +use Mail::Send; + +$| = 1; + +my $ROOT = "/tmp/webcompile"; +#my $ROOT = "/home/vadve/lattner/webcompile"; + +open( STDERR, ">&STDOUT" ) or die "can't redirect stderr to stdout"; + +if ( !-d $ROOT ) { mkdir( $ROOT, 0777 ); } + +my $LOGFILE = "$ROOT/log.txt"; +my $FORM_URL = 'index.cgi'; +my $MAILADDR = 'sabre@nondot.org'; +my $CONTACT_ADDRESS = 'Questions or comments? Email the LLVMdev mailing list.'; +my $LOGO_IMAGE_URL = 'cathead.png'; +my $TIMEOUTAMOUNT = 20; +$ENV{'LD_LIBRARY_PATH'} = '/home/vadve/shared/localtools/fc1/lib/'; + +my @PREPENDPATHDIRS = + ( + '/home/vadve/shared/llvm-gcc4.0-2.1/bin/', + '/home/vadve/shared/llvm-2.1/Release/bin'); + +my $defaultsrc = "#include \n#include \n\n" . + "int power(int X) {\n if (X == 0) return 1;\n" . + " return X*power(X-1);\n}\n\n" . + "int main(int argc, char **argv) {\n" . + " printf(\"%d\\n\", power(atoi(argv[0])));\n}\n"; + +sub getname { + my ($extension) = @_; + for ( my $count = 0 ; ; $count++ ) { + my $name = + sprintf( "$ROOT/_%d_%d%s", $$, $count, $extension ); + if ( !-f $name ) { return $name; } + } +} + +my $c; + +sub barf { + print "", @_, "\n"; + print $c->end_html; + system("rm -f $ROOT/locked"); + exit 1; +} + +sub writeIntoFile { + my $extension = shift @_; + my $contents = join "", @_; + my $name = getname($extension); + local (*FILE); + open( FILE, ">$name" ) or barf("Can't write to $name: $!"); + print FILE $contents; + close FILE; + return $name; +} + +sub addlog { + my ( $source, $pid, $result ) = @_; + open( LOG, ">>$LOGFILE" ); + my $time = scalar localtime; + my $remotehost = $ENV{'REMOTE_ADDR'}; + print LOG "[$time] [$remotehost]: $pid\n"; + print LOG "<<<\n$source\n>>>\nResult is: <<<\n$result\n>>>\n"; + close LOG; +} + +sub dumpFile { + my ( $header, $file ) = @_; + my $result; + open( FILE, "$file" ) or barf("Can't read $file: $!"); + while () { + $result .= $_; + } + close FILE; + my $UnhilightedResult = $result; + my $HtmlResult = + "

$header

\n
\n" . $c->escapeHTML($result) . "\n
\n"; + if (wantarray) { + return ( $UnhilightedResult, $HtmlResult ); + } + else { + return $HtmlResult; + } +} + +sub syntaxHighlightLLVM { + my ($input) = @_; + $input =~ s@\b(void|i8|i1|i16|i32|i64|float|double|type|label|opaque)\b@$1@g; + $input =~ s@\b(add|sub|mul|div|rem|and|or|xor|setne|seteq|setlt|setgt|setle|setge|phi|tail|call|cast|to|shl|shr|vaarg|vanext|ret|br|switch|invoke|unwind|malloc|alloca|free|load|store|getelementptr|begin|end|true|false|declare|global|constant|const|internal|uninitialized|external|implementation|linkonce|weak|appending|null|to|except|not|target|endian|pointersize|big|little|volatile)\b@$1@g; + + # Add links to the FAQ. + $input =~ s@(_ZNSt8ios_base4Init[DC]1Ev)@$1@g; + $input =~ s@\bundef\b@undef@g; + return $input; +} + +sub mailto { + my ( $recipient, $body ) = @_; + my $msg = + new Mail::Send( Subject => "LLVM Demo Page Run", To => $recipient ); + my $fh = $msg->open(); + print $fh $body; + $fh->close(); +} + +$c = new CGI; +print $c->header; + +print < + + + Try out LLVM in your browser! + + + + +
+ Try out LLVM in your browser! +
+ +
+ + +EOF + +if ( -f "$ROOT/locked" ) { + my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$locktime) = + stat("$ROOT/locked"); + my $currtime = time(); + if ($locktime + 60 > $currtime) { + print "This page is already in use by someone else at this "; + print "time, try reloading in a second or two. Meow!
'\n"; + exit 0; + } +} + +system("touch $ROOT/locked"); + +print <

+END + +print $c->start_multipart_form( 'POST', $FORM_URL ); + +my $source = $c->param('source'); + + +# Start the user out with something valid if no code. +$source = $defaultsrc if (!defined($source)); + +print '
'; + +print "Type your source code in below: (hints and +advice)
\n"; + +print $c->textarea( + -name => "source", + -rows => 16, + -columns => 60, + -default => $source +), "
"; + +print "Or upload a file: "; +print $c->filefield( -name => 'uploaded_file', -default => '' ); + +print "

\n"; + + +print '

'; + +print "

General Options

"; + +print "Source language: ", + $c->radio_group( + -name => 'language', + -values => [ 'C', 'C++' ], + -default => 'C' + ), "

"; + +print $c->checkbox( + -name => 'linkopt', + -label => 'Run link-time optimizer', + -checked => 'checked' + ),' ?
'; + +print $c->checkbox( + -name => 'showstats', + -label => 'Show detailed pass statistics' + ), ' ?
'; + +print $c->checkbox( + -name => 'cxxdemangle', + -label => 'Demangle C++ names' + ),' ?

'; + + +print "

Output Options

"; + +print $c->checkbox( + -name => 'showbcanalysis', + -label => 'Show detailed bytecode analysis' + ),' ?
'; + +print $c->checkbox( + -name => 'showllvm2cpp', + -label => 'Show LLVM C++ API code' + ), ' ?'; + +print "
"; + +print "

", $c->submit(-value=> 'Compile Source Code'), + "
\n", $c->endform; + +print "\n

If you have questions about the LLVM code generated by the +front-end, please check the FAQ and +the demo page hints section. +

\n"; + +$ENV{'PATH'} = ( join ( ':', @PREPENDPATHDIRS ) ) . ":" . $ENV{'PATH'}; + +sub sanitychecktools { + my $sanitycheckfail = ''; + + # insert tool-specific sanity checks here + $sanitycheckfail .= ' llvm-dis' + if `llvm-dis --help 2>&1` !~ /ll disassembler/; + + $sanitycheckfail .= ' llvm-gcc' + if ( `llvm-gcc --version 2>&1` !~ /Free Software Foundation/ ); + + $sanitycheckfail .= ' llvm-ld' + if `llvm-ld --help 2>&1` !~ /llvm linker/; + + $sanitycheckfail .= ' llvm-bcanalyzer' + if `llvm-bcanalyzer --help 2>&1` !~ /bcanalyzer/; + + barf( +"
The demo page is currently unavailable. [tools: ($sanitycheckfail ) failed sanity check]" + ) + if $sanitycheckfail; +} + +sanitychecktools(); + +sub try_run { + my ( $program, $commandline, $outputFile ) = @_; + my $retcode = 0; + + eval { + local $SIG{ALRM} = sub { die "timeout"; }; + alarm $TIMEOUTAMOUNT; + $retcode = system($commandline); + alarm 0; + }; + if ( $@ and $@ =~ /timeout/ ) { + barf("Program $program took too long, compile time limited for the web script, sorry!\n"); + } + if ( -s $outputFile ) { + print scalar dumpFile( "Output from $program", $outputFile ); + } + #print "

Finished dumping command output.

\n"; + if ( WIFEXITED($retcode) && WEXITSTATUS($retcode) != 0 ) { + barf( +"$program exited with an error. Please correct source and resubmit.

\n" . +"Please note that this form only allows fully formed and correct source" . +" files. It will not compile fragments of code.

" + ); + } + if ( WIFSIGNALED($retcode) != 0 ) { + my $sig = WTERMSIG($retcode); + barf( + "Ouch, $program caught signal $sig. Sorry, better luck next time!\n" + ); + } +} + +my %suffixes = ( + 'Java' => '.java', + 'JO99' => '.jo9', + 'C' => '.c', + 'C++' => '.cc', + 'Stacker' => '.st', + 'preprocessed C' => '.i', + 'preprocessed C++' => '.ii' +); +my %languages = ( + '.jo9' => 'JO99', + '.java' => 'Java', + '.c' => 'C', + '.i' => 'preprocessed C', + '.ii' => 'preprocessed C++', + '.cc' => 'C++', + '.cpp' => 'C++', + '.st' => 'Stacker' +); + +my $uploaded_file_name = $c->param('uploaded_file'); +if ($uploaded_file_name) { + if ($source) { + barf( +"You must choose between uploading a file and typing code in. You can't do both at the same time." + ); + } + $uploaded_file_name =~ s/^.*(\.[A-Za-z]+)$/$1/; + my $language = $languages{$uploaded_file_name}; + $c->param( 'language', $language ); + + print "

Processing uploaded file. It looks like $language.

\n"; + my $fh = $c->upload('uploaded_file'); + if ( !$fh ) { + barf( "Error uploading file: " . $c->cgi_error ); + } + while (<$fh>) { + $source .= $_; + } + close $fh; +} + +if ($c->param('source')) { + print $c->hr; + my $extension = $suffixes{ $c->param('language') }; + barf "Unknown language; can't compile\n" unless $extension; + + # Add a newline to the source here to avoid a warning from gcc. + $source .= "\n"; + + # Avoid security hole due to #including bad stuff. + $source =~ +s@(\n)?#include.*[<"](.*\.\..*)[">].*\n@$1#error "invalid #include file $2 detected"\n@g; + + my $inputFile = writeIntoFile( $extension, $source ); + my $pid = $$; + + my $bytecodeFile = getname(".bc"); + my $outputFile = getname(".llvm-gcc.out"); + my $timerFile = getname(".llvm-gcc.time"); + + my $stats = ''; + if ( $extension eq ".st" ) { + $stats = "-stats -time-passes " + if ( $c->param('showstats') ); + try_run( "llvm Stacker front-end (stkrc)", + "stkrc $stats -o $bytecodeFile $inputFile > $outputFile 2>&1", + $outputFile ); + } else { + #$stats = "-Wa,--stats,--time-passes,--info-output-file=$timerFile" + $stats = "-ftime-report" + if ( $c->param('showstats') ); + try_run( "llvm C/C++ front-end (llvm-gcc)", + "llvm-gcc -emit-llvm -W -Wall -O2 $stats -o $bytecodeFile -c $inputFile > $outputFile 2>&1", + $outputFile ); + } + + if ( $c->param('showstats') && -s $timerFile ) { + my ( $UnhilightedResult, $HtmlResult ) = + dumpFile( "Statistics for front-end compilation", $timerFile ); + print "$HtmlResult\n"; + } + + if ( $c->param('linkopt') ) { + my $stats = ''; + my $outputFile = getname(".gccld.out"); + my $timerFile = getname(".gccld.time"); + $stats = "--stats --time-passes --info-output-file=$timerFile" + if ( $c->param('showstats') ); + my $tmpFile = getname(".bc"); + try_run( + "optimizing linker (llvm-ld)", +"llvm-ld $stats -o=$tmpFile $bytecodeFile > $outputFile 2>&1", + $outputFile + ); + system("mv $tmpFile.bc $bytecodeFile"); + system("rm $tmpFile"); + + if ( $c->param('showstats') && -s $timerFile ) { + my ( $UnhilightedResult, $HtmlResult ) = + dumpFile( "Statistics for optimizing linker", $timerFile ); + print "$HtmlResult\n"; + } + } + + print " Bytecode size is ", -s $bytecodeFile, " bytes.\n"; + + my $disassemblyFile = getname(".ll"); + try_run( "llvm-dis", + "llvm-dis -o=$disassemblyFile $bytecodeFile > $outputFile 2>&1", + $outputFile ); + + if ( $c->param('cxxdemangle') ) { + print " Demangling disassembler output.\n"; + my $tmpFile = getname(".ll"); + system("c++filt < $disassemblyFile > $tmpFile 2>&1"); + system("mv $tmpFile $disassemblyFile"); + } + + my ( $UnhilightedResult, $HtmlResult ); + if ( -s $disassemblyFile ) { + ( $UnhilightedResult, $HtmlResult ) = + dumpFile( "Output from LLVM disassembler", $disassemblyFile ); + print syntaxHighlightLLVM($HtmlResult); + } + else { + print "

Hmm, that's weird, llvm-dis didn't produce any output.

\n"; + } + + if ( $c->param('showbcanalysis') ) { + my $analFile = getname(".bca"); + try_run( "llvm-bcanalyzer", "llvm-bcanalyzer $bytecodeFile > $analFile 2>&1", + $analFile); + } + if ($c->param('showllvm2cpp') ) { + my $l2cppFile = getname(".l2cpp"); + try_run("llvm2cpp","llvm2cpp $bytecodeFile -o $l2cppFile 2>&1", + $l2cppFile); + } + + # Get the source presented by the user to CGI, convert newline sequences to simple \n. + my $actualsrc = $c->param('source'); + $actualsrc =~ s/\015\012/\n/go; + # Don't log this or mail it if it is the default code. + if ($actualsrc ne $defaultsrc) { + addlog( $source, $pid, $UnhilightedResult ); + + my ( $ip, $host, $lg, $lines ); + chomp( $lines = `wc -l < $inputFile` ); + $lg = $c->param('language'); + $ip = $c->remote_addr(); + chomp( $host = `host $ip` ) if $ip; + mailto( $MAILADDR, + "--- Query: ---\nFrom: ($ip) $host\nInput: $lines lines of $lg\n" + . "C++ demangle = " + . ( $c->param('cxxdemangle') ? 1 : 0 ) + . ", Link opt = " + . ( $c->param('linkopt') ? 1 : 0 ) . "\n\n" + . ", Show stats = " + . ( $c->param('showstats') ? 1 : 0 ) . "\n\n" + . "--- Source: ---\n$source\n" + . "--- Result: ---\n$UnhilightedResult\n" ); + } + unlink( $inputFile, $bytecodeFile, $outputFile, $disassemblyFile ); +} + +print $c->hr, "
$CONTACT_ADDRESS
", $c->end_html; +system("rm $ROOT/locked"); +exit 0; diff --git a/clang/www/demo/syntax.css b/clang/www/demo/syntax.css new file mode 100644 index 0000000..90daf5f --- /dev/null +++ b/clang/www/demo/syntax.css @@ -0,0 +1,4 @@ +/* LLVM syntax highlighting for the Web */ + +.llvm_type { font-style: oblique; color: green } +.llvm_keyword { font-weight: bold; color: blue } diff --git a/clang/www/demo/what is this directory.txt b/clang/www/demo/what is this directory.txt new file mode 100644 index 0000000..a1306ac --- /dev/null +++ b/clang/www/demo/what is this directory.txt @@ -0,0 +1,15 @@ +This is for the LLVM+Clang browser based demo. +It is supposed to work like the LLVM+GCC demo here: http://llvm.org/demo/ but for the BSD licensed Clang instead. + +Perhaps it could also be used for getting crash information and details on errors.... I'm not sure if this would require some major changes or not to report this info. Maybe also adding ways that people can use it to test for errors and a way to report such errors would also be good. + +Status: +Anyways, right now, these file a basically just a copy of the LLVM+GCC demo (no changes have been made). The files don't even work right in this location on the server. As such, someone will need to edit the file or rewrite it. + +If nobody in the LLVM community has the skills, one suggestion would be to post a request on a friendly Perl forum and see if anybody might be interested in taking on the challenge. + +Alternatively, you could try a PHP, Python, Ruby, or Lisp mailing list and see if there are any takers who would be interested (and willing to do a rewrite to their language of choice). + +-- +BTW, once this feature was working, my intention was to link to it from the index.html page in the section entitled: +Try Clang \ No newline at end of file -- cgit v1.2.3