Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit 3280b35f44235dc04620c0a221a307b9bebf70e6 @goccy committed Jul 22, 2013
@@ -0,0 +1,12 @@
+*.o
+*~
+\#*
+*.bak
+blib
+pm_to_blib
+ppport.h
+MYMETA.json
+MYMETA.yml
+Makefile
+Makefile.old
+src/Compiler-CodeGenerator-LLVM.cpp
@@ -0,0 +1,4 @@
+Revision history for Compiler-CodeGenerator-LLVM
+
+0.01 Mon Jul 22 16:40:00 2013
+ - First Version.
No changes.
@@ -0,0 +1,27 @@
+use strict;
+use warnings;
+use inc::Module::Install;
+use Module::Install::XSUtil; # for co-developpers
+use constant DEBUG => 1;
+
+use_ppport 3.19;
+all_from 'lib/Compiler/CodeGenerator/LLVM.pm';
+requires_cplusplus;
+cc_warnings;
+cc_src_paths qw(src);
+cc_include_paths qw(include);
+cc_define qw();
+makemaker_args->{CC} = 'g++';
+makemaker_args->{LD} = 'g++';
+my @ignore_warnings_options = qw(missing-field-initializers unused-variable);
+makemaker_args->{CCFLAGS} .= join('', map { ' -Wno-' . $_ } @ignore_warnings_options);
+if (DEBUG) {
+ makemaker_args->{OPTIMIZE} = '-O0';
+ chomp(my $llvm_cflags = `llvm-config --cxxflags`);
+ $llvm_cflags =~ s/-fno-rtti//;
+ makemaker_args->{CCFLAGS} = "-g3 $llvm_cflags " . makemaker_args->{CCFLAGS};
+ chomp(my $llvm_ldflags = `llvm-config --ldflags`);
+ chomp(my $llvm_libs = `llvm-config --libs`);
+ makemaker_args->{LDLOADLIBS} = "$llvm_ldflags $llvm_libs";
+}
+WriteAll(check_nmake => 0);
@@ -0,0 +1,64 @@
+# NAME
+
+Compiler::CodeGenerator::LLVM - Create LLVM IR for Perl5
+
+# INSTALLATION
+
+ # This module is dependent LLVM-3.3.
+ # Please install LLVM-3.3 before building.
+
+ wget http://llvm.org/releases/3.3/llvm-3.3.src.tar.gz
+ cd llvm-3.3.src && ./configure && make && make install
+
+# SYNOPSIS
+
+ use Compiler::Lexer;
+ use Compiler::Parser;
+ use Compiler::CodeGenerator::LLVM;
+
+ my $filename = $ARGV[0];
+ open(my $fh, "<", $filename) or die("$filename is not found.");
+ my $script = do { local $/; <$fh> };
+ my $lexer = Compiler::Lexer->new($filename);
+ my $tokens = $lexer->tokenize($script);
+ my $parser = Compiler::Parser->new();
+ my $ast = $parser->parse($tokens);
+ my $generator = Compiler::CodeGenerator::LLVM->new();
+ my $llvm_ir = $generator->generate($ast); # generate LLVM-IR
+ $generator->debug_run($ast); # execute LLVM-IR with JIT
+
+# DESCRIPTION
+
+Compiler::CodeGenerator::LLVM creates LLVM IR for perl5.
+
+# METHODS
+
+- my $generator = Compiler::CodeGenerator::LLVM->new();
+
+ Create new instance of Compiler::CodeGenerator::LLVM.
+
+- my $llvm_ir = $generator->generate($ast);
+
+ Get scalar value of LLVM IR.
+ This method requires `$ast` from Compiler::Parser::parse
+
+- $generator->debug_run($ast);
+
+ Execute LLVM-IR with JIT for debugging.
+ This method requires `$ast` from Compiler::Parser::parse
+
+# LICENSE
+
+Copyright (C) Masaaki Goshima (goccy).
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+# AUTHOR
+
+Masaaki Goshima (goccy) <goccy54@gmail.com>
+
+# SEE ALSO
+
+[Compiler::Lexer](http://search.cpan.org/perldoc?Compiler::Lexer)
+[Compiler::Parser](http://search.cpan.org/perldoc?Compiler::Parser)
@@ -0,0 +1,26 @@
+use strict;
+use warnings;
+use Compiler::Lexer;
+use Compiler::Parser;
+use Compiler::Parser::AST::Renderer;
+use Compiler::CodeGenerator::LLVM;
+
+my $code = do { local $/; <DATA> };
+my $tokens = Compiler::Lexer->new('')->tokenize($code);
+my $parser = Compiler::Parser->new();
+my $ast = $parser->parse($tokens);
+Compiler::Parser::AST::Renderer->new->render($ast);
+my $generator = Compiler::CodeGenerator::LLVM->new();
+#my $llvm_ir = $generator->generate($ast);
+$generator->debug_run($ast);
+
+__DATA__
+my $a = 1 + 1;
+say $a == 2;
+if ($a != 2) {
+ say "true";
+} elsif ($a == 2) {
+ say "elsif";
+} else {
+ say "else";
+}
@@ -0,0 +1,31 @@
+use strict;
+use warnings;
+use Compiler::Lexer;
+use Compiler::Parser;
+use Compiler::Parser::AST::Renderer;
+use Compiler::CodeGenerator::LLVM;
+
+my $code = do { local $/; <DATA> };
+my $tokens = Compiler::Lexer->new('')->tokenize($code);
+my $parser = Compiler::Parser->new();
+my $ast = $parser->parse($tokens);
+Compiler::Parser::AST::Renderer->new->render($ast);
+my $generator = Compiler::CodeGenerator::LLVM->new();
+$generator->debug_run($ast);
+
+__DATA__
+say 1 + 2 == 3;
+say 1.2 + 2.3 == 3.5;
+say 2.1 + 2 == 4.1;
+say 1 - 2 == -1;
+say 1.3 - 2 == -0.7;
+say 1.3 * 2 == 2.6;
+say 1.3 * -2 == -2.6;
+say 1.3 / 2 == 0.65;
+say 1.3 / -2 == -0.65;
+say 1 != 2;
+say 1.2 != 2.4;
+say 2 > 1;
+say 1 < 2;
+say 1 & 2;
+say 0 & 1;
@@ -0,0 +1,57 @@
+#include <stdio.h>
+
+typedef enum {
+ Int,
+ Double,
+ String,
+ Array,
+ Hash,
+ BlessedObject,
+ Unknown
+} Type;
+
+typedef struct _Value {
+ long ivalue;
+ double dvalue;
+ char *svalue;
+ void *ovalue;
+} Value;
+
+typedef struct _Object {
+ int type;
+ Value v;
+} Object;
+
+typedef struct _Array {
+ int type;
+ Object **list;
+ size_t size;
+} ArrayObject;
+
+void print(ArrayObject *array)
+{
+ size_t size = array->size;
+ int i = 0;
+ for (i = 0; i < size; i++) {
+ Object *o = array->list[i];
+ switch (o->type) {
+ case Int:
+ fprintf(stdout, "%ld", o->v.ivalue);
+ break;
+ case Double:
+ fprintf(stdout, "%lf", o->v.dvalue);
+ break;
+ case String:
+ fprintf(stdout, "%s", o->v.svalue);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void say(ArrayObject *array)
+{
+ print(array);
+ fprintf(stdout, "\n");
+}
@@ -0,0 +1,87 @@
+; ModuleID = 'gen/runtime_api.c'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin10.0.0"
+
+%struct._Array = type { i32, %struct._Object**, i64 }
+%struct._Object = type { i32, %struct._Value }
+%struct._Value = type { i64, double, i8*, i8* }
+%struct.__sFILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
+%struct.__sFILEX = type opaque
+%struct.__sbuf = type { i8*, i32 }
+
+@__stdoutp = external global %struct.__sFILE*
+@.str = private constant [4 x i8] c"%ld\00"
+@.str1 = private constant [4 x i8] c"%lf\00"
+
+define void @print(%struct._Array* nocapture %array) nounwind ssp {
+ %1 = getelementptr inbounds %struct._Array* %array, i64 0, i32 2
+ %2 = load i64* %1, align 8, !tbaa !0
+ %3 = icmp eq i64 %2, 0
+ br i1 %3, label %._crit_edge, label %bb.nph
+
+bb.nph: ; preds = %0
+ %4 = getelementptr inbounds %struct._Array* %array, i64 0, i32 1
+ br label %._crit_edge2
+
+._crit_edge2: ; preds = %23, %bb.nph
+ %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %23 ]
+ %5 = load %struct._Object*** %4, align 8, !tbaa !3
+ %scevgep = getelementptr %struct._Object** %5, i64 %indvar
+ %6 = load %struct._Object** %scevgep, align 8, !tbaa !3
+ %7 = getelementptr inbounds %struct._Object* %6, i64 0, i32 0
+ %8 = load i32* %7, align 4, !tbaa !4
+ switch i32 %8, label %23 [
+ i32 0, label %9
+ i32 1, label %14
+ i32 2, label %19
+ ]
+
+; <label>:9 ; preds = %._crit_edge2
+ %10 = load %struct.__sFILE** @__stdoutp, align 8, !tbaa !3
+ %11 = getelementptr inbounds %struct._Object* %6, i64 0, i32 1, i32 0
+ %12 = load i64* %11, align 8, !tbaa !0
+ %13 = tail call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %10, i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i64 %12) nounwind
+ br label %23
+
+; <label>:14 ; preds = %._crit_edge2
+ %15 = load %struct.__sFILE** @__stdoutp, align 8, !tbaa !3
+ %16 = getelementptr inbounds %struct._Object* %6, i64 0, i32 1, i32 1
+ %17 = load double* %16, align 8, !tbaa !5
+ %18 = tail call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %15, i8* getelementptr inbounds ([4 x i8]* @.str1, i64 0, i64 0), double %17) nounwind
+ br label %23
+
+; <label>:19 ; preds = %._crit_edge2
+ %20 = load %struct.__sFILE** @__stdoutp, align 8, !tbaa !3
+ %21 = getelementptr inbounds %struct._Object* %6, i64 0, i32 1, i32 2
+ %22 = load i8** %21, align 8, !tbaa !3
+ %fputs = tail call i32 @fputs(i8* %22, %struct.__sFILE* %20)
+ br label %23
+
+; <label>:23 ; preds = %9, %14, %19, %._crit_edge2
+ %indvar.next = add i64 %indvar, 1
+ %exitcond = icmp eq i64 %indvar.next, %2
+ br i1 %exitcond, label %._crit_edge, label %._crit_edge2
+
+._crit_edge: ; preds = %23, %0
+ ret void
+}
+
+declare i32 @fprintf(%struct.__sFILE* nocapture, i8* nocapture, ...) nounwind
+
+define void @say(%struct._Array* nocapture %array) nounwind ssp {
+ tail call void @print(%struct._Array* %array)
+ %1 = load %struct.__sFILE** @__stdoutp, align 8, !tbaa !3
+ %fputc = tail call i32 @fputc(i32 10, %struct.__sFILE* %1)
+ ret void
+}
+
+declare i32 @fputs(i8* nocapture, %struct.__sFILE* nocapture) nounwind
+
+declare i32 @fputc(i32, %struct.__sFILE* nocapture) nounwind
+
+!0 = metadata !{metadata !"long", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
+!3 = metadata !{metadata !"any pointer", metadata !1}
+!4 = metadata !{metadata !"int", metadata !1}
+!5 = metadata !{metadata !"double", metadata !1}
Oops, something went wrong.

0 comments on commit 3280b35

Please sign in to comment.