From baldrick at free.fr Mon Mar 8 03:16:43 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 08 Mar 2010 09:16:43 -0000 Subject: [llvm-commits] [dragonegg] r97940 - /dragonegg/trunk/www/index.html Message-ID: <20100308091643.1C6AD2A6C12C@llvm.org> Author: baldrick Date: Mon Mar 8 03:16:42 2010 New Revision: 97940 URL: http://llvm.org/viewvc/llvm-project?rev=97940&view=rev Log: Dragonegg can now compile clang and boost. Modified: dragonegg/trunk/www/index.html Modified: dragonegg/trunk/www/index.html URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/www/index.html?rev=97940&r1=97939&r2=97940&view=diff ============================================================================== --- dragonegg/trunk/www/index.html (original) +++ dragonegg/trunk/www/index.html Mon Mar 8 03:16:42 2010 @@ -37,9 +37,9 @@
svn co http://gcc.gnu.org/svn/gcc/trunk gcc
Apply all of the patches in dragonegg/gcc-patches/, if any, to gcc. + You need to pass the -p1 option to patch. Build and install gcc in the usual way.
Doing
GCC=path_to_just_installed_gcc makeFrom xuzhongxing at gmail.com Mon Mar 8 06:45:34 2010 From: xuzhongxing at gmail.com (Zhongxing Xu) Date: Mon, 8 Mar 2010 20:45:34 +0800 Subject: [llvm-commits] [PATCH] remove redundant 'static' Message-ID: <5400aeb81003080445r3184c915j3c1471351f67d438@mail.gmail.com> 'static' is redundant in this context: Index: utils/TableGen/RegisterInfoEmitter.cpp =================================================================== --- utils/TableGen/RegisterInfoEmitter.cpp (?? 97892) +++ utils/TableGen/RegisterInfoEmitter.cpp (????) @@ -201,7 +201,7 @@ // Emit the register list now. OS << " // " << Name << " Register Class...\n" - << " static const unsigned " << Name + << " const unsigned " << Name << "[] = {\n "; for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) { Record *Reg = RC.Elements[i]; @@ -223,7 +223,7 @@ // Emit the register list now. OS << " // " << Name << " Register Class Value Types...\n" - << " static const EVT " << Name + << " const EVT " << Name << "[] = {\n "; for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i) OS << getEnumName(RC.VTs[i]) << ", "; @@ -252,7 +252,7 @@ OS << " // " << Name << " Sub-register Classes...\n" - << " static const TargetRegisterClass* const " + << " const TargetRegisterClass* const " << Name << "SubRegClasses[] = {\n "; bool Empty = true; @@ -298,7 +298,7 @@ OS << " // " << Name << " Super-register Classes...\n" - << " static const TargetRegisterClass* const " + << " const TargetRegisterClass* const " << Name << "SuperRegClasses[] = {\n "; bool Empty = true; @@ -334,7 +334,7 @@ OS << " // " << Name << " Register Class sub-classes...\n" - << " static const TargetRegisterClass* const " + << " const TargetRegisterClass* const " << Name << "Subclasses[] = {\n "; bool Empty = true; @@ -382,7 +382,7 @@ OS << " // " << Name << " Register Class super-classes...\n" - << " static const TargetRegisterClass* const " + << " const TargetRegisterClass* const " << Name << "Superclasses[] = {\n "; bool Empty = true; From clattner at apple.com Mon Mar 8 10:40:33 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 8 Mar 2010 08:40:33 -0800 Subject: [llvm-commits] [PATCH] remove redundant 'static' In-Reply-To: <5400aeb81003080445r3184c915j3c1471351f67d438@mail.gmail.com> References: <5400aeb81003080445r3184c915j3c1471351f67d438@mail.gmail.com> Message-ID:
(* Create a new basic block to start insertion into. *)
- let bb = append_block "entry" the_function in
+ let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@@ -903,6 +904,7 @@
let the_module = create_module context "my cool jit"
let builder = builder context
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
+let double_type = double_type context
let rec codegen_expr = function
| Ast.Number n -> const_float double_type n
@@ -974,7 +976,7 @@
let the_function = codegen_proto proto in
(* Create a new basic block to start insertion into. *)
- let bb = append_block "entry" the_function in
+ let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
Modified: llvm/trunk/docs/tutorial/OCamlLangImpl4.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl4.html?rev=97965&r1=97964&r2=97965&view=diff
==============================================================================
--- llvm/trunk/docs/tutorial/OCamlLangImpl4.html (original)
+++ llvm/trunk/docs/tutorial/OCamlLangImpl4.html Mon Mar 8 13:32:18 2010
@@ -186,9 +186,8 @@
(* Create the JIT. *)
- let the_module_provider = ModuleProvider.create Codegen.the_module in
- let the_execution_engine = ExecutionEngine.create the_module_provider in
- let the_fpm = PassManager.create_function the_module_provider in
+ let the_execution_engine = ExecutionEngine.create Codegen.the_module in
+ let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
@@ -213,18 +212,11 @@
-This code defines two values, an Llvm.llmoduleprovider and a
-Llvm.PassManager.t. The former is basically a wrapper around our
-Llvm.llmodule that the Llvm.PassManager.t requires. It
-provides certain flexibility that we're not going to take advantage of here,
-so I won't dive into any details about it.
-
The meat of the matter here, is the definition of "the_fpm". It
-requires a pointer to the the_module (through the
-the_module_provider) to construct itself. Once it is set up, we use a
-series of "add" calls to add a bunch of LLVM passes. The first pass is
-basically boilerplate, it adds a pass so that later optimizations know how the
-data structures in the program are laid out. The
+requires a pointer to the the_module to construct itself. Once it is
+set up, we use a series of "add" calls to add a bunch of LLVM passes. The
+first pass is basically boilerplate, it adds a pass so that later optimizations
+know how the data structures in the program are laid out. The
"the_execution_engine" variable is related to the JIT, which we will
get to in the next section.
@@ -320,8 +312,7 @@
let main () =
...
(* Create the JIT. *)
- let the_module_provider = ModuleProvider.create Codegen.the_module in
- let the_execution_engine = ExecutionEngine.create the_module_provider in
+ let the_execution_engine = ExecutionEngine.create Codegen.the_module in
...
(* Emit 'else' value. *)
- let else_bb = append_block "else" the_function in
+ let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
@@ -433,7 +433,7 @@
(* Emit merge block. *)
- let merge_bb = append_block "ifcont" the_function in
+ let merge_bb = append_block context "ifcont" the_function in
position_at_end merge_bb builder;
let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
let phi = build_phi incoming "iftmp" builder in
@@ -704,7 +704,7 @@
* block. *)
let preheader_bb = insertion_block builder in
let the_function = block_parent preheader_bb in
- let loop_bb = append_block "loop" the_function in
+ let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
@@ -804,7 +804,7 @@
(* Create the "after loop" block and insert it. *)
let loop_end_bb = insertion_block builder in
- let after_bb = append_block "afterloop" the_function in
+ let after_bb = append_block context "afterloop" the_function in
(* Insert the conditional branch into the end of loop_end_bb. *)
ignore (build_cond_br end_cond loop_bb after_bb builder);
@@ -1204,6 +1204,7 @@
let the_module = create_module context "my cool jit"
let builder = builder context
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
+let double_type = double_type context
let rec codegen_expr = function
| Ast.Number n -> const_float double_type n
@@ -1250,7 +1251,7 @@
let start_bb = insertion_block builder in
let the_function = block_parent start_bb in
- let then_bb = append_block "then" the_function in
+ let then_bb = append_block context "then" the_function in
(* Emit 'then' value. *)
position_at_end then_bb builder;
@@ -1262,7 +1263,7 @@
let new_then_bb = insertion_block builder in
(* Emit 'else' value. *)
- let else_bb = append_block "else" the_function in
+ let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
@@ -1271,7 +1272,7 @@
let new_else_bb = insertion_block builder in
(* Emit merge block. *)
- let merge_bb = append_block "ifcont" the_function in
+ let merge_bb = append_block context "ifcont" the_function in
position_at_end merge_bb builder;
let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
let phi = build_phi incoming "iftmp" builder in
@@ -1297,7 +1298,7 @@
* block. *)
let preheader_bb = insertion_block builder in
let the_function = block_parent preheader_bb in
- let loop_bb = append_block "loop" the_function in
+ let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
@@ -1341,7 +1342,7 @@
(* Create the "after loop" block and insert it. *)
let loop_end_bb = insertion_block builder in
- let after_bb = append_block "afterloop" the_function in
+ let after_bb = append_block context "afterloop" the_function in
(* Insert the conditional branch into the end of loop_end_bb. *)
ignore (build_cond_br end_cond loop_bb after_bb builder);
@@ -1397,7 +1398,7 @@
let the_function = codegen_proto proto in
(* Create a new basic block to start insertion into. *)
- let bb = append_block "entry" the_function in
+ let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@@ -1462,7 +1463,7 @@
the_execution_engine in
print_string "Evaluated to ";
- print_float (GenericValue.as_float double_type result);
+ print_float (GenericValue.as_float Codegen.double_type result);
print_newline ();
with Stream.Error s | Codegen.Error s ->
(* Skip token for error recovery. *)
@@ -1501,16 +1502,15 @@
let stream = Lexer.lex (Stream.of_channel stdin) in
(* Create the JIT. *)
- let the_module_provider = ModuleProvider.create Codegen.the_module in
- let the_execution_engine = ExecutionEngine.create the_module_provider in
- let the_fpm = PassManager.create_function the_module_provider in
+ let the_execution_engine = ExecutionEngine.create Codegen.the_module in
+ let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
- add_instruction_combining the_fpm;
+ add_instruction_combination the_fpm;
(* reassociate expressions. *)
add_reassociation the_fpm;
Modified: llvm/trunk/docs/tutorial/OCamlLangImpl6.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl6.html?rev=97965&r1=97964&r2=97965&view=diff
==============================================================================
--- llvm/trunk/docs/tutorial/OCamlLangImpl6.html (original)
+++ llvm/trunk/docs/tutorial/OCamlLangImpl6.html Mon Mar 8 13:32:18 2010
@@ -300,7 +300,7 @@
end;
(* Create a new basic block to start insertion into. *)
- let bb = append_block "entry" the_function in
+ let bb = append_block context "entry" the_function in
position_at_end bb builder;
...
@@ -1177,6 +1177,7 @@
let the_module = create_module context "my cool jit"
let builder = builder context
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
+let double_type = double_type context
let rec codegen_expr = function
| Ast.Number n -> const_float double_type n
@@ -1241,7 +1242,7 @@
let start_bb = insertion_block builder in
let the_function = block_parent start_bb in
- let then_bb = append_block "then" the_function in
+ let then_bb = append_block context "then" the_function in
(* Emit 'then' value. *)
position_at_end then_bb builder;
@@ -1253,7 +1254,7 @@
let new_then_bb = insertion_block builder in
(* Emit 'else' value. *)
- let else_bb = append_block "else" the_function in
+ let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
@@ -1262,7 +1263,7 @@
let new_else_bb = insertion_block builder in
(* Emit merge block. *)
- let merge_bb = append_block "ifcont" the_function in
+ let merge_bb = append_block context "ifcont" the_function in
position_at_end merge_bb builder;
let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
let phi = build_phi incoming "iftmp" builder in
@@ -1288,7 +1289,7 @@
* block. *)
let preheader_bb = insertion_block builder in
let the_function = block_parent preheader_bb in
- let loop_bb = append_block "loop" the_function in
+ let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
@@ -1332,7 +1333,7 @@
(* Create the "after loop" block and insert it. *)
let loop_end_bb = insertion_block builder in
- let after_bb = append_block "afterloop" the_function in
+ let after_bb = append_block context "afterloop" the_function in
(* Insert the conditional branch into the end of loop_end_bb. *)
ignore (build_cond_br end_cond loop_bb after_bb builder);
@@ -1396,7 +1397,7 @@
end;
(* Create a new basic block to start insertion into. *)
- let bb = append_block "entry" the_function in
+ let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@@ -1461,7 +1462,7 @@
the_execution_engine in
print_string "Evaluated to ";
- print_float (GenericValue.as_float double_type result);
+ print_float (GenericValue.as_float Codegen.double_type result);
print_newline ();
with Stream.Error s | Codegen.Error s ->
(* Skip token for error recovery. *)
@@ -1500,16 +1501,15 @@
let stream = Lexer.lex (Stream.of_channel stdin) in
(* Create the JIT. *)
- let the_module_provider = ModuleProvider.create Codegen.the_module in
- let the_execution_engine = ExecutionEngine.create the_module_provider in
- let the_fpm = PassManager.create_function the_module_provider in
+ let the_execution_engine = ExecutionEngine.create Codegen.the_module in
+ let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
- add_instruction_combining the_fpm;
+ add_instruction_combination the_fpm;
(* reassociate expressions. *)
add_reassociation the_fpm;
Modified: llvm/trunk/docs/tutorial/OCamlLangImpl7.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl7.html?rev=97965&r1=97964&r2=97965&view=diff
==============================================================================
--- llvm/trunk/docs/tutorial/OCamlLangImpl7.html (original)
+++ llvm/trunk/docs/tutorial/OCamlLangImpl7.html Mon Mar 8 13:32:18 2010
@@ -543,7 +543,7 @@
let main () =
...
- let the_fpm = PassManager.create_function the_module_provider in
+ let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
@@ -1388,6 +1388,7 @@
let the_module = create_module context "my cool jit"
let builder = builder context
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
+let double_type = double_type context
(* Create an alloca instruction in the entry block of the function. This
* is used for mutable variables etc. *)
@@ -1482,7 +1483,7 @@
let start_bb = insertion_block builder in
let the_function = block_parent start_bb in
- let then_bb = append_block "then" the_function in
+ let then_bb = append_block context "then" the_function in
(* Emit 'then' value. *)
position_at_end then_bb builder;
@@ -1494,7 +1495,7 @@
let new_then_bb = insertion_block builder in
(* Emit 'else' value. *)
- let else_bb = append_block "else" the_function in
+ let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
@@ -1503,7 +1504,7 @@
let new_else_bb = insertion_block builder in
(* Emit merge block. *)
- let merge_bb = append_block "ifcont" the_function in
+ let merge_bb = append_block context "ifcont" the_function in
position_at_end merge_bb builder;
let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
let phi = build_phi incoming "iftmp" builder in
@@ -1555,7 +1556,7 @@
(* Make the new basic block for the loop header, inserting after current
* block. *)
- let loop_bb = append_block "loop" the_function in
+ let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
@@ -1599,7 +1600,7 @@
let end_cond = build_fcmp Fcmp.One end_cond zero "loopcond" builder in
(* Create the "after loop" block and insert it. *)
- let after_bb = append_block "afterloop" the_function in
+ let after_bb = append_block context "afterloop" the_function in
(* Insert the conditional branch into the end of loop_end_bb. *)
ignore (build_cond_br end_cond loop_bb after_bb builder);
@@ -1723,7 +1724,7 @@
end;
(* Create a new basic block to start insertion into. *)
- let bb = append_block "entry" the_function in
+ let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@@ -1791,7 +1792,7 @@
the_execution_engine in
print_string "Evaluated to ";
- print_float (GenericValue.as_float double_type result);
+ print_float (GenericValue.as_float Codegen.double_type result);
print_newline ();
with Stream.Error s | Codegen.Error s ->
(* Skip token for error recovery. *)
@@ -1831,9 +1832,8 @@
let stream = Lexer.lex (Stream.of_channel stdin) in
(* Create the JIT. *)
- let the_module_provider = ModuleProvider.create Codegen.the_module in
- let the_execution_engine = ExecutionEngine.create the_module_provider in
- let the_fpm = PassManager.create_function the_module_provider in
+ let the_execution_engine = ExecutionEngine.create Codegen.the_module in
+ let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
@@ -1843,7 +1843,7 @@
add_memory_to_register_promotion the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
- add_instruction_combining the_fpm;
+ add_instruction_combination the_fpm;
(* reassociate expressions. *)
add_reassociation the_fpm;
From idadesub at users.sourceforge.net Mon Mar 8 13:32:28 2010
From: idadesub at users.sourceforge.net (Erick Tryzelaar)
Date: Mon, 08 Mar 2010 19:32:28 -0000
Subject: [llvm-commits] [llvm] r97966 - in /llvm/trunk: bindings/ocaml/
examples/ examples/OCaml-Kaleidoscope/
examples/OCaml-Kaleidoscope/Chapter2/ examples/OCaml-Kaleidoscope/Chapter3/
examples/OCaml-Kaleidoscope/Chapter4/ examples/OCaml-Kaleidoscope/Chapter5/
examples/OCaml-Kaleidoscope/Chapter6/ examples/OCaml-Kaleidoscope/Chapter7/
Message-ID: <20100308193228.9B6A12A6C12C@llvm.org>
Author: erickt
Date: Mon Mar 8 13:32:27 2010
New Revision: 97966
URL: http://llvm.org/viewvc/llvm-project?rev=97966&view=rev
Log:
Add OCaml tutorial to the examples.
Added:
llvm/trunk/examples/OCaml-Kaleidoscope/
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml
llvm/trunk/examples/OCaml-Kaleidoscope/Makefile
Modified:
llvm/trunk/bindings/ocaml/Makefile.ocaml
llvm/trunk/examples/Makefile
Modified: llvm/trunk/bindings/ocaml/Makefile.ocaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/Makefile.ocaml?rev=97966&r1=97965&r2=97966&view=diff
==============================================================================
--- llvm/trunk/bindings/ocaml/Makefile.ocaml (original)
+++ llvm/trunk/bindings/ocaml/Makefile.ocaml Mon Mar 8 13:32:27 2010
@@ -66,35 +66,64 @@
Compile.CMX := $(strip $(OCAMLOPT) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
Archive.CMXA := $(strip $(OCAMLOPT) -a $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) -o)
+ifdef OCAMLOPT
+Archive.EXE := $(strip $(OCAMLOPT) -cc $(CXX) $(OCAMLCFLAGS) $(UsedOcamLibs:%=%.cmxa) $(OCAMLDEBUGFLAG) -o)
+else
+Archive.EXE := $(strip $(OCAMLC) -cc $(CXX) $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG:%=%.cma) -o)
+endif
+
# Source files
OcamlSources1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.ml))
-OcamlHeaders1 := $(OcamlSources1:.ml=.mli)
+OcamlHeaders1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.mli))
-OcamlSources := $(OcamlSources1:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
-OcamlHeaders := $(OcamlHeaders1:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
+OcamlSources2 := $(filter-out $(ExcludeSources),$(OcamlSources1))
+OcamlHeaders2 := $(filter-out $(ExcludeHeaders),$(OcamlHeaders1))
+
+OcamlSources := $(OcamlSources2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
+OcamlHeaders := $(OcamlHeaders2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
# Intermediate files
-LibraryCMA := $(ObjDir)/$(LIBRARYNAME).cma
-LibraryCMXA := $(ObjDir)/$(LIBRARYNAME).cmxa
ObjectsCMI := $(OcamlSources:%.ml=%.cmi)
ObjectsCMO := $(OcamlSources:%.ml=%.cmo)
ObjectsCMX := $(OcamlSources:%.ml=%.cmx)
+ifdef LIBRARYNAME
+LibraryCMA := $(ObjDir)/$(LIBRARYNAME).cma
+LibraryCMXA := $(ObjDir)/$(LIBRARYNAME).cmxa
+endif
+
+ifdef TOOLNAME
+ToolEXE := $(ObjDir)/$(TOOLNAME)$(EXEEXT)
+endif
+
# Output files
# The .cmo files are the only intermediates; all others are to be installed.
-LibraryA := $(OcamlDir)/lib$(LIBRARYNAME).a
-OutputCMA := $(LibraryCMA:$(ObjDir)/%.cma=$(OcamlDir)/%.cma)
-OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa)
OutputsCMI := $(ObjectsCMI:$(ObjDir)/%.cmi=$(OcamlDir)/%.cmi)
OutputsCMX := $(ObjectsCMX:$(ObjDir)/%.cmx=$(OcamlDir)/%.cmx)
OutputLibs := $(UsedLibNames:%=$(OcamlDir)/%)
+ifdef LIBRARYNAME
+LibraryA := $(OcamlDir)/lib$(LIBRARYNAME).a
+OutputCMA := $(LibraryCMA:$(ObjDir)/%.cma=$(OcamlDir)/%.cma)
+OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa)
+endif
+
+ifdef TOOLNAME
+ifdef EXAMPLE_TOOL
+OutputEXE := $(ExmplDir)/$(strip $(TOOLNAME))$(EXEEXT)
+else
+OutputEXE := $(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT)
+endif
+endif
+
# Installation targets
+DestLibs := $(UsedLibNames:%=$(PROJ_libocamldir)/%)
+
+ifdef LIBRARYNAME
DestA := $(PROJ_libocamldir)/lib$(LIBRARYNAME).a
DestCMA := $(PROJ_libocamldir)/$(LIBRARYNAME).cma
DestCMXA := $(PROJ_libocamldir)/$(LIBRARYNAME).cmxa
-DestLibs := $(UsedLibNames:%=$(PROJ_libocamldir)/%)
-
+endif
##===- Dependencies -------------------------------------------------------===##
# Copy the sources into the intermediate directory because older ocamlc doesn't
@@ -106,18 +135,27 @@
$(ObjDir)/%.ml: $(PROJ_SRC_DIR)/%.ml $(ObjDir)/.dir
$(Verb) $(CP) -f $< $@
+$(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi)
+
+ifdef LIBRARYNAME
$(ObjDir)/$(LIBRARYNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
$(OcamlDir)/.dir $(ObjDir)/.dir
$(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
-$(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi)
-
-include $(ObjDir)/$(LIBRARYNAME).ocamldep
+endif
+
+ifdef TOOLNAME
+$(ObjDir)/$(TOOLNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
+ $(OcamlDir)/.dir $(ObjDir)/.dir
+ $(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
+-include $(ObjDir)/$(TOOLNAME).ocamldep
+endif
##===- Build static library from C sources --------------------------------===##
-ifneq ($(ObjectsO),)
+ifdef LibraryA
all-local:: $(LibraryA)
clean-local:: clean-a
install-local:: install-a
@@ -160,7 +198,7 @@
$(Verb) ln -sf $< $@
clean-deplibs:
- $(Verb) rm -f $(OutputLibs)
+ $(Verb) $(RM) -f $(OutputLibs)
install-deplibs:
$(Verb) $(MKDIR) $(PROJ_libocamldir)
@@ -169,11 +207,12 @@
done
uninstall-deplibs:
- $(Verb) rm -f $(DestLibs)
+ $(Verb) $(RM) -f $(DestLibs)
##===- Build ocaml interfaces (.mli's -> .cmi's) --------------------------===##
+ifneq ($(OcamlHeaders),)
all-local:: build-cmis
clean-local:: clean-cmis
install-local:: install-cmis
@@ -212,10 +251,16 @@
$(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \
$(RM) -f "$(PROJ_libocamldir)/$$i"; \
done
+endif
##===- Build ocaml bytecode archive (.ml's -> .cmo's -> .cma) -------------===##
+$(ObjDir)/%.cmo: $(ObjDir)/%.ml
+ $(Echo) "Compiling $(notdir $<) for $(BuildMode) build"
+ $(Verb) $(Compile.CMO) $@ $<
+
+ifdef LIBRARYNAME
all-local:: $(OutputCMA)
clean-local:: clean-cma
install-local:: install-cma
@@ -228,10 +273,6 @@
$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
$(Verb) $(Archive.CMA) $@ $(ObjectsCMO)
-$(ObjDir)/%.cmo: $(ObjDir)/%.ml
- $(Echo) "Compiling $(notdir $<) for $(BuildMode) build"
- $(Verb) $(Compile.CMO) $@ $<
-
clean-cma::
$(Verb) $(RM) -f $(OutputCMA) $(UsedLibNames:%=$(OcamlDir)/%)
@@ -243,7 +284,7 @@
uninstall-cma::
$(Echo) "Uninstalling $(DestCMA)"
-$(Verb) $(RM) -f $(DestCMA)
-
+endif
##===- Build optimized ocaml archive (.ml's -> .cmx's -> .cmxa, .a) -------===##
@@ -251,6 +292,14 @@
# If unavailable, 'configure' will not define OCAMLOPT in Makefile.config.
ifdef OCAMLOPT
+$(OcamlDir)/%.cmx: $(ObjDir)/%.cmx
+ $(Verb) $(CP) -f $< $@
+
+$(ObjDir)/%.cmx: $(ObjDir)/%.ml
+ $(Echo) "Compiling optimized $(notdir $<) for $(BuildMode) build"
+ $(Verb) $(Compile.CMX) $@ $<
+
+ifdef LIBRARYNAME
all-local:: $(OutputCMXA) $(OutputsCMX)
clean-local:: clean-cmxa
install-local:: install-cmxa
@@ -260,18 +309,11 @@
$(Verb) $(CP) -f $< $@
$(Verb) $(CP) -f $(<:.cmxa=.a) $(@:.cmxa=.a)
-$(OcamlDir)/%.cmx: $(ObjDir)/%.cmx
- $(Verb) $(CP) -f $< $@
-
$(LibraryCMXA): $(ObjectsCMX)
$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
$(Verb) $(Archive.CMXA) $@ $(ObjectsCMX)
$(Verb) $(RM) -f $(@:.cmxa=.o)
-$(ObjDir)/%.cmx: $(ObjDir)/%.ml
- $(Echo) "Compiling optimized $(notdir $<) for $(BuildMode) build"
- $(Verb) $(Compile.CMX) $@ $<
-
clean-cmxa::
$(Verb) $(RM) -f $(OutputCMXA) $(OutputCMXA:.cmxa=.a) $(OutputsCMX)
@@ -295,7 +337,27 @@
$(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \
$(RM) -f $(PROJ_libocamldir)/$$i; \
done
+endif
+endif
+
+##===- Build executables --------------------------------------------------===##
+
+ifdef TOOLNAME
+all-local:: $(OutputEXE)
+clean-local:: clean-exe
+
+$(OutputEXE): $(ToolEXE) $(OcamlDir)/.dir
+ $(Verb) $(CP) -f $< $@
+ifndef OCAMLOPT
+$(ToolEXE): $(ObjectsCMO) $(OcamlDir)/.dir
+ $(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
+ $(Verb) $(Archive.EXE) $@ $<
+else
+$(ToolEXE): $(ObjectsCMX) $(OcamlDir)/.dir
+ $(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
+ $(Verb) $(Archive.EXE) $@ $<
+endif
endif
##===- Generate documentation ---------------------------------------------===##
@@ -325,7 +387,10 @@
$(Echo) "LibraryCMA : " '$(LibraryCMA)'
$(Echo) "LibraryCMXA : " '$(LibraryCMXA)'
$(Echo) "OcamlSources1: " '$(OcamlSources1)'
+ $(Echo) "OcamlSources2: " '$(OcamlSources2)'
$(Echo) "OcamlSources : " '$(OcamlSources)'
+ $(Echo) "OcamlHeaders1: " '$(OcamlHeaders1)'
+ $(Echo) "OcamlHeaders2: " '$(OcamlHeaders2)'
$(Echo) "OcamlHeaders : " '$(OcamlHeaders)'
$(Echo) "ObjectsCMI : " '$(ObjectsCMI)'
$(Echo) "ObjectsCMO : " '$(ObjectsCMO)'
@@ -340,4 +405,6 @@
.PHONY: printcamlvars build-cmis \
clean-a clean-cmis clean-cma clean-cmxa \
install-a install-cmis install-cma install-cmxa \
- uninstall-a uninstall-cmis uninstall-cma uninstall-cmxa
+ install-exe \
+ uninstall-a uninstall-cmis uninstall-cma uninstall-cmxa \
+ uninstall-exe
Modified: llvm/trunk/examples/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Makefile?rev=97966&r1=97965&r2=97966&view=diff
==============================================================================
--- llvm/trunk/examples/Makefile (original)
+++ llvm/trunk/examples/Makefile Mon Mar 8 13:32:27 2010
@@ -10,7 +10,8 @@
include $(LEVEL)/Makefile.config
-PARALLEL_DIRS:= BrainF Fibonacci HowToUseJIT Kaleidoscope ModuleMaker
+PARALLEL_DIRS:= BrainF Fibonacci HowToUseJIT Kaleidoscope ModuleMaker \
+ OCaml-Kaleidoscope
ifeq ($(HAVE_PTHREAD),1)
PARALLEL_DIRS += ParallelJIT
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/Makefile Mon Mar 8 13:32:27 2010
@@ -0,0 +1,22 @@
+##===- examples/OCaml-Kaleidoscope/Chapter2/Makefile -------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 2.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch2
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm
+
+OCAMLCFLAGS += -pp camlp4of
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/_tags Mon Mar 8 13:32:27 2010
@@ -0,0 +1 @@
+<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/ast.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,25 @@
+(*===----------------------------------------------------------------------===
+ * Abstract Syntax Tree (aka Parse Tree)
+ *===----------------------------------------------------------------------===*)
+
+(* expr - Base type for all expression nodes. *)
+type expr =
+ (* variant for numeric literals like "1.0". *)
+ | Number of float
+
+ (* variant for referencing a variable, like "a". *)
+ | Variable of string
+
+ (* variant for a binary operator. *)
+ | Binary of char * expr * expr
+
+ (* variant for function calls. *)
+ | Call of string * expr array
+
+(* proto - This type represents the "prototype" for a function, which captures
+ * its name, and its argument names (thus implicitly the number of arguments the
+ * function takes). *)
+type proto = Prototype of string * string array
+
+(* func - This type represents a function definition itself. *)
+type func = Function of proto * expr
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/lexer.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,52 @@
+(*===----------------------------------------------------------------------===
+ * Lexer
+ *===----------------------------------------------------------------------===*)
+
+let rec lex = parser
+ (* Skip any whitespace. *)
+ | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream
+
+ (* identifier: [a-zA-Z][a-zA-Z0-9] *)
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+
+ (* number: [0-9.]+ *)
+ | [< ' ('0' .. '9' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+
+ (* Comment until end of line. *)
+ | [< ' ('#'); stream >] ->
+ lex_comment stream
+
+ (* Otherwise, just return the character as its ascii value. *)
+ | [< 'c; stream >] ->
+ [< 'Token.Kwd c; lex stream >]
+
+ (* end of stream. *)
+ | [< >] -> [< >]
+
+and lex_number buffer = parser
+ | [< ' ('0' .. '9' | '.' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+ | [< stream=lex >] ->
+ [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >]
+
+and lex_ident buffer = parser
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+ | [< stream=lex >] ->
+ match Buffer.contents buffer with
+ | "def" -> [< 'Token.Def; stream >]
+ | "extern" -> [< 'Token.Extern; stream >]
+ | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+ | [< ' ('\n'); stream=lex >] -> stream
+ | [< 'c; e=lex_comment >] -> e
+ | [< >] -> [< >]
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/parser.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,122 @@
+(*===---------------------------------------------------------------------===
+ * Parser
+ *===---------------------------------------------------------------------===*)
+
+(* binop_precedence - This holds the precedence for each binary operator that is
+ * defined *)
+let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10
+
+(* precedence - Get the precedence of the pending binary operator token. *)
+let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1
+
+(* primary
+ * ::= identifier
+ * ::= numberexpr
+ * ::= parenexpr *)
+let rec parse_primary = parser
+ (* numberexpr ::= number *)
+ | [< 'Token.Number n >] -> Ast.Number n
+
+ (* parenexpr ::= '(' expression ')' *)
+ | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e
+
+ (* identifierexpr
+ * ::= identifier
+ * ::= identifier '(' argumentexpr ')' *)
+ | [< 'Token.Ident id; stream >] ->
+ let rec parse_args accumulator = parser
+ | [< e=parse_expr; stream >] ->
+ begin parser
+ | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e
+ | [< >] -> e :: accumulator
+ end stream
+ | [< >] -> accumulator
+ in
+ let rec parse_ident id = parser
+ (* Call. *)
+ | [< 'Token.Kwd '(';
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')'">] ->
+ Ast.Call (id, Array.of_list (List.rev args))
+
+ (* Simple variable ref. *)
+ | [< >] -> Ast.Variable id
+ in
+ parse_ident id stream
+
+ | [< >] -> raise (Stream.Error "unknown token when expecting an expression.")
+
+(* binoprhs
+ * ::= ('+' primary)* *)
+and parse_bin_rhs expr_prec lhs stream =
+ match Stream.peek stream with
+ (* If this is a binop, find its precedence. *)
+ | Some (Token.Kwd c) when Hashtbl.mem binop_precedence c ->
+ let token_prec = precedence c in
+
+ (* If this is a binop that binds at least as tightly as the current binop,
+ * consume it, otherwise we are done. *)
+ if token_prec < expr_prec then lhs else begin
+ (* Eat the binop. *)
+ Stream.junk stream;
+
+ (* Parse the primary expression after the binary operator. *)
+ let rhs = parse_primary stream in
+
+ (* Okay, we know this is a binop. *)
+ let rhs =
+ match Stream.peek stream with
+ | Some (Token.Kwd c2) ->
+ (* If BinOp binds less tightly with rhs than the operator after
+ * rhs, let the pending operator take rhs as its lhs. *)
+ let next_prec = precedence c2 in
+ if token_prec < next_prec
+ then parse_bin_rhs (token_prec + 1) rhs stream
+ else rhs
+ | _ -> rhs
+ in
+
+ (* Merge lhs/rhs. *)
+ let lhs = Ast.Binary (c, lhs, rhs) in
+ parse_bin_rhs expr_prec lhs stream
+ end
+ | _ -> lhs
+
+(* expression
+ * ::= primary binoprhs *)
+and parse_expr = parser
+ | [< lhs=parse_primary; stream >] -> parse_bin_rhs 0 lhs stream
+
+(* prototype
+ * ::= id '(' id* ')' *)
+let parse_prototype =
+ let rec parse_args accumulator = parser
+ | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
+ | [< >] -> accumulator
+ in
+
+ parser
+ | [< 'Token.Ident id;
+ 'Token.Kwd '(' ?? "expected '(' in prototype";
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+ (* success. *)
+ Ast.Prototype (id, Array.of_list (List.rev args))
+
+ | [< >] ->
+ raise (Stream.Error "expected function name in prototype")
+
+(* definition ::= 'def' prototype expression *)
+let parse_definition = parser
+ | [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
+ Ast.Function (p, e)
+
+(* toplevelexpr ::= expression *)
+let parse_toplevel = parser
+ | [< e=parse_expr >] ->
+ (* Make an anonymous proto. *)
+ Ast.Function (Ast.Prototype ("", [||]), e)
+
+(* external ::= 'extern' prototype *)
+let parse_extern = parser
+ | [< 'Token.Extern; e=parse_prototype >] -> e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/token.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,15 @@
+(*===----------------------------------------------------------------------===
+ * Lexer Tokens
+ *===----------------------------------------------------------------------===*)
+
+(* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of
+ * these others for known things. *)
+type token =
+ (* commands *)
+ | Def | Extern
+
+ (* primary *)
+ | Ident of string | Number of float
+
+ (* unknown *)
+ | Kwd of char
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toplevel.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,34 @@
+(*===----------------------------------------------------------------------===
+ * Top-Level parsing and JIT Driver
+ *===----------------------------------------------------------------------===*)
+
+(* top ::= definition | external | expression | ';' *)
+let rec main_loop stream =
+ match Stream.peek stream with
+ | None -> ()
+
+ (* ignore top-level semicolons. *)
+ | Some (Token.Kwd ';') ->
+ Stream.junk stream;
+ main_loop stream
+
+ | Some token ->
+ begin
+ try match token with
+ | Token.Def ->
+ ignore(Parser.parse_definition stream);
+ print_endline "parsed a function definition.";
+ | Token.Extern ->
+ ignore(Parser.parse_extern stream);
+ print_endline "parsed an extern.";
+ | _ ->
+ (* Evaluate a top-level expression into an anonymous function. *)
+ ignore(Parser.parse_toplevel stream);
+ print_endline "parsed a top-level expr";
+ with Stream.Error s ->
+ (* Skip token for error recovery. *)
+ Stream.junk stream;
+ print_endline s;
+ end;
+ print_string "ready> "; flush stdout;
+ main_loop stream
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter2/toy.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,21 @@
+(*===----------------------------------------------------------------------===
+ * Main driver code.
+ *===----------------------------------------------------------------------===*)
+
+let main () =
+ (* Install standard binary operators.
+ * 1 is the lowest precedence. *)
+ Hashtbl.add Parser.binop_precedence '<' 10;
+ Hashtbl.add Parser.binop_precedence '+' 20;
+ Hashtbl.add Parser.binop_precedence '-' 20;
+ Hashtbl.add Parser.binop_precedence '*' 40; (* highest. *)
+
+ (* Prime the first token. *)
+ print_string "ready> "; flush stdout;
+ let stream = Lexer.lex (Stream.of_channel stdin) in
+
+ (* Run the main "interpreter loop" now. *)
+ Toplevel.main_loop stream;
+;;
+
+main ()
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/Makefile Mon Mar 8 13:32:27 2010
@@ -0,0 +1,24 @@
+##===- examples/OCaml-Kaleidoscope/Chapter3/Makefile -------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 3.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch3
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/_tags Mon Mar 8 13:32:27 2010
@@ -0,0 +1,2 @@
+<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
+<*.{byte,native}>: g++, use_llvm, use_llvm_analysis
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/ast.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,25 @@
+(*===----------------------------------------------------------------------===
+ * Abstract Syntax Tree (aka Parse Tree)
+ *===----------------------------------------------------------------------===*)
+
+(* expr - Base type for all expression nodes. *)
+type expr =
+ (* variant for numeric literals like "1.0". *)
+ | Number of float
+
+ (* variant for referencing a variable, like "a". *)
+ | Variable of string
+
+ (* variant for a binary operator. *)
+ | Binary of char * expr * expr
+
+ (* variant for function calls. *)
+ | Call of string * expr array
+
+(* proto - This type represents the "prototype" for a function, which captures
+ * its name, and its argument names (thus implicitly the number of arguments the
+ * function takes). *)
+type proto = Prototype of string * string array
+
+(* func - This type represents a function definition itself. *)
+type func = Function of proto * expr
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/codegen.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,100 @@
+(*===----------------------------------------------------------------------===
+ * Code Generation
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+
+exception Error of string
+
+let context = global_context ()
+let the_module = create_module context "my cool jit"
+let builder = builder context
+let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
+let double_type = double_type context
+
+let rec codegen_expr = function
+ | Ast.Number n -> const_float double_type n
+ | Ast.Variable name ->
+ (try Hashtbl.find named_values name with
+ | Not_found -> raise (Error "unknown variable name"))
+ | Ast.Binary (op, lhs, rhs) ->
+ let lhs_val = codegen_expr lhs in
+ let rhs_val = codegen_expr rhs in
+ begin
+ match op with
+ | '+' -> build_add lhs_val rhs_val "addtmp" builder
+ | '-' -> build_sub lhs_val rhs_val "subtmp" builder
+ | '*' -> build_mul lhs_val rhs_val "multmp" builder
+ | '<' ->
+ (* Convert bool 0/1 to double 0.0 or 1.0 *)
+ let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in
+ build_uitofp i double_type "booltmp" builder
+ | _ -> raise (Error "invalid binary operator")
+ end
+ | Ast.Call (callee, args) ->
+ (* Look up the name in the module table. *)
+ let callee =
+ match lookup_function callee the_module with
+ | Some callee -> callee
+ | None -> raise (Error "unknown function referenced")
+ in
+ let params = params callee in
+
+ (* If argument mismatch error. *)
+ if Array.length params == Array.length args then () else
+ raise (Error "incorrect # arguments passed");
+ let args = Array.map codegen_expr args in
+ build_call callee args "calltmp" builder
+
+let codegen_proto = function
+ | Ast.Prototype (name, args) ->
+ (* Make the function type: double(double,double) etc. *)
+ let doubles = Array.make (Array.length args) double_type in
+ let ft = function_type double_type doubles in
+ let f =
+ match lookup_function name the_module with
+ | None -> declare_function name ft the_module
+
+ (* If 'f' conflicted, there was already something named 'name'. If it
+ * has a body, don't allow redefinition or reextern. *)
+ | Some f ->
+ (* If 'f' already has a body, reject this. *)
+ if block_begin f <> At_end f then
+ raise (Error "redefinition of function");
+
+ (* If 'f' took a different number of arguments, reject. *)
+ if element_type (type_of f) <> ft then
+ raise (Error "redefinition of function with different # args");
+ f
+ in
+
+ (* Set names for all arguments. *)
+ Array.iteri (fun i a ->
+ let n = args.(i) in
+ set_value_name n a;
+ Hashtbl.add named_values n a;
+ ) (params f);
+ f
+
+let codegen_func = function
+ | Ast.Function (proto, body) ->
+ Hashtbl.clear named_values;
+ let the_function = codegen_proto proto in
+
+ (* Create a new basic block to start insertion into. *)
+ let bb = append_block context "entry" the_function in
+ position_at_end bb builder;
+
+ try
+ let ret_val = codegen_expr body in
+
+ (* Finish off the function. *)
+ let _ = build_ret ret_val builder in
+
+ (* Validate the generated code, checking for consistency. *)
+ Llvm_analysis.assert_valid_function the_function;
+
+ the_function
+ with e ->
+ delete_function the_function;
+ raise e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/lexer.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,52 @@
+(*===----------------------------------------------------------------------===
+ * Lexer
+ *===----------------------------------------------------------------------===*)
+
+let rec lex = parser
+ (* Skip any whitespace. *)
+ | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream
+
+ (* identifier: [a-zA-Z][a-zA-Z0-9] *)
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+
+ (* number: [0-9.]+ *)
+ | [< ' ('0' .. '9' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+
+ (* Comment until end of line. *)
+ | [< ' ('#'); stream >] ->
+ lex_comment stream
+
+ (* Otherwise, just return the character as its ascii value. *)
+ | [< 'c; stream >] ->
+ [< 'Token.Kwd c; lex stream >]
+
+ (* end of stream. *)
+ | [< >] -> [< >]
+
+and lex_number buffer = parser
+ | [< ' ('0' .. '9' | '.' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+ | [< stream=lex >] ->
+ [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >]
+
+and lex_ident buffer = parser
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+ | [< stream=lex >] ->
+ match Buffer.contents buffer with
+ | "def" -> [< 'Token.Def; stream >]
+ | "extern" -> [< 'Token.Extern; stream >]
+ | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+ | [< ' ('\n'); stream=lex >] -> stream
+ | [< 'c; e=lex_comment >] -> e
+ | [< >] -> [< >]
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/myocamlbuild.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,6 @@
+open Ocamlbuild_plugin;;
+
+ocaml_lib ~extern:true "llvm";;
+ocaml_lib ~extern:true "llvm_analysis";;
+
+flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);;
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/parser.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,122 @@
+(*===---------------------------------------------------------------------===
+ * Parser
+ *===---------------------------------------------------------------------===*)
+
+(* binop_precedence - This holds the precedence for each binary operator that is
+ * defined *)
+let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10
+
+(* precedence - Get the precedence of the pending binary operator token. *)
+let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1
+
+(* primary
+ * ::= identifier
+ * ::= numberexpr
+ * ::= parenexpr *)
+let rec parse_primary = parser
+ (* numberexpr ::= number *)
+ | [< 'Token.Number n >] -> Ast.Number n
+
+ (* parenexpr ::= '(' expression ')' *)
+ | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e
+
+ (* identifierexpr
+ * ::= identifier
+ * ::= identifier '(' argumentexpr ')' *)
+ | [< 'Token.Ident id; stream >] ->
+ let rec parse_args accumulator = parser
+ | [< e=parse_expr; stream >] ->
+ begin parser
+ | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e
+ | [< >] -> e :: accumulator
+ end stream
+ | [< >] -> accumulator
+ in
+ let rec parse_ident id = parser
+ (* Call. *)
+ | [< 'Token.Kwd '(';
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')'">] ->
+ Ast.Call (id, Array.of_list (List.rev args))
+
+ (* Simple variable ref. *)
+ | [< >] -> Ast.Variable id
+ in
+ parse_ident id stream
+
+ | [< >] -> raise (Stream.Error "unknown token when expecting an expression.")
+
+(* binoprhs
+ * ::= ('+' primary)* *)
+and parse_bin_rhs expr_prec lhs stream =
+ match Stream.peek stream with
+ (* If this is a binop, find its precedence. *)
+ | Some (Token.Kwd c) when Hashtbl.mem binop_precedence c ->
+ let token_prec = precedence c in
+
+ (* If this is a binop that binds at least as tightly as the current binop,
+ * consume it, otherwise we are done. *)
+ if token_prec < expr_prec then lhs else begin
+ (* Eat the binop. *)
+ Stream.junk stream;
+
+ (* Parse the primary expression after the binary operator. *)
+ let rhs = parse_primary stream in
+
+ (* Okay, we know this is a binop. *)
+ let rhs =
+ match Stream.peek stream with
+ | Some (Token.Kwd c2) ->
+ (* If BinOp binds less tightly with rhs than the operator after
+ * rhs, let the pending operator take rhs as its lhs. *)
+ let next_prec = precedence c2 in
+ if token_prec < next_prec
+ then parse_bin_rhs (token_prec + 1) rhs stream
+ else rhs
+ | _ -> rhs
+ in
+
+ (* Merge lhs/rhs. *)
+ let lhs = Ast.Binary (c, lhs, rhs) in
+ parse_bin_rhs expr_prec lhs stream
+ end
+ | _ -> lhs
+
+(* expression
+ * ::= primary binoprhs *)
+and parse_expr = parser
+ | [< lhs=parse_primary; stream >] -> parse_bin_rhs 0 lhs stream
+
+(* prototype
+ * ::= id '(' id* ')' *)
+let parse_prototype =
+ let rec parse_args accumulator = parser
+ | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
+ | [< >] -> accumulator
+ in
+
+ parser
+ | [< 'Token.Ident id;
+ 'Token.Kwd '(' ?? "expected '(' in prototype";
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+ (* success. *)
+ Ast.Prototype (id, Array.of_list (List.rev args))
+
+ | [< >] ->
+ raise (Stream.Error "expected function name in prototype")
+
+(* definition ::= 'def' prototype expression *)
+let parse_definition = parser
+ | [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
+ Ast.Function (p, e)
+
+(* toplevelexpr ::= expression *)
+let parse_toplevel = parser
+ | [< e=parse_expr >] ->
+ (* Make an anonymous proto. *)
+ Ast.Function (Ast.Prototype ("", [||]), e)
+
+(* external ::= 'extern' prototype *)
+let parse_extern = parser
+ | [< 'Token.Extern; e=parse_prototype >] -> e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/token.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,15 @@
+(*===----------------------------------------------------------------------===
+ * Lexer Tokens
+ *===----------------------------------------------------------------------===*)
+
+(* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of
+ * these others for known things. *)
+type token =
+ (* commands *)
+ | Def | Extern
+
+ (* primary *)
+ | Ident of string | Number of float
+
+ (* unknown *)
+ | Kwd of char
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toplevel.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,39 @@
+(*===----------------------------------------------------------------------===
+ * Top-Level parsing and JIT Driver
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+
+(* top ::= definition | external | expression | ';' *)
+let rec main_loop stream =
+ match Stream.peek stream with
+ | None -> ()
+
+ (* ignore top-level semicolons. *)
+ | Some (Token.Kwd ';') ->
+ Stream.junk stream;
+ main_loop stream
+
+ | Some token ->
+ begin
+ try match token with
+ | Token.Def ->
+ let e = Parser.parse_definition stream in
+ print_endline "parsed a function definition.";
+ dump_value (Codegen.codegen_func e);
+ | Token.Extern ->
+ let e = Parser.parse_extern stream in
+ print_endline "parsed an extern.";
+ dump_value (Codegen.codegen_proto e);
+ | _ ->
+ (* Evaluate a top-level expression into an anonymous function. *)
+ let e = Parser.parse_toplevel stream in
+ print_endline "parsed a top-level expr";
+ dump_value (Codegen.codegen_func e);
+ with Stream.Error s | Codegen.Error s ->
+ (* Skip token for error recovery. *)
+ Stream.junk stream;
+ print_endline s;
+ end;
+ print_string "ready> "; flush stdout;
+ main_loop stream
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter3/toy.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,26 @@
+(*===----------------------------------------------------------------------===
+ * Main driver code.
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+
+let main () =
+ (* Install standard binary operators.
+ * 1 is the lowest precedence. *)
+ Hashtbl.add Parser.binop_precedence '<' 10;
+ Hashtbl.add Parser.binop_precedence '+' 20;
+ Hashtbl.add Parser.binop_precedence '-' 20;
+ Hashtbl.add Parser.binop_precedence '*' 40; (* highest. *)
+
+ (* Prime the first token. *)
+ print_string "ready> "; flush stdout;
+ let stream = Lexer.lex (Stream.of_channel stdin) in
+
+ (* Run the main "interpreter loop" now. *)
+ Toplevel.main_loop stream;
+
+ (* Print out all the generated code. *)
+ dump_module Codegen.the_module
+;;
+
+main ()
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/Makefile Mon Mar 8 13:32:27 2010
@@ -0,0 +1,25 @@
+##===- examples/OCaml-Kaleidoscope/Chapter4/Makefile -------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 4.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch4
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
+ llvm_scalar_opts
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/_tags Mon Mar 8 13:32:27 2010
@@ -0,0 +1,4 @@
+<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
+<*.{byte,native}>: g++, use_llvm, use_llvm_analysis
+<*.{byte,native}>: use_llvm_executionengine, use_llvm_target
+<*.{byte,native}>: use_llvm_scalar_opts, use_bindings
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/ast.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,25 @@
+(*===----------------------------------------------------------------------===
+ * Abstract Syntax Tree (aka Parse Tree)
+ *===----------------------------------------------------------------------===*)
+
+(* expr - Base type for all expression nodes. *)
+type expr =
+ (* variant for numeric literals like "1.0". *)
+ | Number of float
+
+ (* variant for referencing a variable, like "a". *)
+ | Variable of string
+
+ (* variant for a binary operator. *)
+ | Binary of char * expr * expr
+
+ (* variant for function calls. *)
+ | Call of string * expr array
+
+(* proto - This type represents the "prototype" for a function, which captures
+ * its name, and its argument names (thus implicitly the number of arguments the
+ * function takes). *)
+type proto = Prototype of string * string array
+
+(* func - This type represents a function definition itself. *)
+type func = Function of proto * expr
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/bindings.c Mon Mar 8 13:32:27 2010
@@ -0,0 +1,7 @@
+#include
+
+/* putchard - putchar that takes a double and returns 0. */
+extern double putchard(double X) {
+ putchar((char)X);
+ return 0;
+}
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/codegen.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,103 @@
+(*===----------------------------------------------------------------------===
+ * Code Generation
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+
+exception Error of string
+
+let context = global_context ()
+let the_module = create_module context "my cool jit"
+let builder = builder context
+let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
+let double_type = double_type context
+
+let rec codegen_expr = function
+ | Ast.Number n -> const_float double_type n
+ | Ast.Variable name ->
+ (try Hashtbl.find named_values name with
+ | Not_found -> raise (Error "unknown variable name"))
+ | Ast.Binary (op, lhs, rhs) ->
+ let lhs_val = codegen_expr lhs in
+ let rhs_val = codegen_expr rhs in
+ begin
+ match op with
+ | '+' -> build_add lhs_val rhs_val "addtmp" builder
+ | '-' -> build_sub lhs_val rhs_val "subtmp" builder
+ | '*' -> build_mul lhs_val rhs_val "multmp" builder
+ | '<' ->
+ (* Convert bool 0/1 to double 0.0 or 1.0 *)
+ let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in
+ build_uitofp i double_type "booltmp" builder
+ | _ -> raise (Error "invalid binary operator")
+ end
+ | Ast.Call (callee, args) ->
+ (* Look up the name in the module table. *)
+ let callee =
+ match lookup_function callee the_module with
+ | Some callee -> callee
+ | None -> raise (Error "unknown function referenced")
+ in
+ let params = params callee in
+
+ (* If argument mismatch error. *)
+ if Array.length params == Array.length args then () else
+ raise (Error "incorrect # arguments passed");
+ let args = Array.map codegen_expr args in
+ build_call callee args "calltmp" builder
+
+let codegen_proto = function
+ | Ast.Prototype (name, args) ->
+ (* Make the function type: double(double,double) etc. *)
+ let doubles = Array.make (Array.length args) double_type in
+ let ft = function_type double_type doubles in
+ let f =
+ match lookup_function name the_module with
+ | None -> declare_function name ft the_module
+
+ (* If 'f' conflicted, there was already something named 'name'. If it
+ * has a body, don't allow redefinition or reextern. *)
+ | Some f ->
+ (* If 'f' already has a body, reject this. *)
+ if block_begin f <> At_end f then
+ raise (Error "redefinition of function");
+
+ (* If 'f' took a different number of arguments, reject. *)
+ if element_type (type_of f) <> ft then
+ raise (Error "redefinition of function with different # args");
+ f
+ in
+
+ (* Set names for all arguments. *)
+ Array.iteri (fun i a ->
+ let n = args.(i) in
+ set_value_name n a;
+ Hashtbl.add named_values n a;
+ ) (params f);
+ f
+
+let codegen_func the_fpm = function
+ | Ast.Function (proto, body) ->
+ Hashtbl.clear named_values;
+ let the_function = codegen_proto proto in
+
+ (* Create a new basic block to start insertion into. *)
+ let bb = append_block context "entry" the_function in
+ position_at_end bb builder;
+
+ try
+ let ret_val = codegen_expr body in
+
+ (* Finish off the function. *)
+ let _ = build_ret ret_val builder in
+
+ (* Validate the generated code, checking for consistency. *)
+ Llvm_analysis.assert_valid_function the_function;
+
+ (* Optimize the function. *)
+ let _ = PassManager.run_function the_function the_fpm in
+
+ the_function
+ with e ->
+ delete_function the_function;
+ raise e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/lexer.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,52 @@
+(*===----------------------------------------------------------------------===
+ * Lexer
+ *===----------------------------------------------------------------------===*)
+
+let rec lex = parser
+ (* Skip any whitespace. *)
+ | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream
+
+ (* identifier: [a-zA-Z][a-zA-Z0-9] *)
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+
+ (* number: [0-9.]+ *)
+ | [< ' ('0' .. '9' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+
+ (* Comment until end of line. *)
+ | [< ' ('#'); stream >] ->
+ lex_comment stream
+
+ (* Otherwise, just return the character as its ascii value. *)
+ | [< 'c; stream >] ->
+ [< 'Token.Kwd c; lex stream >]
+
+ (* end of stream. *)
+ | [< >] -> [< >]
+
+and lex_number buffer = parser
+ | [< ' ('0' .. '9' | '.' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+ | [< stream=lex >] ->
+ [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >]
+
+and lex_ident buffer = parser
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+ | [< stream=lex >] ->
+ match Buffer.contents buffer with
+ | "def" -> [< 'Token.Def; stream >]
+ | "extern" -> [< 'Token.Extern; stream >]
+ | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+ | [< ' ('\n'); stream=lex >] -> stream
+ | [< 'c; e=lex_comment >] -> e
+ | [< >] -> [< >]
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/myocamlbuild.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,10 @@
+open Ocamlbuild_plugin;;
+
+ocaml_lib ~extern:true "llvm";;
+ocaml_lib ~extern:true "llvm_analysis";;
+ocaml_lib ~extern:true "llvm_executionengine";;
+ocaml_lib ~extern:true "llvm_target";;
+ocaml_lib ~extern:true "llvm_scalar_opts";;
+
+flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);;
+dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];;
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/parser.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,122 @@
+(*===---------------------------------------------------------------------===
+ * Parser
+ *===---------------------------------------------------------------------===*)
+
+(* binop_precedence - This holds the precedence for each binary operator that is
+ * defined *)
+let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10
+
+(* precedence - Get the precedence of the pending binary operator token. *)
+let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1
+
+(* primary
+ * ::= identifier
+ * ::= numberexpr
+ * ::= parenexpr *)
+let rec parse_primary = parser
+ (* numberexpr ::= number *)
+ | [< 'Token.Number n >] -> Ast.Number n
+
+ (* parenexpr ::= '(' expression ')' *)
+ | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e
+
+ (* identifierexpr
+ * ::= identifier
+ * ::= identifier '(' argumentexpr ')' *)
+ | [< 'Token.Ident id; stream >] ->
+ let rec parse_args accumulator = parser
+ | [< e=parse_expr; stream >] ->
+ begin parser
+ | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e
+ | [< >] -> e :: accumulator
+ end stream
+ | [< >] -> accumulator
+ in
+ let rec parse_ident id = parser
+ (* Call. *)
+ | [< 'Token.Kwd '(';
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')'">] ->
+ Ast.Call (id, Array.of_list (List.rev args))
+
+ (* Simple variable ref. *)
+ | [< >] -> Ast.Variable id
+ in
+ parse_ident id stream
+
+ | [< >] -> raise (Stream.Error "unknown token when expecting an expression.")
+
+(* binoprhs
+ * ::= ('+' primary)* *)
+and parse_bin_rhs expr_prec lhs stream =
+ match Stream.peek stream with
+ (* If this is a binop, find its precedence. *)
+ | Some (Token.Kwd c) when Hashtbl.mem binop_precedence c ->
+ let token_prec = precedence c in
+
+ (* If this is a binop that binds at least as tightly as the current binop,
+ * consume it, otherwise we are done. *)
+ if token_prec < expr_prec then lhs else begin
+ (* Eat the binop. *)
+ Stream.junk stream;
+
+ (* Parse the primary expression after the binary operator. *)
+ let rhs = parse_primary stream in
+
+ (* Okay, we know this is a binop. *)
+ let rhs =
+ match Stream.peek stream with
+ | Some (Token.Kwd c2) ->
+ (* If BinOp binds less tightly with rhs than the operator after
+ * rhs, let the pending operator take rhs as its lhs. *)
+ let next_prec = precedence c2 in
+ if token_prec < next_prec
+ then parse_bin_rhs (token_prec + 1) rhs stream
+ else rhs
+ | _ -> rhs
+ in
+
+ (* Merge lhs/rhs. *)
+ let lhs = Ast.Binary (c, lhs, rhs) in
+ parse_bin_rhs expr_prec lhs stream
+ end
+ | _ -> lhs
+
+(* expression
+ * ::= primary binoprhs *)
+and parse_expr = parser
+ | [< lhs=parse_primary; stream >] -> parse_bin_rhs 0 lhs stream
+
+(* prototype
+ * ::= id '(' id* ')' *)
+let parse_prototype =
+ let rec parse_args accumulator = parser
+ | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
+ | [< >] -> accumulator
+ in
+
+ parser
+ | [< 'Token.Ident id;
+ 'Token.Kwd '(' ?? "expected '(' in prototype";
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+ (* success. *)
+ Ast.Prototype (id, Array.of_list (List.rev args))
+
+ | [< >] ->
+ raise (Stream.Error "expected function name in prototype")
+
+(* definition ::= 'def' prototype expression *)
+let parse_definition = parser
+ | [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
+ Ast.Function (p, e)
+
+(* toplevelexpr ::= expression *)
+let parse_toplevel = parser
+ | [< e=parse_expr >] ->
+ (* Make an anonymous proto. *)
+ Ast.Function (Ast.Prototype ("", [||]), e)
+
+(* external ::= 'extern' prototype *)
+let parse_extern = parser
+ | [< 'Token.Extern; e=parse_prototype >] -> e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/token.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,15 @@
+(*===----------------------------------------------------------------------===
+ * Lexer Tokens
+ *===----------------------------------------------------------------------===*)
+
+(* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of
+ * these others for known things. *)
+type token =
+ (* commands *)
+ | Def | Extern
+
+ (* primary *)
+ | Ident of string | Number of float
+
+ (* unknown *)
+ | Kwd of char
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toplevel.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,49 @@
+(*===----------------------------------------------------------------------===
+ * Top-Level parsing and JIT Driver
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+open Llvm_executionengine
+
+(* top ::= definition | external | expression | ';' *)
+let rec main_loop the_fpm the_execution_engine stream =
+ match Stream.peek stream with
+ | None -> ()
+
+ (* ignore top-level semicolons. *)
+ | Some (Token.Kwd ';') ->
+ Stream.junk stream;
+ main_loop the_fpm the_execution_engine stream
+
+ | Some token ->
+ begin
+ try match token with
+ | Token.Def ->
+ let e = Parser.parse_definition stream in
+ print_endline "parsed a function definition.";
+ dump_value (Codegen.codegen_func the_fpm e);
+ | Token.Extern ->
+ let e = Parser.parse_extern stream in
+ print_endline "parsed an extern.";
+ dump_value (Codegen.codegen_proto e);
+ | _ ->
+ (* Evaluate a top-level expression into an anonymous function. *)
+ let e = Parser.parse_toplevel stream in
+ print_endline "parsed a top-level expr";
+ let the_function = Codegen.codegen_func the_fpm e in
+ dump_value the_function;
+
+ (* JIT the function, returning a function pointer. *)
+ let result = ExecutionEngine.run_function the_function [||]
+ the_execution_engine in
+
+ print_string "Evaluated to ";
+ print_float (GenericValue.as_float Codegen.double_type result);
+ print_newline ();
+ with Stream.Error s | Codegen.Error s ->
+ (* Skip token for error recovery. *)
+ Stream.junk stream;
+ print_endline s;
+ end;
+ print_string "ready> "; flush stdout;
+ main_loop the_fpm the_execution_engine stream
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter4/toy.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,53 @@
+(*===----------------------------------------------------------------------===
+ * Main driver code.
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+open Llvm_executionengine
+open Llvm_target
+open Llvm_scalar_opts
+
+let main () =
+ ignore (initialize_native_target ());
+
+ (* Install standard binary operators.
+ * 1 is the lowest precedence. *)
+ Hashtbl.add Parser.binop_precedence '<' 10;
+ Hashtbl.add Parser.binop_precedence '+' 20;
+ Hashtbl.add Parser.binop_precedence '-' 20;
+ Hashtbl.add Parser.binop_precedence '*' 40; (* highest. *)
+
+ (* Prime the first token. *)
+ print_string "ready> "; flush stdout;
+ let stream = Lexer.lex (Stream.of_channel stdin) in
+
+ (* Create the JIT. *)
+ let the_execution_engine = ExecutionEngine.create Codegen.the_module in
+ let the_fpm = PassManager.create_function Codegen.the_module in
+
+ (* Set up the optimizer pipeline. Start with registering info about how the
+ * target lays out data structures. *)
+ TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+
+ (* Do simple "peephole" optimizations and bit-twiddling optzn. *)
+ add_instruction_combination the_fpm;
+
+ (* reassociate expressions. *)
+ add_reassociation the_fpm;
+
+ (* Eliminate Common SubExpressions. *)
+ add_gvn the_fpm;
+
+ (* Simplify the control flow graph (deleting unreachable blocks, etc). *)
+ add_cfg_simplification the_fpm;
+
+ ignore (PassManager.initialize the_fpm);
+
+ (* Run the main "interpreter loop" now. *)
+ Toplevel.main_loop the_fpm the_execution_engine stream;
+
+ (* Print out all the generated code. *)
+ dump_module Codegen.the_module
+;;
+
+main ()
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/Makefile Mon Mar 8 13:32:27 2010
@@ -0,0 +1,25 @@
+##===- examples/OCaml-Kaleidoscope/Chapter5/Makefile -------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 5.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch5
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
+ llvm_scalar_opts
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/_tags Mon Mar 8 13:32:27 2010
@@ -0,0 +1,4 @@
+<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
+<*.{byte,native}>: g++, use_llvm, use_llvm_analysis
+<*.{byte,native}>: use_llvm_executionengine, use_llvm_target
+<*.{byte,native}>: use_llvm_scalar_opts, use_bindings
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/ast.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,31 @@
+(*===----------------------------------------------------------------------===
+ * Abstract Syntax Tree (aka Parse Tree)
+ *===----------------------------------------------------------------------===*)
+
+(* expr - Base type for all expression nodes. *)
+type expr =
+ (* variant for numeric literals like "1.0". *)
+ | Number of float
+
+ (* variant for referencing a variable, like "a". *)
+ | Variable of string
+
+ (* variant for a binary operator. *)
+ | Binary of char * expr * expr
+
+ (* variant for function calls. *)
+ | Call of string * expr array
+
+ (* variant for if/then/else. *)
+ | If of expr * expr * expr
+
+ (* variant for for/in. *)
+ | For of string * expr * expr * expr option * expr
+
+(* proto - This type represents the "prototype" for a function, which captures
+ * its name, and its argument names (thus implicitly the number of arguments the
+ * function takes). *)
+type proto = Prototype of string * string array
+
+(* func - This type represents a function definition itself. *)
+type func = Function of proto * expr
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/bindings.c Mon Mar 8 13:32:27 2010
@@ -0,0 +1,7 @@
+#include
+
+/* putchard - putchar that takes a double and returns 0. */
+extern double putchard(double X) {
+ putchar((char)X);
+ return 0;
+}
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/codegen.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,225 @@
+(*===----------------------------------------------------------------------===
+ * Code Generation
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+
+exception Error of string
+
+let context = global_context ()
+let the_module = create_module context "my cool jit"
+let builder = builder context
+let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
+let double_type = double_type context
+
+let rec codegen_expr = function
+ | Ast.Number n -> const_float double_type n
+ | Ast.Variable name ->
+ (try Hashtbl.find named_values name with
+ | Not_found -> raise (Error "unknown variable name"))
+ | Ast.Binary (op, lhs, rhs) ->
+ let lhs_val = codegen_expr lhs in
+ let rhs_val = codegen_expr rhs in
+ begin
+ match op with
+ | '+' -> build_add lhs_val rhs_val "addtmp" builder
+ | '-' -> build_sub lhs_val rhs_val "subtmp" builder
+ | '*' -> build_mul lhs_val rhs_val "multmp" builder
+ | '<' ->
+ (* Convert bool 0/1 to double 0.0 or 1.0 *)
+ let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in
+ build_uitofp i double_type "booltmp" builder
+ | _ -> raise (Error "invalid binary operator")
+ end
+ | Ast.Call (callee, args) ->
+ (* Look up the name in the module table. *)
+ let callee =
+ match lookup_function callee the_module with
+ | Some callee -> callee
+ | None -> raise (Error "unknown function referenced")
+ in
+ let params = params callee in
+
+ (* If argument mismatch error. *)
+ if Array.length params == Array.length args then () else
+ raise (Error "incorrect # arguments passed");
+ let args = Array.map codegen_expr args in
+ build_call callee args "calltmp" builder
+ | Ast.If (cond, then_, else_) ->
+ let cond = codegen_expr cond in
+
+ (* Convert condition to a bool by comparing equal to 0.0 *)
+ let zero = const_float double_type 0.0 in
+ let cond_val = build_fcmp Fcmp.One cond zero "ifcond" builder in
+
+ (* Grab the first block so that we might later add the conditional branch
+ * to it at the end of the function. *)
+ let start_bb = insertion_block builder in
+ let the_function = block_parent start_bb in
+
+ let then_bb = append_block context "then" the_function in
+
+ (* Emit 'then' value. *)
+ position_at_end then_bb builder;
+ let then_val = codegen_expr then_ in
+
+ (* Codegen of 'then' can change the current block, update then_bb for the
+ * phi. We create a new name because one is used for the phi node, and the
+ * other is used for the conditional branch. *)
+ let new_then_bb = insertion_block builder in
+
+ (* Emit 'else' value. *)
+ let else_bb = append_block context "else" the_function in
+ position_at_end else_bb builder;
+ let else_val = codegen_expr else_ in
+
+ (* Codegen of 'else' can change the current block, update else_bb for the
+ * phi. *)
+ let new_else_bb = insertion_block builder in
+
+ (* Emit merge block. *)
+ let merge_bb = append_block context "ifcont" the_function in
+ position_at_end merge_bb builder;
+ let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
+ let phi = build_phi incoming "iftmp" builder in
+
+ (* Return to the start block to add the conditional branch. *)
+ position_at_end start_bb builder;
+ ignore (build_cond_br cond_val then_bb else_bb builder);
+
+ (* Set a unconditional branch at the end of the 'then' block and the
+ * 'else' block to the 'merge' block. *)
+ position_at_end new_then_bb builder; ignore (build_br merge_bb builder);
+ position_at_end new_else_bb builder; ignore (build_br merge_bb builder);
+
+ (* Finally, set the builder to the end of the merge block. *)
+ position_at_end merge_bb builder;
+
+ phi
+ | Ast.For (var_name, start, end_, step, body) ->
+ (* Emit the start code first, without 'variable' in scope. *)
+ let start_val = codegen_expr start in
+
+ (* Make the new basic block for the loop header, inserting after current
+ * block. *)
+ let preheader_bb = insertion_block builder in
+ let the_function = block_parent preheader_bb in
+ let loop_bb = append_block context "loop" the_function in
+
+ (* Insert an explicit fall through from the current block to the
+ * loop_bb. *)
+ ignore (build_br loop_bb builder);
+
+ (* Start insertion in loop_bb. *)
+ position_at_end loop_bb builder;
+
+ (* Start the PHI node with an entry for start. *)
+ let variable = build_phi [(start_val, preheader_bb)] var_name builder in
+
+ (* Within the loop, the variable is defined equal to the PHI node. If it
+ * shadows an existing variable, we have to restore it, so save it
+ * now. *)
+ let old_val =
+ try Some (Hashtbl.find named_values var_name) with Not_found -> None
+ in
+ Hashtbl.add named_values var_name variable;
+
+ (* Emit the body of the loop. This, like any other expr, can change the
+ * current BB. Note that we ignore the value computed by the body, but
+ * don't allow an error *)
+ ignore (codegen_expr body);
+
+ (* Emit the step value. *)
+ let step_val =
+ match step with
+ | Some step -> codegen_expr step
+ (* If not specified, use 1.0. *)
+ | None -> const_float double_type 1.0
+ in
+
+ let next_var = build_add variable step_val "nextvar" builder in
+
+ (* Compute the end condition. *)
+ let end_cond = codegen_expr end_ in
+
+ (* Convert condition to a bool by comparing equal to 0.0. *)
+ let zero = const_float double_type 0.0 in
+ let end_cond = build_fcmp Fcmp.One end_cond zero "loopcond" builder in
+
+ (* Create the "after loop" block and insert it. *)
+ let loop_end_bb = insertion_block builder in
+ let after_bb = append_block context "afterloop" the_function in
+
+ (* Insert the conditional branch into the end of loop_end_bb. *)
+ ignore (build_cond_br end_cond loop_bb after_bb builder);
+
+ (* Any new code will be inserted in after_bb. *)
+ position_at_end after_bb builder;
+
+ (* Add a new entry to the PHI node for the backedge. *)
+ add_incoming (next_var, loop_end_bb) variable;
+
+ (* Restore the unshadowed variable. *)
+ begin match old_val with
+ | Some old_val -> Hashtbl.add named_values var_name old_val
+ | None -> ()
+ end;
+
+ (* for expr always returns 0.0. *)
+ const_null double_type
+
+let codegen_proto = function
+ | Ast.Prototype (name, args) ->
+ (* Make the function type: double(double,double) etc. *)
+ let doubles = Array.make (Array.length args) double_type in
+ let ft = function_type double_type doubles in
+ let f =
+ match lookup_function name the_module with
+ | None -> declare_function name ft the_module
+
+ (* If 'f' conflicted, there was already something named 'name'. If it
+ * has a body, don't allow redefinition or reextern. *)
+ | Some f ->
+ (* If 'f' already has a body, reject this. *)
+ if block_begin f <> At_end f then
+ raise (Error "redefinition of function");
+
+ (* If 'f' took a different number of arguments, reject. *)
+ if element_type (type_of f) <> ft then
+ raise (Error "redefinition of function with different # args");
+ f
+ in
+
+ (* Set names for all arguments. *)
+ Array.iteri (fun i a ->
+ let n = args.(i) in
+ set_value_name n a;
+ Hashtbl.add named_values n a;
+ ) (params f);
+ f
+
+let codegen_func the_fpm = function
+ | Ast.Function (proto, body) ->
+ Hashtbl.clear named_values;
+ let the_function = codegen_proto proto in
+
+ (* Create a new basic block to start insertion into. *)
+ let bb = append_block context "entry" the_function in
+ position_at_end bb builder;
+
+ try
+ let ret_val = codegen_expr body in
+
+ (* Finish off the function. *)
+ let _ = build_ret ret_val builder in
+
+ (* Validate the generated code, checking for consistency. *)
+ Llvm_analysis.assert_valid_function the_function;
+
+ (* Optimize the function. *)
+ let _ = PassManager.run_function the_function the_fpm in
+
+ the_function
+ with e ->
+ delete_function the_function;
+ raise e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/lexer.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,57 @@
+(*===----------------------------------------------------------------------===
+ * Lexer
+ *===----------------------------------------------------------------------===*)
+
+let rec lex = parser
+ (* Skip any whitespace. *)
+ | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream
+
+ (* identifier: [a-zA-Z][a-zA-Z0-9] *)
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+
+ (* number: [0-9.]+ *)
+ | [< ' ('0' .. '9' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+
+ (* Comment until end of line. *)
+ | [< ' ('#'); stream >] ->
+ lex_comment stream
+
+ (* Otherwise, just return the character as its ascii value. *)
+ | [< 'c; stream >] ->
+ [< 'Token.Kwd c; lex stream >]
+
+ (* end of stream. *)
+ | [< >] -> [< >]
+
+and lex_number buffer = parser
+ | [< ' ('0' .. '9' | '.' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+ | [< stream=lex >] ->
+ [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >]
+
+and lex_ident buffer = parser
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+ | [< stream=lex >] ->
+ match Buffer.contents buffer with
+ | "def" -> [< 'Token.Def; stream >]
+ | "extern" -> [< 'Token.Extern; stream >]
+ | "if" -> [< 'Token.If; stream >]
+ | "then" -> [< 'Token.Then; stream >]
+ | "else" -> [< 'Token.Else; stream >]
+ | "for" -> [< 'Token.For; stream >]
+ | "in" -> [< 'Token.In; stream >]
+ | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+ | [< ' ('\n'); stream=lex >] -> stream
+ | [< 'c; e=lex_comment >] -> e
+ | [< >] -> [< >]
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/myocamlbuild.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,10 @@
+open Ocamlbuild_plugin;;
+
+ocaml_lib ~extern:true "llvm";;
+ocaml_lib ~extern:true "llvm_analysis";;
+ocaml_lib ~extern:true "llvm_executionengine";;
+ocaml_lib ~extern:true "llvm_target";;
+ocaml_lib ~extern:true "llvm_scalar_opts";;
+
+flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);;
+dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];;
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/parser.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,158 @@
+(*===---------------------------------------------------------------------===
+ * Parser
+ *===---------------------------------------------------------------------===*)
+
+(* binop_precedence - This holds the precedence for each binary operator that is
+ * defined *)
+let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10
+
+(* precedence - Get the precedence of the pending binary operator token. *)
+let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1
+
+(* primary
+ * ::= identifier
+ * ::= numberexpr
+ * ::= parenexpr
+ * ::= ifexpr
+ * ::= forexpr *)
+let rec parse_primary = parser
+ (* numberexpr ::= number *)
+ | [< 'Token.Number n >] -> Ast.Number n
+
+ (* parenexpr ::= '(' expression ')' *)
+ | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e
+
+ (* identifierexpr
+ * ::= identifier
+ * ::= identifier '(' argumentexpr ')' *)
+ | [< 'Token.Ident id; stream >] ->
+ let rec parse_args accumulator = parser
+ | [< e=parse_expr; stream >] ->
+ begin parser
+ | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e
+ | [< >] -> e :: accumulator
+ end stream
+ | [< >] -> accumulator
+ in
+ let rec parse_ident id = parser
+ (* Call. *)
+ | [< 'Token.Kwd '(';
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')'">] ->
+ Ast.Call (id, Array.of_list (List.rev args))
+
+ (* Simple variable ref. *)
+ | [< >] -> Ast.Variable id
+ in
+ parse_ident id stream
+
+ (* ifexpr ::= 'if' expr 'then' expr 'else' expr *)
+ | [< 'Token.If; c=parse_expr;
+ 'Token.Then ?? "expected 'then'"; t=parse_expr;
+ 'Token.Else ?? "expected 'else'"; e=parse_expr >] ->
+ Ast.If (c, t, e)
+
+ (* forexpr
+ ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)
+ | [< 'Token.For;
+ 'Token.Ident id ?? "expected identifier after for";
+ 'Token.Kwd '=' ?? "expected '=' after for";
+ stream >] ->
+ begin parser
+ | [<
+ start=parse_expr;
+ 'Token.Kwd ',' ?? "expected ',' after for";
+ end_=parse_expr;
+ stream >] ->
+ let step =
+ begin parser
+ | [< 'Token.Kwd ','; step=parse_expr >] -> Some step
+ | [< >] -> None
+ end stream
+ in
+ begin parser
+ | [< 'Token.In; body=parse_expr >] ->
+ Ast.For (id, start, end_, step, body)
+ | [< >] ->
+ raise (Stream.Error "expected 'in' after for")
+ end stream
+ | [< >] ->
+ raise (Stream.Error "expected '=' after for")
+ end stream
+
+ | [< >] -> raise (Stream.Error "unknown token when expecting an expression.")
+
+(* binoprhs
+ * ::= ('+' primary)* *)
+and parse_bin_rhs expr_prec lhs stream =
+ match Stream.peek stream with
+ (* If this is a binop, find its precedence. *)
+ | Some (Token.Kwd c) when Hashtbl.mem binop_precedence c ->
+ let token_prec = precedence c in
+
+ (* If this is a binop that binds at least as tightly as the current binop,
+ * consume it, otherwise we are done. *)
+ if token_prec < expr_prec then lhs else begin
+ (* Eat the binop. *)
+ Stream.junk stream;
+
+ (* Parse the primary expression after the binary operator. *)
+ let rhs = parse_primary stream in
+
+ (* Okay, we know this is a binop. *)
+ let rhs =
+ match Stream.peek stream with
+ | Some (Token.Kwd c2) ->
+ (* If BinOp binds less tightly with rhs than the operator after
+ * rhs, let the pending operator take rhs as its lhs. *)
+ let next_prec = precedence c2 in
+ if token_prec < next_prec
+ then parse_bin_rhs (token_prec + 1) rhs stream
+ else rhs
+ | _ -> rhs
+ in
+
+ (* Merge lhs/rhs. *)
+ let lhs = Ast.Binary (c, lhs, rhs) in
+ parse_bin_rhs expr_prec lhs stream
+ end
+ | _ -> lhs
+
+(* expression
+ * ::= primary binoprhs *)
+and parse_expr = parser
+ | [< lhs=parse_primary; stream >] -> parse_bin_rhs 0 lhs stream
+
+(* prototype
+ * ::= id '(' id* ')' *)
+let parse_prototype =
+ let rec parse_args accumulator = parser
+ | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
+ | [< >] -> accumulator
+ in
+
+ parser
+ | [< 'Token.Ident id;
+ 'Token.Kwd '(' ?? "expected '(' in prototype";
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+ (* success. *)
+ Ast.Prototype (id, Array.of_list (List.rev args))
+
+ | [< >] ->
+ raise (Stream.Error "expected function name in prototype")
+
+(* definition ::= 'def' prototype expression *)
+let parse_definition = parser
+ | [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
+ Ast.Function (p, e)
+
+(* toplevelexpr ::= expression *)
+let parse_toplevel = parser
+ | [< e=parse_expr >] ->
+ (* Make an anonymous proto. *)
+ Ast.Function (Ast.Prototype ("", [||]), e)
+
+(* external ::= 'extern' prototype *)
+let parse_extern = parser
+ | [< 'Token.Extern; e=parse_prototype >] -> e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/token.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,19 @@
+(*===----------------------------------------------------------------------===
+ * Lexer Tokens
+ *===----------------------------------------------------------------------===*)
+
+(* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of
+ * these others for known things. *)
+type token =
+ (* commands *)
+ | Def | Extern
+
+ (* primary *)
+ | Ident of string | Number of float
+
+ (* unknown *)
+ | Kwd of char
+
+ (* control *)
+ | If | Then | Else
+ | For | In
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toplevel.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,49 @@
+(*===----------------------------------------------------------------------===
+ * Top-Level parsing and JIT Driver
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+open Llvm_executionengine
+
+(* top ::= definition | external | expression | ';' *)
+let rec main_loop the_fpm the_execution_engine stream =
+ match Stream.peek stream with
+ | None -> ()
+
+ (* ignore top-level semicolons. *)
+ | Some (Token.Kwd ';') ->
+ Stream.junk stream;
+ main_loop the_fpm the_execution_engine stream
+
+ | Some token ->
+ begin
+ try match token with
+ | Token.Def ->
+ let e = Parser.parse_definition stream in
+ print_endline "parsed a function definition.";
+ dump_value (Codegen.codegen_func the_fpm e);
+ | Token.Extern ->
+ let e = Parser.parse_extern stream in
+ print_endline "parsed an extern.";
+ dump_value (Codegen.codegen_proto e);
+ | _ ->
+ (* Evaluate a top-level expression into an anonymous function. *)
+ let e = Parser.parse_toplevel stream in
+ print_endline "parsed a top-level expr";
+ let the_function = Codegen.codegen_func the_fpm e in
+ dump_value the_function;
+
+ (* JIT the function, returning a function pointer. *)
+ let result = ExecutionEngine.run_function the_function [||]
+ the_execution_engine in
+
+ print_string "Evaluated to ";
+ print_float (GenericValue.as_float Codegen.double_type result);
+ print_newline ();
+ with Stream.Error s | Codegen.Error s ->
+ (* Skip token for error recovery. *)
+ Stream.junk stream;
+ print_endline s;
+ end;
+ print_string "ready> "; flush stdout;
+ main_loop the_fpm the_execution_engine stream
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter5/toy.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,53 @@
+(*===----------------------------------------------------------------------===
+ * Main driver code.
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+open Llvm_executionengine
+open Llvm_target
+open Llvm_scalar_opts
+
+let main () =
+ ignore (initialize_native_target ());
+
+ (* Install standard binary operators.
+ * 1 is the lowest precedence. *)
+ Hashtbl.add Parser.binop_precedence '<' 10;
+ Hashtbl.add Parser.binop_precedence '+' 20;
+ Hashtbl.add Parser.binop_precedence '-' 20;
+ Hashtbl.add Parser.binop_precedence '*' 40; (* highest. *)
+
+ (* Prime the first token. *)
+ print_string "ready> "; flush stdout;
+ let stream = Lexer.lex (Stream.of_channel stdin) in
+
+ (* Create the JIT. *)
+ let the_execution_engine = ExecutionEngine.create Codegen.the_module in
+ let the_fpm = PassManager.create_function Codegen.the_module in
+
+ (* Set up the optimizer pipeline. Start with registering info about how the
+ * target lays out data structures. *)
+ TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+
+ (* Do simple "peephole" optimizations and bit-twiddling optzn. *)
+ add_instruction_combination the_fpm;
+
+ (* reassociate expressions. *)
+ add_reassociation the_fpm;
+
+ (* Eliminate Common SubExpressions. *)
+ add_gvn the_fpm;
+
+ (* Simplify the control flow graph (deleting unreachable blocks, etc). *)
+ add_cfg_simplification the_fpm;
+
+ ignore (PassManager.initialize the_fpm);
+
+ (* Run the main "interpreter loop" now. *)
+ Toplevel.main_loop the_fpm the_execution_engine stream;
+
+ (* Print out all the generated code. *)
+ dump_module Codegen.the_module
+;;
+
+main ()
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/Makefile Mon Mar 8 13:32:27 2010
@@ -0,0 +1,25 @@
+##===- examples/OCaml-Kaleidoscope/Chapter6/Makefile -------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 6.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch6
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
+ llvm_scalar_opts
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/_tags Mon Mar 8 13:32:27 2010
@@ -0,0 +1,4 @@
+<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
+<*.{byte,native}>: g++, use_llvm, use_llvm_analysis
+<*.{byte,native}>: use_llvm_executionengine, use_llvm_target
+<*.{byte,native}>: use_llvm_scalar_opts, use_bindings
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/ast.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,36 @@
+(*===----------------------------------------------------------------------===
+ * Abstract Syntax Tree (aka Parse Tree)
+ *===----------------------------------------------------------------------===*)
+
+(* expr - Base type for all expression nodes. *)
+type expr =
+ (* variant for numeric literals like "1.0". *)
+ | Number of float
+
+ (* variant for referencing a variable, like "a". *)
+ | Variable of string
+
+ (* variant for a unary operator. *)
+ | Unary of char * expr
+
+ (* variant for a binary operator. *)
+ | Binary of char * expr * expr
+
+ (* variant for function calls. *)
+ | Call of string * expr array
+
+ (* variant for if/then/else. *)
+ | If of expr * expr * expr
+
+ (* variant for for/in. *)
+ | For of string * expr * expr * expr option * expr
+
+(* proto - This type represents the "prototype" for a function, which captures
+ * its name, and its argument names (thus implicitly the number of arguments the
+ * function takes). *)
+type proto =
+ | Prototype of string * string array
+ | BinOpPrototype of string * string array * int
+
+(* func - This type represents a function definition itself. *)
+type func = Function of proto * expr
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/bindings.c Mon Mar 8 13:32:27 2010
@@ -0,0 +1,13 @@
+#include
+
+/* putchard - putchar that takes a double and returns 0. */
+extern double putchard(double X) {
+ putchar((char)X);
+ return 0;
+}
+
+/* printd - printf that takes a double prints it as "%f\n", returning 0. */
+extern double printd(double X) {
+ printf("%f\n", X);
+ return 0;
+}
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/codegen.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,251 @@
+(*===----------------------------------------------------------------------===
+ * Code Generation
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+
+exception Error of string
+
+let context = global_context ()
+let the_module = create_module context "my cool jit"
+let builder = builder context
+let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
+let double_type = double_type context
+
+let rec codegen_expr = function
+ | Ast.Number n -> const_float double_type n
+ | Ast.Variable name ->
+ (try Hashtbl.find named_values name with
+ | Not_found -> raise (Error "unknown variable name"))
+ | Ast.Unary (op, operand) ->
+ let operand = codegen_expr operand in
+ let callee = "unary" ^ (String.make 1 op) in
+ let callee =
+ match lookup_function callee the_module with
+ | Some callee -> callee
+ | None -> raise (Error "unknown unary operator")
+ in
+ build_call callee [|operand|] "unop" builder
+ | Ast.Binary (op, lhs, rhs) ->
+ let lhs_val = codegen_expr lhs in
+ let rhs_val = codegen_expr rhs in
+ begin
+ match op with
+ | '+' -> build_add lhs_val rhs_val "addtmp" builder
+ | '-' -> build_sub lhs_val rhs_val "subtmp" builder
+ | '*' -> build_mul lhs_val rhs_val "multmp" builder
+ | '<' ->
+ (* Convert bool 0/1 to double 0.0 or 1.0 *)
+ let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in
+ build_uitofp i double_type "booltmp" builder
+ | _ ->
+ (* If it wasn't a builtin binary operator, it must be a user defined
+ * one. Emit a call to it. *)
+ let callee = "binary" ^ (String.make 1 op) in
+ let callee =
+ match lookup_function callee the_module with
+ | Some callee -> callee
+ | None -> raise (Error "binary operator not found!")
+ in
+ build_call callee [|lhs_val; rhs_val|] "binop" builder
+ end
+ | Ast.Call (callee, args) ->
+ (* Look up the name in the module table. *)
+ let callee =
+ match lookup_function callee the_module with
+ | Some callee -> callee
+ | None -> raise (Error "unknown function referenced")
+ in
+ let params = params callee in
+
+ (* If argument mismatch error. *)
+ if Array.length params == Array.length args then () else
+ raise (Error "incorrect # arguments passed");
+ let args = Array.map codegen_expr args in
+ build_call callee args "calltmp" builder
+ | Ast.If (cond, then_, else_) ->
+ let cond = codegen_expr cond in
+
+ (* Convert condition to a bool by comparing equal to 0.0 *)
+ let zero = const_float double_type 0.0 in
+ let cond_val = build_fcmp Fcmp.One cond zero "ifcond" builder in
+
+ (* Grab the first block so that we might later add the conditional branch
+ * to it at the end of the function. *)
+ let start_bb = insertion_block builder in
+ let the_function = block_parent start_bb in
+
+ let then_bb = append_block context "then" the_function in
+
+ (* Emit 'then' value. *)
+ position_at_end then_bb builder;
+ let then_val = codegen_expr then_ in
+
+ (* Codegen of 'then' can change the current block, update then_bb for the
+ * phi. We create a new name because one is used for the phi node, and the
+ * other is used for the conditional branch. *)
+ let new_then_bb = insertion_block builder in
+
+ (* Emit 'else' value. *)
+ let else_bb = append_block context "else" the_function in
+ position_at_end else_bb builder;
+ let else_val = codegen_expr else_ in
+
+ (* Codegen of 'else' can change the current block, update else_bb for the
+ * phi. *)
+ let new_else_bb = insertion_block builder in
+
+ (* Emit merge block. *)
+ let merge_bb = append_block context "ifcont" the_function in
+ position_at_end merge_bb builder;
+ let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
+ let phi = build_phi incoming "iftmp" builder in
+
+ (* Return to the start block to add the conditional branch. *)
+ position_at_end start_bb builder;
+ ignore (build_cond_br cond_val then_bb else_bb builder);
+
+ (* Set a unconditional branch at the end of the 'then' block and the
+ * 'else' block to the 'merge' block. *)
+ position_at_end new_then_bb builder; ignore (build_br merge_bb builder);
+ position_at_end new_else_bb builder; ignore (build_br merge_bb builder);
+
+ (* Finally, set the builder to the end of the merge block. *)
+ position_at_end merge_bb builder;
+
+ phi
+ | Ast.For (var_name, start, end_, step, body) ->
+ (* Emit the start code first, without 'variable' in scope. *)
+ let start_val = codegen_expr start in
+
+ (* Make the new basic block for the loop header, inserting after current
+ * block. *)
+ let preheader_bb = insertion_block builder in
+ let the_function = block_parent preheader_bb in
+ let loop_bb = append_block context "loop" the_function in
+
+ (* Insert an explicit fall through from the current block to the
+ * loop_bb. *)
+ ignore (build_br loop_bb builder);
+
+ (* Start insertion in loop_bb. *)
+ position_at_end loop_bb builder;
+
+ (* Start the PHI node with an entry for start. *)
+ let variable = build_phi [(start_val, preheader_bb)] var_name builder in
+
+ (* Within the loop, the variable is defined equal to the PHI node. If it
+ * shadows an existing variable, we have to restore it, so save it
+ * now. *)
+ let old_val =
+ try Some (Hashtbl.find named_values var_name) with Not_found -> None
+ in
+ Hashtbl.add named_values var_name variable;
+
+ (* Emit the body of the loop. This, like any other expr, can change the
+ * current BB. Note that we ignore the value computed by the body, but
+ * don't allow an error *)
+ ignore (codegen_expr body);
+
+ (* Emit the step value. *)
+ let step_val =
+ match step with
+ | Some step -> codegen_expr step
+ (* If not specified, use 1.0. *)
+ | None -> const_float double_type 1.0
+ in
+
+ let next_var = build_add variable step_val "nextvar" builder in
+
+ (* Compute the end condition. *)
+ let end_cond = codegen_expr end_ in
+
+ (* Convert condition to a bool by comparing equal to 0.0. *)
+ let zero = const_float double_type 0.0 in
+ let end_cond = build_fcmp Fcmp.One end_cond zero "loopcond" builder in
+
+ (* Create the "after loop" block and insert it. *)
+ let loop_end_bb = insertion_block builder in
+ let after_bb = append_block context "afterloop" the_function in
+
+ (* Insert the conditional branch into the end of loop_end_bb. *)
+ ignore (build_cond_br end_cond loop_bb after_bb builder);
+
+ (* Any new code will be inserted in after_bb. *)
+ position_at_end after_bb builder;
+
+ (* Add a new entry to the PHI node for the backedge. *)
+ add_incoming (next_var, loop_end_bb) variable;
+
+ (* Restore the unshadowed variable. *)
+ begin match old_val with
+ | Some old_val -> Hashtbl.add named_values var_name old_val
+ | None -> ()
+ end;
+
+ (* for expr always returns 0.0. *)
+ const_null double_type
+
+let codegen_proto = function
+ | Ast.Prototype (name, args) | Ast.BinOpPrototype (name, args, _) ->
+ (* Make the function type: double(double,double) etc. *)
+ let doubles = Array.make (Array.length args) double_type in
+ let ft = function_type double_type doubles in
+ let f =
+ match lookup_function name the_module with
+ | None -> declare_function name ft the_module
+
+ (* If 'f' conflicted, there was already something named 'name'. If it
+ * has a body, don't allow redefinition or reextern. *)
+ | Some f ->
+ (* If 'f' already has a body, reject this. *)
+ if block_begin f <> At_end f then
+ raise (Error "redefinition of function");
+
+ (* If 'f' took a different number of arguments, reject. *)
+ if element_type (type_of f) <> ft then
+ raise (Error "redefinition of function with different # args");
+ f
+ in
+
+ (* Set names for all arguments. *)
+ Array.iteri (fun i a ->
+ let n = args.(i) in
+ set_value_name n a;
+ Hashtbl.add named_values n a;
+ ) (params f);
+ f
+
+let codegen_func the_fpm = function
+ | Ast.Function (proto, body) ->
+ Hashtbl.clear named_values;
+ let the_function = codegen_proto proto in
+
+ (* If this is an operator, install it. *)
+ begin match proto with
+ | Ast.BinOpPrototype (name, args, prec) ->
+ let op = name.[String.length name - 1] in
+ Hashtbl.add Parser.binop_precedence op prec;
+ | _ -> ()
+ end;
+
+ (* Create a new basic block to start insertion into. *)
+ let bb = append_block context "entry" the_function in
+ position_at_end bb builder;
+
+ try
+ let ret_val = codegen_expr body in
+
+ (* Finish off the function. *)
+ let _ = build_ret ret_val builder in
+
+ (* Validate the generated code, checking for consistency. *)
+ Llvm_analysis.assert_valid_function the_function;
+
+ (* Optimize the function. *)
+ let _ = PassManager.run_function the_function the_fpm in
+
+ the_function
+ with e ->
+ delete_function the_function;
+ raise e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/lexer.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,59 @@
+(*===----------------------------------------------------------------------===
+ * Lexer
+ *===----------------------------------------------------------------------===*)
+
+let rec lex = parser
+ (* Skip any whitespace. *)
+ | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream
+
+ (* identifier: [a-zA-Z][a-zA-Z0-9] *)
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+
+ (* number: [0-9.]+ *)
+ | [< ' ('0' .. '9' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+
+ (* Comment until end of line. *)
+ | [< ' ('#'); stream >] ->
+ lex_comment stream
+
+ (* Otherwise, just return the character as its ascii value. *)
+ | [< 'c; stream >] ->
+ [< 'Token.Kwd c; lex stream >]
+
+ (* end of stream. *)
+ | [< >] -> [< >]
+
+and lex_number buffer = parser
+ | [< ' ('0' .. '9' | '.' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+ | [< stream=lex >] ->
+ [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >]
+
+and lex_ident buffer = parser
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+ | [< stream=lex >] ->
+ match Buffer.contents buffer with
+ | "def" -> [< 'Token.Def; stream >]
+ | "extern" -> [< 'Token.Extern; stream >]
+ | "if" -> [< 'Token.If; stream >]
+ | "then" -> [< 'Token.Then; stream >]
+ | "else" -> [< 'Token.Else; stream >]
+ | "for" -> [< 'Token.For; stream >]
+ | "in" -> [< 'Token.In; stream >]
+ | "binary" -> [< 'Token.Binary; stream >]
+ | "unary" -> [< 'Token.Unary; stream >]
+ | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+ | [< ' ('\n'); stream=lex >] -> stream
+ | [< 'c; e=lex_comment >] -> e
+ | [< >] -> [< >]
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/myocamlbuild.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,10 @@
+open Ocamlbuild_plugin;;
+
+ocaml_lib ~extern:true "llvm";;
+ocaml_lib ~extern:true "llvm_analysis";;
+ocaml_lib ~extern:true "llvm_executionengine";;
+ocaml_lib ~extern:true "llvm_target";;
+ocaml_lib ~extern:true "llvm_scalar_opts";;
+
+flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);;
+dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];;
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/parser.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,195 @@
+(*===---------------------------------------------------------------------===
+ * Parser
+ *===---------------------------------------------------------------------===*)
+
+(* binop_precedence - This holds the precedence for each binary operator that is
+ * defined *)
+let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10
+
+(* precedence - Get the precedence of the pending binary operator token. *)
+let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1
+
+(* primary
+ * ::= identifier
+ * ::= numberexpr
+ * ::= parenexpr
+ * ::= ifexpr
+ * ::= forexpr *)
+let rec parse_primary = parser
+ (* numberexpr ::= number *)
+ | [< 'Token.Number n >] -> Ast.Number n
+
+ (* parenexpr ::= '(' expression ')' *)
+ | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e
+
+ (* identifierexpr
+ * ::= identifier
+ * ::= identifier '(' argumentexpr ')' *)
+ | [< 'Token.Ident id; stream >] ->
+ let rec parse_args accumulator = parser
+ | [< e=parse_expr; stream >] ->
+ begin parser
+ | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e
+ | [< >] -> e :: accumulator
+ end stream
+ | [< >] -> accumulator
+ in
+ let rec parse_ident id = parser
+ (* Call. *)
+ | [< 'Token.Kwd '(';
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')'">] ->
+ Ast.Call (id, Array.of_list (List.rev args))
+
+ (* Simple variable ref. *)
+ | [< >] -> Ast.Variable id
+ in
+ parse_ident id stream
+
+ (* ifexpr ::= 'if' expr 'then' expr 'else' expr *)
+ | [< 'Token.If; c=parse_expr;
+ 'Token.Then ?? "expected 'then'"; t=parse_expr;
+ 'Token.Else ?? "expected 'else'"; e=parse_expr >] ->
+ Ast.If (c, t, e)
+
+ (* forexpr
+ ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)
+ | [< 'Token.For;
+ 'Token.Ident id ?? "expected identifier after for";
+ 'Token.Kwd '=' ?? "expected '=' after for";
+ stream >] ->
+ begin parser
+ | [<
+ start=parse_expr;
+ 'Token.Kwd ',' ?? "expected ',' after for";
+ end_=parse_expr;
+ stream >] ->
+ let step =
+ begin parser
+ | [< 'Token.Kwd ','; step=parse_expr >] -> Some step
+ | [< >] -> None
+ end stream
+ in
+ begin parser
+ | [< 'Token.In; body=parse_expr >] ->
+ Ast.For (id, start, end_, step, body)
+ | [< >] ->
+ raise (Stream.Error "expected 'in' after for")
+ end stream
+ | [< >] ->
+ raise (Stream.Error "expected '=' after for")
+ end stream
+
+ | [< >] -> raise (Stream.Error "unknown token when expecting an expression.")
+
+(* unary
+ * ::= primary
+ * ::= '!' unary *)
+and parse_unary = parser
+ (* If this is a unary operator, read it. *)
+ | [< 'Token.Kwd op when op != '(' && op != ')'; operand=parse_expr >] ->
+ Ast.Unary (op, operand)
+
+ (* If the current token is not an operator, it must be a primary expr. *)
+ | [< stream >] -> parse_primary stream
+
+(* binoprhs
+ * ::= ('+' primary)* *)
+and parse_bin_rhs expr_prec lhs stream =
+ match Stream.peek stream with
+ (* If this is a binop, find its precedence. *)
+ | Some (Token.Kwd c) when Hashtbl.mem binop_precedence c ->
+ let token_prec = precedence c in
+
+ (* If this is a binop that binds at least as tightly as the current binop,
+ * consume it, otherwise we are done. *)
+ if token_prec < expr_prec then lhs else begin
+ (* Eat the binop. *)
+ Stream.junk stream;
+
+ (* Parse the unary expression after the binary operator. *)
+ let rhs = parse_unary stream in
+
+ (* Okay, we know this is a binop. *)
+ let rhs =
+ match Stream.peek stream with
+ | Some (Token.Kwd c2) ->
+ (* If BinOp binds less tightly with rhs than the operator after
+ * rhs, let the pending operator take rhs as its lhs. *)
+ let next_prec = precedence c2 in
+ if token_prec < next_prec
+ then parse_bin_rhs (token_prec + 1) rhs stream
+ else rhs
+ | _ -> rhs
+ in
+
+ (* Merge lhs/rhs. *)
+ let lhs = Ast.Binary (c, lhs, rhs) in
+ parse_bin_rhs expr_prec lhs stream
+ end
+ | _ -> lhs
+
+(* expression
+ * ::= primary binoprhs *)
+and parse_expr = parser
+ | [< lhs=parse_unary; stream >] -> parse_bin_rhs 0 lhs stream
+
+(* prototype
+ * ::= id '(' id* ')'
+ * ::= binary LETTER number? (id, id)
+ * ::= unary LETTER number? (id) *)
+let parse_prototype =
+ let rec parse_args accumulator = parser
+ | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
+ | [< >] -> accumulator
+ in
+ let parse_operator = parser
+ | [< 'Token.Unary >] -> "unary", 1
+ | [< 'Token.Binary >] -> "binary", 2
+ in
+ let parse_binary_precedence = parser
+ | [< 'Token.Number n >] -> int_of_float n
+ | [< >] -> 30
+ in
+ parser
+ | [< 'Token.Ident id;
+ 'Token.Kwd '(' ?? "expected '(' in prototype";
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+ (* success. *)
+ Ast.Prototype (id, Array.of_list (List.rev args))
+ | [< (prefix, kind)=parse_operator;
+ 'Token.Kwd op ?? "expected an operator";
+ (* Read the precedence if present. *)
+ binary_precedence=parse_binary_precedence;
+ 'Token.Kwd '(' ?? "expected '(' in prototype";
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+ let name = prefix ^ (String.make 1 op) in
+ let args = Array.of_list (List.rev args) in
+
+ (* Verify right number of arguments for operator. *)
+ if Array.length args != kind
+ then raise (Stream.Error "invalid number of operands for operator")
+ else
+ if kind == 1 then
+ Ast.Prototype (name, args)
+ else
+ Ast.BinOpPrototype (name, args, binary_precedence)
+ | [< >] ->
+ raise (Stream.Error "expected function name in prototype")
+
+(* definition ::= 'def' prototype expression *)
+let parse_definition = parser
+ | [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
+ Ast.Function (p, e)
+
+(* toplevelexpr ::= expression *)
+let parse_toplevel = parser
+ | [< e=parse_expr >] ->
+ (* Make an anonymous proto. *)
+ Ast.Function (Ast.Prototype ("", [||]), e)
+
+(* external ::= 'extern' prototype *)
+let parse_extern = parser
+ | [< 'Token.Extern; e=parse_prototype >] -> e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/token.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,22 @@
+(*===----------------------------------------------------------------------===
+ * Lexer Tokens
+ *===----------------------------------------------------------------------===*)
+
+(* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of
+ * these others for known things. *)
+type token =
+ (* commands *)
+ | Def | Extern
+
+ (* primary *)
+ | Ident of string | Number of float
+
+ (* unknown *)
+ | Kwd of char
+
+ (* control *)
+ | If | Then | Else
+ | For | In
+
+ (* operators *)
+ | Binary | Unary
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toplevel.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,49 @@
+(*===----------------------------------------------------------------------===
+ * Top-Level parsing and JIT Driver
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+open Llvm_executionengine
+
+(* top ::= definition | external | expression | ';' *)
+let rec main_loop the_fpm the_execution_engine stream =
+ match Stream.peek stream with
+ | None -> ()
+
+ (* ignore top-level semicolons. *)
+ | Some (Token.Kwd ';') ->
+ Stream.junk stream;
+ main_loop the_fpm the_execution_engine stream
+
+ | Some token ->
+ begin
+ try match token with
+ | Token.Def ->
+ let e = Parser.parse_definition stream in
+ print_endline "parsed a function definition.";
+ dump_value (Codegen.codegen_func the_fpm e);
+ | Token.Extern ->
+ let e = Parser.parse_extern stream in
+ print_endline "parsed an extern.";
+ dump_value (Codegen.codegen_proto e);
+ | _ ->
+ (* Evaluate a top-level expression into an anonymous function. *)
+ let e = Parser.parse_toplevel stream in
+ print_endline "parsed a top-level expr";
+ let the_function = Codegen.codegen_func the_fpm e in
+ dump_value the_function;
+
+ (* JIT the function, returning a function pointer. *)
+ let result = ExecutionEngine.run_function the_function [||]
+ the_execution_engine in
+
+ print_string "Evaluated to ";
+ print_float (GenericValue.as_float Codegen.double_type result);
+ print_newline ();
+ with Stream.Error s | Codegen.Error s ->
+ (* Skip token for error recovery. *)
+ Stream.junk stream;
+ print_endline s;
+ end;
+ print_string "ready> "; flush stdout;
+ main_loop the_fpm the_execution_engine stream
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter6/toy.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,53 @@
+(*===----------------------------------------------------------------------===
+ * Main driver code.
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+open Llvm_executionengine
+open Llvm_target
+open Llvm_scalar_opts
+
+let main () =
+ ignore (initialize_native_target ());
+
+ (* Install standard binary operators.
+ * 1 is the lowest precedence. *)
+ Hashtbl.add Parser.binop_precedence '<' 10;
+ Hashtbl.add Parser.binop_precedence '+' 20;
+ Hashtbl.add Parser.binop_precedence '-' 20;
+ Hashtbl.add Parser.binop_precedence '*' 40; (* highest. *)
+
+ (* Prime the first token. *)
+ print_string "ready> "; flush stdout;
+ let stream = Lexer.lex (Stream.of_channel stdin) in
+
+ (* Create the JIT. *)
+ let the_execution_engine = ExecutionEngine.create Codegen.the_module in
+ let the_fpm = PassManager.create_function Codegen.the_module in
+
+ (* Set up the optimizer pipeline. Start with registering info about how the
+ * target lays out data structures. *)
+ TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+
+ (* Do simple "peephole" optimizations and bit-twiddling optzn. *)
+ add_instruction_combination the_fpm;
+
+ (* reassociate expressions. *)
+ add_reassociation the_fpm;
+
+ (* Eliminate Common SubExpressions. *)
+ add_gvn the_fpm;
+
+ (* Simplify the control flow graph (deleting unreachable blocks, etc). *)
+ add_cfg_simplification the_fpm;
+
+ ignore (PassManager.initialize the_fpm);
+
+ (* Run the main "interpreter loop" now. *)
+ Toplevel.main_loop the_fpm the_execution_engine stream;
+
+ (* Print out all the generated code. *)
+ dump_module Codegen.the_module
+;;
+
+main ()
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/Makefile Mon Mar 8 13:32:27 2010
@@ -0,0 +1,25 @@
+##===- examples/OCaml-Kaleidoscope/Chapter7/Makefile -------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 7.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../../..
+TOOLNAME := OCaml-Kaleidoscope-Ch7
+EXAMPLE_TOOL := 1
+UsedComponents := core
+UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
+ llvm_scalar_opts
+
+OCAMLCFLAGS += -pp camlp4of
+
+ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
+
+include $(LEVEL)/bindings/ocaml/Makefile.ocaml
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/_tags Mon Mar 8 13:32:27 2010
@@ -0,0 +1,4 @@
+<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
+<*.{byte,native}>: g++, use_llvm, use_llvm_analysis
+<*.{byte,native}>: use_llvm_executionengine, use_llvm_target
+<*.{byte,native}>: use_llvm_scalar_opts, use_bindings
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/ast.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,39 @@
+(*===----------------------------------------------------------------------===
+ * Abstract Syntax Tree (aka Parse Tree)
+ *===----------------------------------------------------------------------===*)
+
+(* expr - Base type for all expression nodes. *)
+type expr =
+ (* variant for numeric literals like "1.0". *)
+ | Number of float
+
+ (* variant for referencing a variable, like "a". *)
+ | Variable of string
+
+ (* variant for a unary operator. *)
+ | Unary of char * expr
+
+ (* variant for a binary operator. *)
+ | Binary of char * expr * expr
+
+ (* variant for function calls. *)
+ | Call of string * expr array
+
+ (* variant for if/then/else. *)
+ | If of expr * expr * expr
+
+ (* variant for for/in. *)
+ | For of string * expr * expr * expr option * expr
+
+ (* variant for var/in. *)
+ | Var of (string * expr option) array * expr
+
+(* proto - This type represents the "prototype" for a function, which captures
+ * its name, and its argument names (thus implicitly the number of arguments the
+ * function takes). *)
+type proto =
+ | Prototype of string * string array
+ | BinOpPrototype of string * string array * int
+
+(* func - This type represents a function definition itself. *)
+type func = Function of proto * expr
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/bindings.c Mon Mar 8 13:32:27 2010
@@ -0,0 +1,13 @@
+#include
+
+/* putchard - putchar that takes a double and returns 0. */
+extern double putchard(double X) {
+ putchar((char)X);
+ return 0;
+}
+
+/* printd - printf that takes a double prints it as "%f\n", returning 0. */
+extern double printd(double X) {
+ printf("%f\n", X);
+ return 0;
+}
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/codegen.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,370 @@
+(*===----------------------------------------------------------------------===
+ * Code Generation
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+
+exception Error of string
+
+let context = global_context ()
+let the_module = create_module context "my cool jit"
+let builder = builder context
+let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
+let double_type = double_type context
+
+(* Create an alloca instruction in the entry block of the function. This
+ * is used for mutable variables etc. *)
+let create_entry_block_alloca the_function var_name =
+ let builder = builder_at context (instr_begin (entry_block the_function)) in
+ build_alloca double_type var_name builder
+
+let rec codegen_expr = function
+ | Ast.Number n -> const_float double_type n
+ | Ast.Variable name ->
+ let v = try Hashtbl.find named_values name with
+ | Not_found -> raise (Error "unknown variable name")
+ in
+ (* Load the value. *)
+ build_load v name builder
+ | Ast.Unary (op, operand) ->
+ let operand = codegen_expr operand in
+ let callee = "unary" ^ (String.make 1 op) in
+ let callee =
+ match lookup_function callee the_module with
+ | Some callee -> callee
+ | None -> raise (Error "unknown unary operator")
+ in
+ build_call callee [|operand|] "unop" builder
+ | Ast.Binary (op, lhs, rhs) ->
+ begin match op with
+ | '=' ->
+ (* Special case '=' because we don't want to emit the LHS as an
+ * expression. *)
+ let name =
+ match lhs with
+ | Ast.Variable name -> name
+ | _ -> raise (Error "destination of '=' must be a variable")
+ in
+
+ (* Codegen the rhs. *)
+ let val_ = codegen_expr rhs in
+
+ (* Lookup the name. *)
+ let variable = try Hashtbl.find named_values name with
+ | Not_found -> raise (Error "unknown variable name")
+ in
+ ignore(build_store val_ variable builder);
+ val_
+ | _ ->
+ let lhs_val = codegen_expr lhs in
+ let rhs_val = codegen_expr rhs in
+ begin
+ match op with
+ | '+' -> build_add lhs_val rhs_val "addtmp" builder
+ | '-' -> build_sub lhs_val rhs_val "subtmp" builder
+ | '*' -> build_mul lhs_val rhs_val "multmp" builder
+ | '<' ->
+ (* Convert bool 0/1 to double 0.0 or 1.0 *)
+ let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in
+ build_uitofp i double_type "booltmp" builder
+ | _ ->
+ (* If it wasn't a builtin binary operator, it must be a user defined
+ * one. Emit a call to it. *)
+ let callee = "binary" ^ (String.make 1 op) in
+ let callee =
+ match lookup_function callee the_module with
+ | Some callee -> callee
+ | None -> raise (Error "binary operator not found!")
+ in
+ build_call callee [|lhs_val; rhs_val|] "binop" builder
+ end
+ end
+ | Ast.Call (callee, args) ->
+ (* Look up the name in the module table. *)
+ let callee =
+ match lookup_function callee the_module with
+ | Some callee -> callee
+ | None -> raise (Error "unknown function referenced")
+ in
+ let params = params callee in
+
+ (* If argument mismatch error. *)
+ if Array.length params == Array.length args then () else
+ raise (Error "incorrect # arguments passed");
+ let args = Array.map codegen_expr args in
+ build_call callee args "calltmp" builder
+ | Ast.If (cond, then_, else_) ->
+ let cond = codegen_expr cond in
+
+ (* Convert condition to a bool by comparing equal to 0.0 *)
+ let zero = const_float double_type 0.0 in
+ let cond_val = build_fcmp Fcmp.One cond zero "ifcond" builder in
+
+ (* Grab the first block so that we might later add the conditional branch
+ * to it at the end of the function. *)
+ let start_bb = insertion_block builder in
+ let the_function = block_parent start_bb in
+
+ let then_bb = append_block context "then" the_function in
+
+ (* Emit 'then' value. *)
+ position_at_end then_bb builder;
+ let then_val = codegen_expr then_ in
+
+ (* Codegen of 'then' can change the current block, update then_bb for the
+ * phi. We create a new name because one is used for the phi node, and the
+ * other is used for the conditional branch. *)
+ let new_then_bb = insertion_block builder in
+
+ (* Emit 'else' value. *)
+ let else_bb = append_block context "else" the_function in
+ position_at_end else_bb builder;
+ let else_val = codegen_expr else_ in
+
+ (* Codegen of 'else' can change the current block, update else_bb for the
+ * phi. *)
+ let new_else_bb = insertion_block builder in
+
+ (* Emit merge block. *)
+ let merge_bb = append_block context "ifcont" the_function in
+ position_at_end merge_bb builder;
+ let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
+ let phi = build_phi incoming "iftmp" builder in
+
+ (* Return to the start block to add the conditional branch. *)
+ position_at_end start_bb builder;
+ ignore (build_cond_br cond_val then_bb else_bb builder);
+
+ (* Set a unconditional branch at the end of the 'then' block and the
+ * 'else' block to the 'merge' block. *)
+ position_at_end new_then_bb builder; ignore (build_br merge_bb builder);
+ position_at_end new_else_bb builder; ignore (build_br merge_bb builder);
+
+ (* Finally, set the builder to the end of the merge block. *)
+ position_at_end merge_bb builder;
+
+ phi
+ | Ast.For (var_name, start, end_, step, body) ->
+ (* Output this as:
+ * var = alloca double
+ * ...
+ * start = startexpr
+ * store start -> var
+ * goto loop
+ * loop:
+ * ...
+ * bodyexpr
+ * ...
+ * loopend:
+ * step = stepexpr
+ * endcond = endexpr
+ *
+ * curvar = load var
+ * nextvar = curvar + step
+ * store nextvar -> var
+ * br endcond, loop, endloop
+ * outloop: *)
+
+ let the_function = block_parent (insertion_block builder) in
+
+ (* Create an alloca for the variable in the entry block. *)
+ let alloca = create_entry_block_alloca the_function var_name in
+
+ (* Emit the start code first, without 'variable' in scope. *)
+ let start_val = codegen_expr start in
+
+ (* Store the value into the alloca. *)
+ ignore(build_store start_val alloca builder);
+
+ (* Make the new basic block for the loop header, inserting after current
+ * block. *)
+ let loop_bb = append_block context "loop" the_function in
+
+ (* Insert an explicit fall through from the current block to the
+ * loop_bb. *)
+ ignore (build_br loop_bb builder);
+
+ (* Start insertion in loop_bb. *)
+ position_at_end loop_bb builder;
+
+ (* Within the loop, the variable is defined equal to the PHI node. If it
+ * shadows an existing variable, we have to restore it, so save it
+ * now. *)
+ let old_val =
+ try Some (Hashtbl.find named_values var_name) with Not_found -> None
+ in
+ Hashtbl.add named_values var_name alloca;
+
+ (* Emit the body of the loop. This, like any other expr, can change the
+ * current BB. Note that we ignore the value computed by the body, but
+ * don't allow an error *)
+ ignore (codegen_expr body);
+
+ (* Emit the step value. *)
+ let step_val =
+ match step with
+ | Some step -> codegen_expr step
+ (* If not specified, use 1.0. *)
+ | None -> const_float double_type 1.0
+ in
+
+ (* Compute the end condition. *)
+ let end_cond = codegen_expr end_ in
+
+ (* Reload, increment, and restore the alloca. This handles the case where
+ * the body of the loop mutates the variable. *)
+ let cur_var = build_load alloca var_name builder in
+ let next_var = build_add cur_var step_val "nextvar" builder in
+ ignore(build_store next_var alloca builder);
+
+ (* Convert condition to a bool by comparing equal to 0.0. *)
+ let zero = const_float double_type 0.0 in
+ let end_cond = build_fcmp Fcmp.One end_cond zero "loopcond" builder in
+
+ (* Create the "after loop" block and insert it. *)
+ let after_bb = append_block context "afterloop" the_function in
+
+ (* Insert the conditional branch into the end of loop_end_bb. *)
+ ignore (build_cond_br end_cond loop_bb after_bb builder);
+
+ (* Any new code will be inserted in after_bb. *)
+ position_at_end after_bb builder;
+
+ (* Restore the unshadowed variable. *)
+ begin match old_val with
+ | Some old_val -> Hashtbl.add named_values var_name old_val
+ | None -> ()
+ end;
+
+ (* for expr always returns 0.0. *)
+ const_null double_type
+ | Ast.Var (var_names, body) ->
+ let old_bindings = ref [] in
+
+ let the_function = block_parent (insertion_block builder) in
+
+ (* Register all variables and emit their initializer. *)
+ Array.iter (fun (var_name, init) ->
+ (* Emit the initializer before adding the variable to scope, this
+ * prevents the initializer from referencing the variable itself, and
+ * permits stuff like this:
+ * var a = 1 in
+ * var a = a in ... # refers to outer 'a'. *)
+ let init_val =
+ match init with
+ | Some init -> codegen_expr init
+ (* If not specified, use 0.0. *)
+ | None -> const_float double_type 0.0
+ in
+
+ let alloca = create_entry_block_alloca the_function var_name in
+ ignore(build_store init_val alloca builder);
+
+ (* Remember the old variable binding so that we can restore the binding
+ * when we unrecurse. *)
+ begin
+ try
+ let old_value = Hashtbl.find named_values var_name in
+ old_bindings := (var_name, old_value) :: !old_bindings;
+ with Not_found -> ()
+ end;
+
+ (* Remember this binding. *)
+ Hashtbl.add named_values var_name alloca;
+ ) var_names;
+
+ (* Codegen the body, now that all vars are in scope. *)
+ let body_val = codegen_expr body in
+
+ (* Pop all our variables from scope. *)
+ List.iter (fun (var_name, old_value) ->
+ Hashtbl.add named_values var_name old_value
+ ) !old_bindings;
+
+ (* Return the body computation. *)
+ body_val
+
+let codegen_proto = function
+ | Ast.Prototype (name, args) | Ast.BinOpPrototype (name, args, _) ->
+ (* Make the function type: double(double,double) etc. *)
+ let doubles = Array.make (Array.length args) double_type in
+ let ft = function_type double_type doubles in
+ let f =
+ match lookup_function name the_module with
+ | None -> declare_function name ft the_module
+
+ (* If 'f' conflicted, there was already something named 'name'. If it
+ * has a body, don't allow redefinition or reextern. *)
+ | Some f ->
+ (* If 'f' already has a body, reject this. *)
+ if block_begin f <> At_end f then
+ raise (Error "redefinition of function");
+
+ (* If 'f' took a different number of arguments, reject. *)
+ if element_type (type_of f) <> ft then
+ raise (Error "redefinition of function with different # args");
+ f
+ in
+
+ (* Set names for all arguments. *)
+ Array.iteri (fun i a ->
+ let n = args.(i) in
+ set_value_name n a;
+ Hashtbl.add named_values n a;
+ ) (params f);
+ f
+
+(* Create an alloca for each argument and register the argument in the symbol
+ * table so that references to it will succeed. *)
+let create_argument_allocas the_function proto =
+ let args = match proto with
+ | Ast.Prototype (_, args) | Ast.BinOpPrototype (_, args, _) -> args
+ in
+ Array.iteri (fun i ai ->
+ let var_name = args.(i) in
+ (* Create an alloca for this variable. *)
+ let alloca = create_entry_block_alloca the_function var_name in
+
+ (* Store the initial value into the alloca. *)
+ ignore(build_store ai alloca builder);
+
+ (* Add arguments to variable symbol table. *)
+ Hashtbl.add named_values var_name alloca;
+ ) (params the_function)
+
+let codegen_func the_fpm = function
+ | Ast.Function (proto, body) ->
+ Hashtbl.clear named_values;
+ let the_function = codegen_proto proto in
+
+ (* If this is an operator, install it. *)
+ begin match proto with
+ | Ast.BinOpPrototype (name, args, prec) ->
+ let op = name.[String.length name - 1] in
+ Hashtbl.add Parser.binop_precedence op prec;
+ | _ -> ()
+ end;
+
+ (* Create a new basic block to start insertion into. *)
+ let bb = append_block context "entry" the_function in
+ position_at_end bb builder;
+
+ try
+ (* Add all arguments to the symbol table and create their allocas. *)
+ create_argument_allocas the_function proto;
+
+ let ret_val = codegen_expr body in
+
+ (* Finish off the function. *)
+ let _ = build_ret ret_val builder in
+
+ (* Validate the generated code, checking for consistency. *)
+ Llvm_analysis.assert_valid_function the_function;
+
+ (* Optimize the function. *)
+ let _ = PassManager.run_function the_function the_fpm in
+
+ the_function
+ with e ->
+ delete_function the_function;
+ raise e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/lexer.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,60 @@
+(*===----------------------------------------------------------------------===
+ * Lexer
+ *===----------------------------------------------------------------------===*)
+
+let rec lex = parser
+ (* Skip any whitespace. *)
+ | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream
+
+ (* identifier: [a-zA-Z][a-zA-Z0-9] *)
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+
+ (* number: [0-9.]+ *)
+ | [< ' ('0' .. '9' as c); stream >] ->
+ let buffer = Buffer.create 1 in
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+
+ (* Comment until end of line. *)
+ | [< ' ('#'); stream >] ->
+ lex_comment stream
+
+ (* Otherwise, just return the character as its ascii value. *)
+ | [< 'c; stream >] ->
+ [< 'Token.Kwd c; lex stream >]
+
+ (* end of stream. *)
+ | [< >] -> [< >]
+
+and lex_number buffer = parser
+ | [< ' ('0' .. '9' | '.' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_number buffer stream
+ | [< stream=lex >] ->
+ [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >]
+
+and lex_ident buffer = parser
+ | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] ->
+ Buffer.add_char buffer c;
+ lex_ident buffer stream
+ | [< stream=lex >] ->
+ match Buffer.contents buffer with
+ | "def" -> [< 'Token.Def; stream >]
+ | "extern" -> [< 'Token.Extern; stream >]
+ | "if" -> [< 'Token.If; stream >]
+ | "then" -> [< 'Token.Then; stream >]
+ | "else" -> [< 'Token.Else; stream >]
+ | "for" -> [< 'Token.For; stream >]
+ | "in" -> [< 'Token.In; stream >]
+ | "binary" -> [< 'Token.Binary; stream >]
+ | "unary" -> [< 'Token.Unary; stream >]
+ | "var" -> [< 'Token.Var; stream >]
+ | id -> [< 'Token.Ident id; stream >]
+
+and lex_comment = parser
+ | [< ' ('\n'); stream=lex >] -> stream
+ | [< 'c; e=lex_comment >] -> e
+ | [< >] -> [< >]
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/myocamlbuild.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,10 @@
+open Ocamlbuild_plugin;;
+
+ocaml_lib ~extern:true "llvm";;
+ocaml_lib ~extern:true "llvm_analysis";;
+ocaml_lib ~extern:true "llvm_executionengine";;
+ocaml_lib ~extern:true "llvm_target";;
+ocaml_lib ~extern:true "llvm_scalar_opts";;
+
+flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);;
+dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];;
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/parser.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,221 @@
+(*===---------------------------------------------------------------------===
+ * Parser
+ *===---------------------------------------------------------------------===*)
+
+(* binop_precedence - This holds the precedence for each binary operator that is
+ * defined *)
+let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10
+
+(* precedence - Get the precedence of the pending binary operator token. *)
+let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1
+
+(* primary
+ * ::= identifier
+ * ::= numberexpr
+ * ::= parenexpr
+ * ::= ifexpr
+ * ::= forexpr
+ * ::= varexpr *)
+let rec parse_primary = parser
+ (* numberexpr ::= number *)
+ | [< 'Token.Number n >] -> Ast.Number n
+
+ (* parenexpr ::= '(' expression ')' *)
+ | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e
+
+ (* identifierexpr
+ * ::= identifier
+ * ::= identifier '(' argumentexpr ')' *)
+ | [< 'Token.Ident id; stream >] ->
+ let rec parse_args accumulator = parser
+ | [< e=parse_expr; stream >] ->
+ begin parser
+ | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e
+ | [< >] -> e :: accumulator
+ end stream
+ | [< >] -> accumulator
+ in
+ let rec parse_ident id = parser
+ (* Call. *)
+ | [< 'Token.Kwd '(';
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')'">] ->
+ Ast.Call (id, Array.of_list (List.rev args))
+
+ (* Simple variable ref. *)
+ | [< >] -> Ast.Variable id
+ in
+ parse_ident id stream
+
+ (* ifexpr ::= 'if' expr 'then' expr 'else' expr *)
+ | [< 'Token.If; c=parse_expr;
+ 'Token.Then ?? "expected 'then'"; t=parse_expr;
+ 'Token.Else ?? "expected 'else'"; e=parse_expr >] ->
+ Ast.If (c, t, e)
+
+ (* forexpr
+ ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)
+ | [< 'Token.For;
+ 'Token.Ident id ?? "expected identifier after for";
+ 'Token.Kwd '=' ?? "expected '=' after for";
+ stream >] ->
+ begin parser
+ | [<
+ start=parse_expr;
+ 'Token.Kwd ',' ?? "expected ',' after for";
+ end_=parse_expr;
+ stream >] ->
+ let step =
+ begin parser
+ | [< 'Token.Kwd ','; step=parse_expr >] -> Some step
+ | [< >] -> None
+ end stream
+ in
+ begin parser
+ | [< 'Token.In; body=parse_expr >] ->
+ Ast.For (id, start, end_, step, body)
+ | [< >] ->
+ raise (Stream.Error "expected 'in' after for")
+ end stream
+ | [< >] ->
+ raise (Stream.Error "expected '=' after for")
+ end stream
+
+ (* varexpr
+ * ::= 'var' identifier ('=' expression?
+ * (',' identifier ('=' expression)?)* 'in' expression *)
+ | [< 'Token.Var;
+ (* At least one variable name is required. *)
+ 'Token.Ident id ?? "expected identifier after var";
+ init=parse_var_init;
+ var_names=parse_var_names [(id, init)];
+ (* At this point, we have to have 'in'. *)
+ 'Token.In ?? "expected 'in' keyword after 'var'";
+ body=parse_expr >] ->
+ Ast.Var (Array.of_list (List.rev var_names), body)
+
+ | [< >] -> raise (Stream.Error "unknown token when expecting an expression.")
+
+(* unary
+ * ::= primary
+ * ::= '!' unary *)
+and parse_unary = parser
+ (* If this is a unary operator, read it. *)
+ | [< 'Token.Kwd op when op != '(' && op != ')'; operand=parse_expr >] ->
+ Ast.Unary (op, operand)
+
+ (* If the current token is not an operator, it must be a primary expr. *)
+ | [< stream >] -> parse_primary stream
+
+(* binoprhs
+ * ::= ('+' primary)* *)
+and parse_bin_rhs expr_prec lhs stream =
+ match Stream.peek stream with
+ (* If this is a binop, find its precedence. *)
+ | Some (Token.Kwd c) when Hashtbl.mem binop_precedence c ->
+ let token_prec = precedence c in
+
+ (* If this is a binop that binds at least as tightly as the current binop,
+ * consume it, otherwise we are done. *)
+ if token_prec < expr_prec then lhs else begin
+ (* Eat the binop. *)
+ Stream.junk stream;
+
+ (* Parse the primary expression after the binary operator. *)
+ let rhs = parse_unary stream in
+
+ (* Okay, we know this is a binop. *)
+ let rhs =
+ match Stream.peek stream with
+ | Some (Token.Kwd c2) ->
+ (* If BinOp binds less tightly with rhs than the operator after
+ * rhs, let the pending operator take rhs as its lhs. *)
+ let next_prec = precedence c2 in
+ if token_prec < next_prec
+ then parse_bin_rhs (token_prec + 1) rhs stream
+ else rhs
+ | _ -> rhs
+ in
+
+ (* Merge lhs/rhs. *)
+ let lhs = Ast.Binary (c, lhs, rhs) in
+ parse_bin_rhs expr_prec lhs stream
+ end
+ | _ -> lhs
+
+and parse_var_init = parser
+ (* read in the optional initializer. *)
+ | [< 'Token.Kwd '='; e=parse_expr >] -> Some e
+ | [< >] -> None
+
+and parse_var_names accumulator = parser
+ | [< 'Token.Kwd ',';
+ 'Token.Ident id ?? "expected identifier list after var";
+ init=parse_var_init;
+ e=parse_var_names ((id, init) :: accumulator) >] -> e
+ | [< >] -> accumulator
+
+(* expression
+ * ::= primary binoprhs *)
+and parse_expr = parser
+ | [< lhs=parse_unary; stream >] -> parse_bin_rhs 0 lhs stream
+
+(* prototype
+ * ::= id '(' id* ')'
+ * ::= binary LETTER number? (id, id)
+ * ::= unary LETTER number? (id) *)
+let parse_prototype =
+ let rec parse_args accumulator = parser
+ | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
+ | [< >] -> accumulator
+ in
+ let parse_operator = parser
+ | [< 'Token.Unary >] -> "unary", 1
+ | [< 'Token.Binary >] -> "binary", 2
+ in
+ let parse_binary_precedence = parser
+ | [< 'Token.Number n >] -> int_of_float n
+ | [< >] -> 30
+ in
+ parser
+ | [< 'Token.Ident id;
+ 'Token.Kwd '(' ?? "expected '(' in prototype";
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+ (* success. *)
+ Ast.Prototype (id, Array.of_list (List.rev args))
+ | [< (prefix, kind)=parse_operator;
+ 'Token.Kwd op ?? "expected an operator";
+ (* Read the precedence if present. *)
+ binary_precedence=parse_binary_precedence;
+ 'Token.Kwd '(' ?? "expected '(' in prototype";
+ args=parse_args [];
+ 'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
+ let name = prefix ^ (String.make 1 op) in
+ let args = Array.of_list (List.rev args) in
+
+ (* Verify right number of arguments for operator. *)
+ if Array.length args != kind
+ then raise (Stream.Error "invalid number of operands for operator")
+ else
+ if kind == 1 then
+ Ast.Prototype (name, args)
+ else
+ Ast.BinOpPrototype (name, args, binary_precedence)
+ | [< >] ->
+ raise (Stream.Error "expected function name in prototype")
+
+(* definition ::= 'def' prototype expression *)
+let parse_definition = parser
+ | [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
+ Ast.Function (p, e)
+
+(* toplevelexpr ::= expression *)
+let parse_toplevel = parser
+ | [< e=parse_expr >] ->
+ (* Make an anonymous proto. *)
+ Ast.Function (Ast.Prototype ("", [||]), e)
+
+(* external ::= 'extern' prototype *)
+let parse_extern = parser
+ | [< 'Token.Extern; e=parse_prototype >] -> e
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/token.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,25 @@
+(*===----------------------------------------------------------------------===
+ * Lexer Tokens
+ *===----------------------------------------------------------------------===*)
+
+(* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of
+ * these others for known things. *)
+type token =
+ (* commands *)
+ | Def | Extern
+
+ (* primary *)
+ | Ident of string | Number of float
+
+ (* unknown *)
+ | Kwd of char
+
+ (* control *)
+ | If | Then | Else
+ | For | In
+
+ (* operators *)
+ | Binary | Unary
+
+ (* var definition *)
+ | Var
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toplevel.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,49 @@
+(*===----------------------------------------------------------------------===
+ * Top-Level parsing and JIT Driver
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+open Llvm_executionengine
+
+(* top ::= definition | external | expression | ';' *)
+let rec main_loop the_fpm the_execution_engine stream =
+ match Stream.peek stream with
+ | None -> ()
+
+ (* ignore top-level semicolons. *)
+ | Some (Token.Kwd ';') ->
+ Stream.junk stream;
+ main_loop the_fpm the_execution_engine stream
+
+ | Some token ->
+ begin
+ try match token with
+ | Token.Def ->
+ let e = Parser.parse_definition stream in
+ print_endline "parsed a function definition.";
+ dump_value (Codegen.codegen_func the_fpm e);
+ | Token.Extern ->
+ let e = Parser.parse_extern stream in
+ print_endline "parsed an extern.";
+ dump_value (Codegen.codegen_proto e);
+ | _ ->
+ (* Evaluate a top-level expression into an anonymous function. *)
+ let e = Parser.parse_toplevel stream in
+ print_endline "parsed a top-level expr";
+ let the_function = Codegen.codegen_func the_fpm e in
+ dump_value the_function;
+
+ (* JIT the function, returning a function pointer. *)
+ let result = ExecutionEngine.run_function the_function [||]
+ the_execution_engine in
+
+ print_string "Evaluated to ";
+ print_float (GenericValue.as_float Codegen.double_type result);
+ print_newline ();
+ with Stream.Error s | Codegen.Error s ->
+ (* Skip token for error recovery. *)
+ Stream.junk stream;
+ print_endline s;
+ end;
+ print_string "ready> "; flush stdout;
+ main_loop the_fpm the_execution_engine stream
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Chapter7/toy.ml Mon Mar 8 13:32:27 2010
@@ -0,0 +1,57 @@
+(*===----------------------------------------------------------------------===
+ * Main driver code.
+ *===----------------------------------------------------------------------===*)
+
+open Llvm
+open Llvm_executionengine
+open Llvm_target
+open Llvm_scalar_opts
+
+let main () =
+ ignore (initialize_native_target ());
+
+ (* Install standard binary operators.
+ * 1 is the lowest precedence. *)
+ Hashtbl.add Parser.binop_precedence '=' 2;
+ Hashtbl.add Parser.binop_precedence '<' 10;
+ Hashtbl.add Parser.binop_precedence '+' 20;
+ Hashtbl.add Parser.binop_precedence '-' 20;
+ Hashtbl.add Parser.binop_precedence '*' 40; (* highest. *)
+
+ (* Prime the first token. *)
+ print_string "ready> "; flush stdout;
+ let stream = Lexer.lex (Stream.of_channel stdin) in
+
+ (* Create the JIT. *)
+ let the_execution_engine = ExecutionEngine.create Codegen.the_module in
+ let the_fpm = PassManager.create_function Codegen.the_module in
+
+ (* Set up the optimizer pipeline. Start with registering info about how the
+ * target lays out data structures. *)
+ TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+
+ (* Promote allocas to registers. *)
+ add_memory_to_register_promotion the_fpm;
+
+ (* Do simple "peephole" optimizations and bit-twiddling optzn. *)
+ add_instruction_combination the_fpm;
+
+ (* reassociate expressions. *)
+ add_reassociation the_fpm;
+
+ (* Eliminate Common SubExpressions. *)
+ add_gvn the_fpm;
+
+ (* Simplify the control flow graph (deleting unreachable blocks, etc). *)
+ add_cfg_simplification the_fpm;
+
+ ignore (PassManager.initialize the_fpm);
+
+ (* Run the main "interpreter loop" now. *)
+ Toplevel.main_loop the_fpm the_execution_engine stream;
+
+ (* Print out all the generated code. *)
+ dump_module Codegen.the_module
+;;
+
+main ()
Added: llvm/trunk/examples/OCaml-Kaleidoscope/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/OCaml-Kaleidoscope/Makefile?rev=97966&view=auto
==============================================================================
--- llvm/trunk/examples/OCaml-Kaleidoscope/Makefile (added)
+++ llvm/trunk/examples/OCaml-Kaleidoscope/Makefile Mon Mar 8 13:32:27 2010
@@ -0,0 +1,15 @@
+##===- examples/OCaml-Kaleidoscope/Makefile ----------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL=../..
+
+include $(LEVEL)/Makefile.config
+
+PARALLEL_DIRS:= Chapter2 Chapter3 Chapter4 Chapter5 Chapter6 Chapter7
+
+include $(LEVEL)/Makefile.common
From rjmccall at apple.com Mon Mar 8 14:02:05 2010
From: rjmccall at apple.com (John McCall)
Date: Mon, 08 Mar 2010 20:02:05 -0000
Subject: [llvm-commits] [llvm] r97972 - in /llvm/trunk: test/lit.cfg
utils/lit/lit/TestRunner.py utils/lit/lit/TestingConfig.py
Message-ID: <20100308200205.8302F2A6C12C@llvm.org>
Author: rjmccall
Date: Mon Mar 8 14:02:05 2010
New Revision: 97972
URL: http://llvm.org/viewvc/llvm-project?rev=97972&view=rev
Log:
Revert r97726 and r97728 at ddunbar's request; we want to solve this
some other way when it comes to be necessary.
Modified:
llvm/trunk/test/lit.cfg
llvm/trunk/utils/lit/lit/TestRunner.py
llvm/trunk/utils/lit/lit/TestingConfig.py
Modified: llvm/trunk/test/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=97972&r1=97971&r2=97972&view=diff
==============================================================================
--- llvm/trunk/test/lit.cfg (original)
+++ llvm/trunk/test/lit.cfg Mon Mar 8 14:02:05 2010
@@ -144,9 +144,6 @@
def llvm_supports_binding(name):
return name in bindings
-config.conditions["TARGET"] = llvm_supports_target
-config.conditions["BINDING"] = llvm_supports_binding
-
# Provide on_clone hook for reading 'dg.exp'.
import os
simpleLibData = re.compile(r"""load_lib llvm.exp
Modified: llvm/trunk/utils/lit/lit/TestRunner.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestRunner.py?rev=97972&r1=97971&r2=97972&view=diff
==============================================================================
--- llvm/trunk/utils/lit/lit/TestRunner.py (original)
+++ llvm/trunk/utils/lit/lit/TestRunner.py Mon Mar 8 14:02:05 2010
@@ -353,8 +353,6 @@
return True
-import re
-
def parseIntegratedTestScript(test):
"""parseIntegratedTestScript - Scan an LLVM/Clang style integrated test
script and extract the lines to 'RUN' as well as 'XFAIL' and 'XTARGET'
@@ -387,21 +385,7 @@
script = []
xfails = []
xtargets = []
- ignoredAny = False
for ln in open(sourcepath):
- conditional = re.search('IF\((.+?)\((.+?)\)\):', ln)
- if conditional:
- ln = ln[conditional.end():]
- condition = conditional.group(1)
- value = conditional.group(2)
-
- # Actually test the condition.
- if condition not in test.config.conditions:
- return (Test.UNRESOLVED, "unknown condition '"+condition+"'")
- if not test.config.conditions[condition](value):
- ignoredAny = True
- continue
-
if 'RUN:' in ln:
# Isolate the command to run.
index = ln.index('RUN:')
@@ -438,8 +422,6 @@
# Verify the script contains a run line.
if not script:
- if ignoredAny:
- return (Test.UNSUPPORTED, "Test has only ignored run lines")
return (Test.UNRESOLVED, "Test has no run line!")
if script[-1][-1] == '\\':
Modified: llvm/trunk/utils/lit/lit/TestingConfig.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestingConfig.py?rev=97972&r1=97971&r2=97972&view=diff
==============================================================================
--- llvm/trunk/utils/lit/lit/TestingConfig.py (original)
+++ llvm/trunk/utils/lit/lit/TestingConfig.py Mon Mar 8 14:02:05 2010
@@ -28,8 +28,7 @@
on_clone = None,
test_exec_root = None,
test_source_root = None,
- excludes = [],
- conditions = {})
+ excludes = [])
if os.path.exists(path):
# FIXME: Improve detection and error reporting of errors in the
@@ -55,7 +54,7 @@
def __init__(self, parent, name, suffixes, test_format,
environment, substitutions, unsupported, on_clone,
- test_exec_root, test_source_root, excludes, conditions):
+ test_exec_root, test_source_root, excludes):
self.parent = parent
self.name = str(name)
self.suffixes = set(suffixes)
@@ -67,7 +66,6 @@
self.test_exec_root = test_exec_root
self.test_source_root = test_source_root
self.excludes = set(excludes)
- self.conditions = dict(conditions)
def clone(self, path):
# FIXME: Chain implementations?
@@ -77,7 +75,7 @@
self.environment, self.substitutions,
self.unsupported, self.on_clone,
self.test_exec_root, self.test_source_root,
- self.excludes, self.conditions)
+ self.excludes)
if cfg.on_clone:
cfg.on_clone(self, cfg, path)
return cfg
From idadesub at users.sourceforge.net Mon Mar 8 14:07:32 2010
From: idadesub at users.sourceforge.net (Erick Tryzelaar)
Date: Mon, 08 Mar 2010 20:07:32 -0000
Subject: [llvm-commits] [llvm] r97973 - /llvm/trunk/examples/Makefile
Message-ID: <20100308200732.7CE582A6C12C@llvm.org>
Author: erickt
Date: Mon Mar 8 14:07:32 2010
New Revision: 97973
URL: http://llvm.org/viewvc/llvm-project?rev=97973&view=rev
Log:
Don't always run the ocaml kaleidoscope tutorials.
Modified:
llvm/trunk/examples/Makefile
Modified: llvm/trunk/examples/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Makefile?rev=97973&r1=97972&r2=97973&view=diff
==============================================================================
--- llvm/trunk/examples/Makefile (original)
+++ llvm/trunk/examples/Makefile Mon Mar 8 14:07:32 2010
@@ -10,8 +10,7 @@
include $(LEVEL)/Makefile.config
-PARALLEL_DIRS:= BrainF Fibonacci HowToUseJIT Kaleidoscope ModuleMaker \
- OCaml-Kaleidoscope
+PARALLEL_DIRS:= BrainF Fibonacci HowToUseJIT Kaleidoscope ModuleMaker
ifeq ($(HAVE_PTHREAD),1)
PARALLEL_DIRS += ParallelJIT
@@ -26,4 +25,8 @@
endif
endif
+ifeq ($(filter $(BINDINGS_TO_BUILD),ocaml),ocaml)
+ PARALLEL_DIRS += OCaml-Kaleidoscope
+endif
+
include $(LEVEL)/Makefile.common
From alenhar2 at llvm.org Mon Mar 8 14:45:53 2010
From: alenhar2 at llvm.org (alenhar2 at llvm.org)
Date: Mon, 08 Mar 2010 20:45:53 -0000
Subject: [llvm-commits] [llvm] r97974 - in /llvm/trunk/include/llvm/ADT:
DenseMap.h DenseSet.h
Message-ID: <20100308204553.1B5982A6C12C@llvm.org>
Author: alenhar2
Date: Mon Mar 8 14:45:52 2010
New Revision: 97974
URL: http://llvm.org/viewvc/llvm-project?rev=97974&view=rev
Log:
Iterator traits and swap. closes PR6548 and PR6549
Modified:
llvm/trunk/include/llvm/ADT/DenseMap.h
llvm/trunk/include/llvm/ADT/DenseSet.h
Modified: llvm/trunk/include/llvm/ADT/DenseMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=97974&r1=97973&r2=97974&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/DenseMap.h (original)
+++ llvm/trunk/include/llvm/ADT/DenseMap.h Mon Mar 8 14:45:52 2010
@@ -192,6 +192,13 @@
return true;
}
+ void swap(DenseMap& RHS) {
+ std::swap(NumBuckets, RHS.NumBuckets);
+ std::swap(Buckets, RHS.Buckets);
+ std::swap(NumEntries, RHS.NumEntries);
+ std::swap(NumTombstones, RHS.NumTombstones);
+ }
+
value_type& FindAndConstruct(const KeyT &Key) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
Modified: llvm/trunk/include/llvm/ADT/DenseSet.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseSet.h?rev=97974&r1=97973&r2=97974&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/DenseSet.h (original)
+++ llvm/trunk/include/llvm/ADT/DenseSet.h Mon Mar 8 14:45:52 2010
@@ -45,6 +45,10 @@
return TheMap.erase(V);
}
+ void swap(DenseSet& RHS) {
+ TheMap.swap(RHS.TheMap);
+ }
+
DenseSet &operator=(const DenseSet &RHS) {
TheMap = RHS.TheMap;
return *this;
@@ -55,6 +59,12 @@
class Iterator {
typename MapTy::iterator I;
public:
+ typedef typename MapTy::iterator::difference_type difference_type;
+ typedef ValueT value_type;
+ typedef value_type *pointer;
+ typedef value_type &reference;
+ typedef std::forward_iterator_tag iterator_category;
+
Iterator(const typename MapTy::iterator &i) : I(i) {}
ValueT& operator*() { return I->first; }
@@ -68,6 +78,12 @@
class ConstIterator {
typename MapTy::const_iterator I;
public:
+ typedef typename MapTy::const_iterator::difference_type difference_type;
+ typedef ValueT value_type;
+ typedef value_type *pointer;
+ typedef value_type &reference;
+ typedef std::forward_iterator_tag iterator_category;
+
ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
const ValueT& operator*() { return I->first; }
From dpatel at apple.com Mon Mar 8 14:52:55 2010
From: dpatel at apple.com (Devang Patel)
Date: Mon, 08 Mar 2010 20:52:55 -0000
Subject: [llvm-commits] [llvm] r97975 - in /llvm/trunk:
include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp
lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h lib/CodeGen/MachineInstr.cpp
lib/Target/PIC16/PIC16DebugInfo.cpp lib/Transforms/Utils/CloneFunction.cpp
Message-ID: <20100308205255.469472A6C12D@llvm.org>
Author: dpatel
Date: Mon Mar 8 14:52:55 2010
New Revision: 97975
URL: http://llvm.org/viewvc/llvm-project?rev=97975&view=rev
Log:
Avoid using DIDescriptor.isNull().
This is a first step towards eliminating checks in Descriptor constructors.
Modified:
llvm/trunk/include/llvm/Analysis/DebugInfo.h
llvm/trunk/lib/Analysis/DebugInfo.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
llvm/trunk/lib/CodeGen/MachineInstr.cpp
llvm/trunk/lib/Target/PIC16/PIC16DebugInfo.cpp
llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=97975&r1=97974&r2=97975&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Mar 8 14:52:55 2010
@@ -68,6 +68,7 @@
explicit DIDescriptor(MDNode *N) : DbgNode(N) {}
bool isNull() const { return DbgNode == 0; }
+ bool Verify() const { return DbgNode != 0; }
MDNode *getNode() const { return DbgNode; }
@@ -246,7 +247,9 @@
bool isArtificial() const {
return (getFlags() & FlagArtificial) != 0;
}
-
+ bool isValid() const {
+ return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
+ }
/// dump - print type.
void dump() const;
};
@@ -360,7 +363,7 @@
/// DIType or as DICompositeType.
StringRef getReturnTypeName() const {
DICompositeType DCT(getFieldAs(8));
- if (!DCT.isNull()) {
+ if (DCT.Verify()) {
DIArray A = DCT.getTypeArray();
DIType T(A.getElement(0).getNode());
return T.getName();
@@ -494,6 +497,7 @@
DILocation getOrigLocation() const { return getFieldAs(3); }
StringRef getFilename() const { return getScope().getFilename(); }
StringRef getDirectory() const { return getScope().getDirectory(); }
+ bool Verify() const;
};
/// DIFactory - This object assists with the construction of the various
Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=97975&r1=97974&r2=97975&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/DebugInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon Mar 8 14:52:55 2010
@@ -132,13 +132,12 @@
/// isBasicType - Return true if the specified tag is legal for
/// DIBasicType.
bool DIDescriptor::isBasicType() const {
- assert(!isNull() && "Invalid descriptor!");
- return getTag() == dwarf::DW_TAG_base_type;
+ return DbgNode && getTag() == dwarf::DW_TAG_base_type;
}
/// isDerivedType - Return true if the specified tag is legal for DIDerivedType.
bool DIDescriptor::isDerivedType() const {
- assert(!isNull() && "Invalid descriptor!");
+ if (!DbgNode) return false;
switch (getTag()) {
case dwarf::DW_TAG_typedef:
case dwarf::DW_TAG_pointer_type:
@@ -158,7 +157,7 @@
/// isCompositeType - Return true if the specified tag is legal for
/// DICompositeType.
bool DIDescriptor::isCompositeType() const {
- assert(!isNull() && "Invalid descriptor!");
+ if (!DbgNode) return false;
switch (getTag()) {
case dwarf::DW_TAG_array_type:
case dwarf::DW_TAG_structure_type:
@@ -175,7 +174,7 @@
/// isVariable - Return true if the specified tag is legal for DIVariable.
bool DIDescriptor::isVariable() const {
- assert(!isNull() && "Invalid descriptor!");
+ if (!DbgNode) return false;
switch (getTag()) {
case dwarf::DW_TAG_auto_variable:
case dwarf::DW_TAG_arg_variable:
@@ -194,15 +193,13 @@
/// isSubprogram - Return true if the specified tag is legal for
/// DISubprogram.
bool DIDescriptor::isSubprogram() const {
- assert(!isNull() && "Invalid descriptor!");
- return getTag() == dwarf::DW_TAG_subprogram;
+ return DbgNode && getTag() == dwarf::DW_TAG_subprogram;
}
/// isGlobalVariable - Return true if the specified tag is legal for
/// DIGlobalVariable.
bool DIDescriptor::isGlobalVariable() const {
- assert(!isNull() && "Invalid descriptor!");
- return getTag() == dwarf::DW_TAG_variable;
+ return DbgNode && getTag() == dwarf::DW_TAG_variable;
}
/// isGlobal - Return true if the specified tag is legal for DIGlobal.
@@ -213,7 +210,7 @@
/// isScope - Return true if the specified tag is one of the scope
/// related tag.
bool DIDescriptor::isScope() const {
- assert(!isNull() && "Invalid descriptor!");
+ if (!DbgNode) return false;
switch (getTag()) {
case dwarf::DW_TAG_compile_unit:
case dwarf::DW_TAG_lexical_block:
@@ -228,32 +225,27 @@
/// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit.
bool DIDescriptor::isCompileUnit() const {
- assert(!isNull() && "Invalid descriptor!");
- return getTag() == dwarf::DW_TAG_compile_unit;
+ return DbgNode && getTag() == dwarf::DW_TAG_compile_unit;
}
/// isNameSpace - Return true if the specified tag is DW_TAG_namespace.
bool DIDescriptor::isNameSpace() const {
- assert(!isNull() && "Invalid descriptor!");
- return getTag() == dwarf::DW_TAG_namespace;
+ return DbgNode && getTag() == dwarf::DW_TAG_namespace;
}
/// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block.
bool DIDescriptor::isLexicalBlock() const {
- assert(!isNull() && "Invalid descriptor!");
- return getTag() == dwarf::DW_TAG_lexical_block;
+ return DbgNode && getTag() == dwarf::DW_TAG_lexical_block;
}
/// isSubrange - Return true if the specified tag is DW_TAG_subrange_type.
bool DIDescriptor::isSubrange() const {
- assert(!isNull() && "Invalid descriptor!");
- return getTag() == dwarf::DW_TAG_subrange_type;
+ return DbgNode && getTag() == dwarf::DW_TAG_subrange_type;
}
/// isEnumerator - Return true if the specified tag is DW_TAG_enumerator.
bool DIDescriptor::isEnumerator() const {
- assert(!isNull() && "Invalid descriptor!");
- return getTag() == dwarf::DW_TAG_enumerator;
+ return DbgNode && getTag() == dwarf::DW_TAG_enumerator;
}
//===----------------------------------------------------------------------===//
@@ -268,7 +260,8 @@
}
unsigned DIArray::getNumElements() const {
- assert(DbgNode && "Invalid DIArray");
+ if (!DbgNode)
+ return 0;
return DbgNode->getNumOperands();
}
@@ -276,11 +269,9 @@
/// this descriptor. After this completes, the current debug info value
/// is erased.
void DIDerivedType::replaceAllUsesWith(DIDescriptor &D) {
- if (isNull())
+ if (!DbgNode)
return;
- assert(!D.isNull() && "Can not replace with null");
-
// Since we use a TrackingVH for the node, its easy for clients to manufacture
// legitimate situations where they want to replaceAllUsesWith() on something
// which, due to uniquing, has merged with the source. We shield clients from
@@ -295,7 +286,7 @@
/// Verify - Verify that a compile unit is well formed.
bool DICompileUnit::Verify() const {
- if (isNull())
+ if (!DbgNode)
return false;
StringRef N = getFilename();
if (N.empty())
@@ -306,36 +297,36 @@
/// Verify - Verify that a type descriptor is well formed.
bool DIType::Verify() const {
- if (isNull())
+ if (!DbgNode)
return false;
- if (getContext().isNull())
+ if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
- if (!CU.isNull() && !CU.Verify())
+ if (!CU.Verify())
return false;
return true;
}
/// Verify - Verify that a composite type descriptor is well formed.
bool DICompositeType::Verify() const {
- if (isNull())
+ if (!DbgNode)
return false;
- if (getContext().isNull())
+ if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
- if (!CU.isNull() && !CU.Verify())
+ if (!CU.Verify())
return false;
return true;
}
/// Verify - Verify that a subprogram descriptor is well formed.
bool DISubprogram::Verify() const {
- if (isNull())
+ if (!DbgNode)
return false;
- if (getContext().isNull())
+ if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
@@ -343,24 +334,24 @@
return false;
DICompositeType Ty = getType();
- if (!Ty.isNull() && !Ty.Verify())
+ if (!Ty.Verify())
return false;
return true;
}
/// Verify - Verify that a global variable descriptor is well formed.
bool DIGlobalVariable::Verify() const {
- if (isNull())
+ if (!DbgNode)
return false;
if (getDisplayName().empty())
return false;
- if (getContext().isNull())
+ if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
- if (!CU.isNull() && !CU.Verify())
+ if (!CU.Verify())
return false;
DIType Ty = getType();
@@ -375,10 +366,10 @@
/// Verify - Verify that a variable descriptor is well formed.
bool DIVariable::Verify() const {
- if (isNull())
+ if (!DbgNode)
return false;
- if (getContext().isNull())
+ if (!getContext().Verify())
return false;
DIType Ty = getType();
@@ -388,6 +379,14 @@
return true;
}
+/// Verify - Verify that a location descriptor is well formed.
+bool DILocation::Verify() const {
+ if (!DbgNode)
+ return false;
+
+ return DbgNode->getNumOperands() == 4;
+}
+
/// getOriginalTypeSize - If this type is derived from a base type then
/// return base type size.
uint64_t DIDerivedType::getOriginalTypeSize() const {
@@ -398,7 +397,7 @@
DIType BaseType = getTypeDerivedFrom();
// If this type is not derived from any type then take conservative
// approach.
- if (BaseType.isNull())
+ if (!BaseType.isValid())
return getSizeInBits();
if (BaseType.isDerivedType())
return DIDerivedType(BaseType.getNode()).getOriginalTypeSize();
@@ -468,7 +467,7 @@
/// dump - Print type.
void DIType::dump() const {
- if (isNull()) return;
+ if (!DbgNode) return;
StringRef Res = getName();
if (!Res.empty())
@@ -521,8 +520,6 @@
/// dump - Print composite type.
void DICompositeType::dump() const {
DIArray A = getTypeArray();
- if (A.isNull())
- return;
dbgs() << " [" << A.getNumElements() << " elements]";
}
@@ -1155,9 +1152,8 @@
/// processLocation - Process DILocation.
void DebugInfoFinder::processLocation(DILocation Loc) {
- if (Loc.isNull()) return;
- DIScope S(Loc.getScope().getNode());
- if (S.isNull()) return;
+ if (!Loc.Verify()) return;
+ DIDescriptor S(Loc.getScope().getNode());
if (S.isCompileUnit())
addCompileUnit(DICompileUnit(S.getNode()));
else if (S.isSubprogram())
@@ -1177,26 +1173,21 @@
DICompositeType DCT(DT.getNode());
processType(DCT.getTypeDerivedFrom());
DIArray DA = DCT.getTypeArray();
- if (!DA.isNull())
- for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
- DIDescriptor D = DA.getElement(i);
- DIType TyE = DIType(D.getNode());
- if (!TyE.isNull())
- processType(TyE);
- else
- processSubprogram(DISubprogram(D.getNode()));
- }
+ for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
+ DIDescriptor D = DA.getElement(i);
+ if (D.isType())
+ processType(DIType(D.getNode()));
+ else if (D.isSubprogram())
+ processSubprogram(DISubprogram(D.getNode()));
+ }
} else if (DT.isDerivedType()) {
DIDerivedType DDT(DT.getNode());
- if (!DDT.isNull())
- processType(DDT.getTypeDerivedFrom());
+ processType(DDT.getTypeDerivedFrom());
}
}
/// processLexicalBlock
void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) {
- if (LB.isNull())
- return;
DIScope Context = LB.getContext();
if (Context.isLexicalBlock())
return processLexicalBlock(DILexicalBlock(Context.getNode()));
@@ -1206,8 +1197,6 @@
/// processSubprogram - Process DISubprogram.
void DebugInfoFinder::processSubprogram(DISubprogram SP) {
- if (SP.isNull())
- return;
if (!addSubprogram(SP))
return;
addCompileUnit(SP.getCompileUnit());
@@ -1216,20 +1205,23 @@
/// processDeclare - Process DbgDeclareInst.
void DebugInfoFinder::processDeclare(DbgDeclareInst *DDI) {
- DIVariable DV(cast(DDI->getVariable()));
- if (DV.isNull())
+ MDNode *N = dyn_cast(DDI->getVariable());
+ if (!N) return;
+
+ DIDescriptor DV(N);
+ if (!DV.isVariable())
return;
if (!NodesSeen.insert(DV.getNode()))
return;
- addCompileUnit(DV.getCompileUnit());
- processType(DV.getType());
+ addCompileUnit(DIVariable(N).getCompileUnit());
+ processType(DIVariable(N).getType());
}
/// addType - Add type into Tys.
bool DebugInfoFinder::addType(DIType DT) {
- if (DT.isNull())
+ if (!DT.isValid())
return false;
if (!NodesSeen.insert(DT.getNode()))
@@ -1241,7 +1233,7 @@
/// addCompileUnit - Add compile unit into CUs.
bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) {
- if (CU.isNull())
+ if (!CU.Verify())
return false;
if (!NodesSeen.insert(CU.getNode()))
@@ -1253,7 +1245,7 @@
/// addGlobalVariable - Add global variable into GVs.
bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) {
- if (DIG.isNull())
+ if (!DIDescriptor(DIG.getNode()).isGlobalVariable())
return false;
if (!NodesSeen.insert(DIG.getNode()))
@@ -1265,7 +1257,7 @@
// addSubprogram - Add subprgoram into SPs.
bool DebugInfoFinder::addSubprogram(DISubprogram SP) {
- if (SP.isNull())
+ if (!DIDescriptor(SP.getNode()).isSubprogram())
return false;
if (!NodesSeen.insert(SP.getNode()))
@@ -1283,10 +1275,10 @@
return 0;
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
- DIGlobalVariable DIG(cast_or_null(NMD->getOperand(i)));
- if (DIG.isNull())
+ DIDescriptor DIG(cast_or_null(NMD->getOperand(i)));
+ if (!DIG.isGlobalVariable())
continue;
- if (DIG.getGlobal() == V)
+ if (DIGlobalVariable(DIG.getNode()).getGlobal() == V)
return DIG.getNode();
}
return 0;
@@ -1378,12 +1370,6 @@
/// getDISubprogram - Find subprogram that is enclosing this scope.
DISubprogram llvm::getDISubprogram(MDNode *Scope) {
DIDescriptor D(Scope);
- if (D.isNull())
- return DISubprogram();
-
- if (D.isCompileUnit())
- return DISubprogram();
-
if (D.isSubprogram())
return DISubprogram(Scope);
@@ -1395,9 +1381,6 @@
/// getDICompositeType - Find underlying composite type.
DICompositeType llvm::getDICompositeType(DIType T) {
- if (T.isNull())
- return DICompositeType();
-
if (T.isCompositeType())
return DICompositeType(T.getNode());
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=97975&r1=97974&r2=97975&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Mar 8 14:52:55 2010
@@ -335,7 +335,7 @@
// Print source line info.
DIScope Scope = DLT.getScope();
// Omit the directory, because it's likely to be long and uninteresting.
- if (!Scope.isNull())
+ if (Scope.Verify())
CommentOS << Scope.getFilename();
else
CommentOS << "";
@@ -1287,7 +1287,7 @@
if (DL.isUnknown())
return;
DILocation CurDLT = MF->getDILocation(DL);
- if (CurDLT.getScope().isNull())
+ if (!CurDLT.getScope().Verify())
return;
if (!BeforePrintingInsn) {
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=97975&r1=97974&r2=97975&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 8 14:52:55 2010
@@ -413,7 +413,7 @@
/// entry.
void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) {
// If there is no compile unit specified, don't add a line #.
- if (V->getCompileUnit().isNull())
+ if (!V->getCompileUnit().Verify())
return;
unsigned Line = V->getLineNumber();
@@ -427,7 +427,7 @@
/// entry.
void DwarfDebug::addSourceLine(DIE *Die, const DIGlobal *G) {
// If there is no compile unit specified, don't add a line #.
- if (G->getCompileUnit().isNull())
+ if (!G->getCompileUnit().Verify())
return;
unsigned Line = G->getLineNumber();
@@ -441,7 +441,7 @@
/// entry.
void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
// If there is no compile unit specified, don't add a line #.
- if (SP->getCompileUnit().isNull())
+ if (!SP->getCompileUnit().Verify())
return;
// If the line number is 0, don't add it.
if (SP->getLineNumber() == 0)
@@ -460,7 +460,7 @@
void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) {
// If there is no compile unit specified, don't add a line #.
DICompileUnit CU = Ty->getCompileUnit();
- if (CU.isNull())
+ if (!CU.Verify())
return;
unsigned Line = Ty->getLineNumber();
@@ -474,7 +474,7 @@
/// entry.
void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) {
// If there is no compile unit specified, don't add a line #.
- if (NS->getCompileUnit().isNull())
+ if (!NS->getCompileUnit().Verify())
return;
unsigned Line = NS->getLineNumber();
@@ -526,12 +526,8 @@
}
DICompositeType blockStruct = DICompositeType(subType.getNode());
-
DIArray Elements = blockStruct.getTypeArray();
- if (Elements.isNull())
- return Ty;
-
for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
DIDescriptor Element = Elements.getElement(i);
DIDerivedType DT = DIDerivedType(Element.getNode());
@@ -677,7 +673,6 @@
DIDescriptor varField = DIDescriptor();
DIDescriptor forwardingField = DIDescriptor();
-
for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
DIDescriptor Element = Fields.getElement(i);
DIDerivedType DT = DIDerivedType(Element.getNode());
@@ -688,10 +683,6 @@
varField = Element;
}
- assert(!varField.isNull() && "Can't find byref variable in Block struct");
- assert(!forwardingField.isNull()
- && "Can't find forwarding field in Block struct");
-
// Get the offsets for the forwarding field and the variable field.
unsigned int forwardingFieldOffset =
DIDerivedType(forwardingField.getNode()).getOffsetInBits() >> 3;
@@ -781,9 +772,7 @@
/// addToContextOwner - Add Die into the list of its context owner's children.
void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
- if (Context.isNull())
- ModuleCU->addDie(Die);
- else if (Context.isType()) {
+ if (Context.isType()) {
DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode()));
ContextDIE->addChild(Die);
} else if (Context.isNameSpace()) {
@@ -820,7 +809,7 @@
/// addType - Add a new type attribute to the specified entity.
void DwarfDebug::addType(DIE *Entity, DIType Ty) {
- if (Ty.isNull())
+ if (!Ty.isValid())
return;
// Check for pre-existence.
@@ -906,9 +895,9 @@
// Add enumerators to enumeration type.
for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
DIE *ElemDie = NULL;
- DIEnumerator Enum(Elements.getElement(i).getNode());
- if (!Enum.isNull()) {
- ElemDie = constructEnumTypeDIE(&Enum);
+ DIDescriptor Enum(Elements.getElement(i).getNode());
+ if (Enum.isEnumerator()) {
+ ElemDie = constructEnumTypeDIE(DIEnumerator(Enum.getNode()));
Buffer.addChild(ElemDie);
}
}
@@ -939,18 +928,17 @@
DIArray Elements = CTy.getTypeArray();
// A forward struct declared type may not have elements available.
- if (Elements.isNull())
+ unsigned N = Elements.getNumElements();
+ if (N == 0)
break;
// Add elements to structure type.
- for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
+ for (unsigned i = 0; i < N; ++i) {
DIDescriptor Element = Elements.getElement(i);
- if (Element.isNull())
- continue;
DIE *ElemDie = NULL;
- if (Element.getTag() == dwarf::DW_TAG_subprogram)
+ if (Element.isSubprogram())
ElemDie = createSubprogramDIE(DISubprogram(Element.getNode()));
- else if (Element.getTag() == dwarf::DW_TAG_auto_variable) {
+ else if (Element.isVariable()) {
DIVariable DV(Element.getNode());
ElemDie = new DIE(dwarf::DW_TAG_variable);
addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
@@ -959,8 +947,10 @@
addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
addSourceLine(ElemDie, &DV);
- } else
+ } else if (Element.isDerivedType())
ElemDie = createMemberDIE(DIDerivedType(Element.getNode()));
+ else
+ continue;
Buffer.addChild(ElemDie);
}
@@ -973,7 +963,7 @@
dwarf::DW_FORM_data1, RLang);
DICompositeType ContainingType = CTy.getContainingType();
- if (!ContainingType.isNull())
+ if (DIDescriptor(ContainingType.getNode()).isCompositeType())
addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
getOrCreateTypeDIE(DIType(ContainingType.getNode())));
break;
@@ -1051,11 +1041,11 @@
}
/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
-DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) {
+DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator ETy) {
DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
- StringRef Name = ETy->getName();
+ StringRef Name = ETy.getName();
addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
- int64_t Value = ETy->getEnumValue();
+ int64_t Value = ETy.getEnumValue();
addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
return Enumerator;
}
@@ -1199,7 +1189,7 @@
DIArray Args = SPTy.getTypeArray();
unsigned SPTag = SPTy.getTag();
- if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type)
+ if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
addType(SPDie, SPTy);
else
addType(SPDie, DIType(Args.getElement(0).getNode()));
@@ -1282,11 +1272,9 @@
Parent->addScope(NScope);
} else if (DIDescriptor(N).isLexicalBlock()) {
DILexicalBlock DB(N);
- if (!DB.getContext().isNull()) {
- Parent = getUpdatedDbgScope(DB.getContext().getNode(), MI, InlinedAt);
- NScope->setParent(Parent);
- Parent->addScope(NScope);
- }
+ Parent = getUpdatedDbgScope(DB.getContext().getNode(), MI, InlinedAt);
+ NScope->setParent(Parent);
+ Parent->addScope(NScope);
}
NScope->setFirstInsn(MI);
@@ -1318,8 +1306,7 @@
if (Scope.isLexicalBlock()) {
DILexicalBlock DB(N);
DIDescriptor ParentDesc = DB.getContext();
- if (!ParentDesc.isNull())
- Parent = getOrCreateAbstractScope(ParentDesc.getNode());
+ Parent = getOrCreateAbstractScope(ParentDesc.getNode());
}
AScope = new DbgScope(Parent, DIDescriptor(N), NULL);
@@ -1422,10 +1409,9 @@
// Ignore empty scopes.
if (StartID == EndID && StartID != 0)
return NULL;
-
- DIScope DS(Scope->getScopeNode());
- if (DS.isNull())
+ if (!Scope->getScopeNode())
return NULL;
+ DIScope DS(Scope->getScopeNode());
DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
DISubprogram InlinedSP = getDISubprogram(DS.getNode());
@@ -1547,15 +1533,12 @@
return;
DIArray Args = SPTy.getTypeArray();
- if (Args.isNull())
- return;
-
for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
DIType ATy(Args.getElement(i).getNode());
- if (ATy.isNull())
+ if (!ATy.isValid())
continue;
DICompositeType CATy = getDICompositeType(ATy);
- if (!CATy.isNull() && !CATy.getName().empty()) {
+ if (DIDescriptor(CATy.getNode()).Verify() && !CATy.getName().empty()) {
if (DIEEntry *Entry = ModuleCU->getDIEEntry(CATy.getNode()))
ModuleCU->addGlobalType(CATy.getName(), Entry->getEntry());
}
@@ -1564,26 +1547,24 @@
/// constructScopeDIE - Construct a DIE for this scope.
DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
- if (!Scope)
- return NULL;
- DIScope DS(Scope->getScopeNode());
- if (DS.isNull())
- return NULL;
-
- DIE *ScopeDIE = NULL;
- if (Scope->getInlinedAt())
- ScopeDIE = constructInlinedScopeDIE(Scope);
- else if (DS.isSubprogram()) {
- if (Scope->isAbstractScope())
- ScopeDIE = ModuleCU->getDIE(DS.getNode());
- else
- ScopeDIE = updateSubprogramScopeDIE(DS.getNode());
- }
- else {
- ScopeDIE = constructLexicalScopeDIE(Scope);
- if (!ScopeDIE) return NULL;
- }
-
+ if (!Scope || !Scope->getScopeNode())
+ return NULL;
+
+ DIScope DS(Scope->getScopeNode());
+ DIE *ScopeDIE = NULL;
+ if (Scope->getInlinedAt())
+ ScopeDIE = constructInlinedScopeDIE(Scope);
+ else if (DS.isSubprogram()) {
+ if (Scope->isAbstractScope())
+ ScopeDIE = ModuleCU->getDIE(DS.getNode());
+ else
+ ScopeDIE = updateSubprogramScopeDIE(DS.getNode());
+ }
+ else {
+ ScopeDIE = constructLexicalScopeDIE(Scope);
+ if (!ScopeDIE) return NULL;
+ }
+
// Add variables to scope.
SmallVector &Variables = Scope->getVariables();
for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
@@ -2069,7 +2050,6 @@
if (DL.isUnknown()) continue;
DILocation DLT = MF->getDILocation(DL);
DIScope DLTScope = DLT.getScope();
- if (DLTScope.isNull()) continue;
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
@@ -2089,7 +2069,6 @@
if (DL.isUnknown()) continue;
DILocation DLT = MF->getDILocation(DL);
DIScope DLTScope = DLT.getScope();
- if (DLTScope.isNull()) continue;
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
@@ -2168,7 +2147,7 @@
DILocation DLT = MF->getDILocation(FDL);
unsigned LabelID = 0;
DISubprogram SP = getDISubprogram(DLT.getScope().getNode());
- if (!SP.isNull())
+ if (SP.Verify())
LabelID = recordSourceLine(SP.getLineNumber(), 0,
DLT.getScope().getNode());
else
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=97975&r1=97974&r2=97975&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Mon Mar 8 14:52:55 2010
@@ -346,7 +346,7 @@
DICompositeType *CTy);
/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
- DIE *constructEnumTypeDIE(DIEnumerator *ETy);
+ DIE *constructEnumTypeDIE(DIEnumerator ETy);
/// createGlobalVariableDIE - Create new DIE using GV.
DIE *createGlobalVariableDIE(const DIGlobalVariable &GV);
Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=97975&r1=97974&r2=97975&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Mon Mar 8 14:52:55 2010
@@ -1219,7 +1219,7 @@
DIScope Scope = DLT.getScope();
OS << " dbg:";
// Omit the directory, since it's usually long and uninteresting.
- if (!Scope.isNull())
+ if (Scope.Verify())
OS << Scope.getFilename();
else
OS << "";
Modified: llvm/trunk/lib/Target/PIC16/PIC16DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16DebugInfo.cpp?rev=97975&r1=97974&r2=97975&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16DebugInfo.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16DebugInfo.cpp Mon Mar 8 14:52:55 2010
@@ -333,7 +333,7 @@
for (DebugInfoFinder::iterator I = DbgFinder.type_begin(),
E = DbgFinder.type_end(); I != E; ++I) {
DICompositeType CTy(*I);
- if (CTy.isNull())
+ if (!CTy.Verify())
continue;
if (CTy.getTag() == dwarf::DW_TAG_union_type ||
CTy.getTag() == dwarf::DW_TAG_structure_type ) {
Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=97975&r1=97974&r2=97975&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Mon Mar 8 14:52:55 2010
@@ -336,14 +336,14 @@
static MDNode *UpdateInlinedAtInfo(MDNode *InsnMD, MDNode *TheCallMD) {
DILocation ILoc(InsnMD);
- if (ILoc.isNull()) return InsnMD;
+ if (!ILoc.Verify()) return InsnMD;
DILocation CallLoc(TheCallMD);
- if (CallLoc.isNull()) return InsnMD;
+ if (!CallLoc.Verify()) return InsnMD;
DILocation OrigLocation = ILoc.getOrigLocation();
MDNode *NewLoc = TheCallMD;
- if (!OrigLocation.isNull())
+ if (OrigLocation.Verify())
NewLoc = UpdateInlinedAtInfo(OrigLocation.getNode(), TheCallMD);
Value *MDVs[] = {
From dpatel at apple.com Mon Mar 8 14:53:59 2010
From: dpatel at apple.com (Devang Patel)
Date: Mon, 08 Mar 2010 20:53:59 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r97977 -
/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
Message-ID: <20100308205359.6A3012A6C12C@llvm.org>
Author: dpatel
Date: Mon Mar 8 14:53:59 2010
New Revision: 97977
URL: http://llvm.org/viewvc/llvm-project?rev=97977&view=rev
Log:
Avoid using DIDescriptor.isNull().
One character "!" makes all the difference!
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=97977&r1=97976&r2=97977&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Mon Mar 8 14:53:59 2010
@@ -1147,7 +1147,7 @@
MainTy = getOrCreateType(TYPE_MAIN_VARIANT(type));
DIType Ty = createVariantType(type, MainTy);
- if (!Ty.isNull())
+ if (Ty.isValid())
return Ty;
// Work out details of type.
From dpatel at apple.com Mon Mar 8 15:00:27 2010
From: dpatel at apple.com (Devang Patel)
Date: Mon, 08 Mar 2010 21:00:27 -0000
Subject: [llvm-commits] [llvm] r97979 -
/llvm/trunk/include/llvm/Analysis/DebugInfo.h
Message-ID: <20100308210028.0896F2A6C12C@llvm.org>
Author: dpatel
Date: Mon Mar 8 15:00:27 2010
New Revision: 97979
URL: http://llvm.org/viewvc/llvm-project?rev=97979&view=rev
Log:
isNull() is not used any more.
Modified:
llvm/trunk/include/llvm/Analysis/DebugInfo.h
Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=97979&r1=97978&r2=97979&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Mar 8 15:00:27 2010
@@ -67,7 +67,6 @@
explicit DIDescriptor() : DbgNode(0) {}
explicit DIDescriptor(MDNode *N) : DbgNode(N) {}
- bool isNull() const { return DbgNode == 0; }
bool Verify() const { return DbgNode != 0; }
MDNode *getNode() const { return DbgNode; }
From evan.cheng at apple.com Mon Mar 8 15:05:02 2010
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 08 Mar 2010 21:05:02 -0000
Subject: [llvm-commits] [llvm] r97980 - in /llvm/trunk:
docs/CodeGenerator.html docs/LangRef.html test/CodeGen/X86/sibcall.ll
test/CodeGen/X86/tailcall2.ll
Message-ID: <20100308210503.297632A6C12C@llvm.org>
Author: evancheng
Date: Mon Mar 8 15:05:02 2010
New Revision: 97980
URL: http://llvm.org/viewvc/llvm-project?rev=97980&view=rev
Log:
Add documentation on sibling call optimization. Rename tailcall2.ll test to sibcall.ll.
Added:
llvm/trunk/test/CodeGen/X86/sibcall.ll
- copied unchanged from r97973, llvm/trunk/test/CodeGen/X86/tailcall2.ll
Removed:
llvm/trunk/test/CodeGen/X86/tailcall2.ll
Modified:
llvm/trunk/docs/CodeGenerator.html
llvm/trunk/docs/LangRef.html
Modified: llvm/trunk/docs/CodeGenerator.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=97980&r1=97979&r2=97980&view=diff
==============================================================================
--- llvm/trunk/docs/CodeGenerator.html (original)
+++ llvm/trunk/docs/CodeGenerator.html Mon Mar 8 15:05:02 2010
@@ -86,6 +86,7 @@
- Target-specific Implementation Notes
- Tail call optimization
+ - Sibling call optimization
- The X86 backend
- The PowerPC backend
@@ -1734,6 +1735,50 @@
+
+
+
+Sibling call optimization is a restricted form of tail call optimization.
+ Unlike tail call optimization described in the previous section, it can be
+ performed automatically on any tail calls when -tailcallopt option
+ is not specified.
+
+Sibling call optimization is currently performed on x86/x86-64 when the
+ following constraints are met:
+
+
+ - Caller and callee have the same calling convention. It can be either
+ c or fastcc.
+
+
- The call is a tail call - in tail position (ret immediately follows call
+ and ret uses value of call or is void).
+
+ - Caller and callee have matching return type or the callee result is not
+ used.
+
+
- If any of the callee arguments are being passed in stack, they must be
+ available in caller's own incoming argument stack and the frame offsets
+ must be the same.
+
+
+Example:
+
+
+declare i32 @bar(i32, i32)
+
+define i32 @foo(i32 %a, i32 %b, i32 %c) {
+entry:
+ %0 = tail call i32 @bar(i32 %a, i32 %b)
+ ret i32 %0
+}
+
+
+
+
+
+
Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=97980&r1=97979&r2=97980&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Mon Mar 8 15:05:02 2010
@@ -5149,8 +5149,11 @@
a ret instruction. If the "tail" marker is
present, the function call is eligible for tail call optimization,
but might not in fact be
- optimized into a jump. As of this writing, the extra requirements for
- a call to actually be optimized are:
+ optimized into a jump. The code generator may optimize calls marked
+ "tail" with either 1) automatic
+ sibling call optimization when the caller and callee have
+ matching signatures, or 2) forced tail call optimization when the
+ following extra requirements are met:
To provide basic functionality, the LLVM debugger does have to make some assumptions about the source-level language being debugged, though it keeps these to a minimum. The only common features that the LLVM debugger assumes - exist are source files, + exist are source files, and program objects. These abstract objects are used by a debugger to form stack traces, show information about local variables, etc.
@@ -307,8 +308,8 @@ of tags are loosely bound to the tag values of DWARF information entries. However, that does not restrict the use of the information supplied to DWARF targets. To facilitate versioning of debug information, the tag is augmented - with the current debug version (LLVMDebugVersion = 7 << 16 or 0x70000 or - 458752.) + with the current debug version (LLVMDebugVersion = 8 << 16 or 0x80000 or + 524288.)The details of the various descriptors follow.
@@ -346,18 +347,36 @@ that produced it.Compile unit descriptors provide the root context for objects declared in a - specific source file. Global variables and top level functions would be - defined using this context. Compile unit descriptors also provide context - for source line correspondence.
- -Each input file is encoded as a separate compile unit in LLVM debugging - information output. However, many target specific tool chains prefer to - encode only one compile unit in an object file. In this situation, the LLVM - code generator will include debugging information entities in the compile - unit that is marked as main compile unit. The code generator accepts maximum - one main compile unit per module. If a module does not contain any main - compile unit then the code generator will emit multiple compile units in the - output object file.
+ specific compilation unit. File descriptors are defined using this context. + +
+!0 = metadata !{
+ i32, ;; Tag = 41 + LLVMDebugVersion
+ ;; (DW_TAG_file_type)
+ metadata, ;; Source file name
+ metadata, ;; Source file directory (includes trailing slash)
+ metadata ;; Reference to compile unit where defined
+}
+
+These descriptors contain informations for a file. Global variables and top + level functions would be defined using this context.k File descriptors also + provide context for source line correspondence.
+ +Each input file is encoded as a separate file descriptor in LLVM debugging + information output. Each file descriptor would be defined using a + compile unit.
...
;;
-;; Define the compile unit for the source file "/Users/mine/sources/MySource.cpp".
+;; Define the compile unit for the main source file "/Users/mine/sources/MySource.cpp".
;;
-!3 = metadata !{
- i32 458769, ;; Tag
+!2 = metadata !{
+ i32 524305, ;; Tag
i32 0, ;; Unused
i32 4, ;; Language Id
metadata !"MySource.cpp",
@@ -1027,19 +1046,24 @@
i32 0} ;; Runtime version
;;
-;; Define the compile unit for the header file "/Users/mine/sources/MyHeader.h".
+;; Define the file for the file "/Users/mine/sources/MySource.cpp".
;;
!1 = metadata !{
- i32 458769, ;; Tag
- i32 0, ;; Unused
- i32 4, ;; Language Id
- metadata !"MyHeader.h",
+ i32 524329, ;; Tag
+ metadata !"MySource.cpp",
metadata !"/Users/mine/sources",
- metadata !"4.2.1 (Based on Apple Inc. build 5649) (LLVM build 00)",
- i1 false, ;; Main Compile Unit
- i1 false, ;; Optimized compile unit
- metadata !"", ;; Compiler flags
- i32 0} ;; Runtime version
+ metadata !3 ;; Compile unit
+}
+
+;;
+;; Define the file for the file "/Users/mine/sources/Myheader.h"
+;;
+!3 = metadata !{
+ i32 524329, ;; Tag
+ metadata !"Myheader.h"
+ metadata !"/Users/mine/sources",
+ metadata !3 ;; Compile unit
+}
...
@@ -1081,15 +1105,15 @@
;; variable anchor and the global variable itself.
;;
!0 = metadata !{
- i32 458804, ;; Tag
+ i32 524340, ;; Tag
i32 0, ;; Unused
metadata !1, ;; Context
metadata !"MyGlobal", ;; Name
metadata !"MyGlobal", ;; Display Name
metadata !"MyGlobal", ;; Linkage Name
- metadata !1, ;; Compile Unit
+ metadata !3, ;; Compile Unit
i32 1, ;; Line Number
- metadata !2, ;; Type
+ metadata !4, ;; Type
i1 false, ;; Is a local variable
i1 true, ;; Is this a definition
i32* @MyGlobal ;; The global variable
@@ -1099,11 +1123,11 @@
;; Define the basic type of 32 bit signed integer. Note that since int is an
;; intrinsic type the source file is NULL and line 0.
;;
-!2 = metadata !{
- i32 458788, ;; Tag
+!4 = metadata !{
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"int", ;; Name
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@@ -1143,16 +1167,16 @@
;; anchor is 46, which is the same as the tag for subprograms
;; (46 = DW_TAG_subprogram.)
;;
-!0 = metadata !{
- i32 458798, ;; Tag
+!6 = metadata !{
+ i32 524334, ;; Tag
i32 0, ;; Unused
metadata !1, ;; Context
metadata !"main", ;; Name
metadata !"main", ;; Display name
metadata !"main", ;; Linkage name
- metadata !1, ;; Compile unit
+ metadata !1, ;; File
i32 1, ;; Line number
- metadata !2, ;; Type
+ metadata !4, ;; Type
i1 false, ;; Is local
i1 true ;; Is definition
}
@@ -1188,10 +1212,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"bool", ;; Name
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 8, ;; Size in Bits
i64 8, ;; Align in Bits
@@ -1214,10 +1238,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"char", ;; Name
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 8, ;; Size in Bits
i64 8, ;; Align in Bits
@@ -1240,10 +1264,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"unsigned char",
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 8, ;; Size in Bits
i64 8, ;; Align in Bits
@@ -1266,10 +1290,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"short int",
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 16, ;; Size in Bits
i64 16, ;; Align in Bits
@@ -1292,10 +1316,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"short unsigned int",
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 16, ;; Size in Bits
i64 16, ;; Align in Bits
@@ -1318,10 +1342,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"int", ;; Name
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@@ -1343,10 +1367,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"unsigned int",
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@@ -1369,10 +1393,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"long long int",
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 64, ;; Size in Bits
i64 64, ;; Align in Bits
@@ -1395,10 +1419,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"long long unsigned int",
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 64, ;; Size in Bits
i64 64, ;; Align in Bits
@@ -1421,10 +1445,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"float",
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@@ -1447,10 +1471,10 @@
!2 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"double",;; Name
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 64, ;; Size in Bits
i64 64, ;; Align in Bits
@@ -1486,10 +1510,10 @@
;; Define the typedef "IntPtr".
;;
!2 = metadata !{
- i32 458774, ;; Tag
+ i32 524310, ;; Tag
metadata !1, ;; Context
metadata !"IntPtr", ;; Name
- metadata !3, ;; Compile unit
+ metadata !3, ;; File
i32 0, ;; Line number
i64 0, ;; Size in bits
i64 0, ;; Align in bits
@@ -1502,10 +1526,10 @@
;; Define the pointer type.
;;
!4 = metadata !{
- i32 458767, ;; Tag
+ i32 524303, ;; Tag
metadata !1, ;; Context
metadata !"", ;; Name
- metadata !1, ;; Compile unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 64, ;; Size in bits
i64 64, ;; Align in bits
@@ -1517,10 +1541,10 @@
;; Define the const type.
;;
!5 = metadata !{
- i32 458790, ;; Tag
+ i32 524326, ;; Tag
metadata !1, ;; Context
metadata !"", ;; Name
- metadata !1, ;; Compile unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@@ -1532,10 +1556,10 @@
;; Define the int type.
;;
!6 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"int", ;; Name
- metadata !1, ;; Compile unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@@ -1575,10 +1599,10 @@
;; Define basic type for unsigned int.
;;
!5 = metadata !{
- i32 458788, ;; Tag
+ i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"unsigned int",
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@@ -1590,7 +1614,7 @@
;; Define composite type for struct Color.
;;
!2 = metadata !{
- i32 458771, ;; Tag
+ i32 524307, ;; Tag
metadata !1, ;; Context
metadata !"Color", ;; Name
metadata !1, ;; Compile unit
@@ -1608,10 +1632,10 @@
;; Define the Red field.
;;
!4 = metadata !{
- i32 458765, ;; Tag
+ i32 524301, ;; Tag
metadata !1, ;; Context
metadata !"Red", ;; Name
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 2, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@@ -1624,10 +1648,10 @@
;; Define the Green field.
;;
!6 = metadata !{
- i32 458765, ;; Tag
+ i32 524301, ;; Tag
metadata !1, ;; Context
metadata !"Green", ;; Name
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 3, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@@ -1640,10 +1664,10 @@
;; Define the Blue field.
;;
!7 = metadata !{
- i32 458765, ;; Tag
+ i32 524301, ;; Tag
metadata !1, ;; Context
metadata !"Blue", ;; Name
- metadata !1, ;; Compile Unit
+ metadata !1, ;; File
i32 4, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@@ -1688,10 +1712,10 @@
;; Define composite type for enum Trees
;;
!2 = metadata !{
- i32 458756, ;; Tag
+ i32 524292, ;; Tag
metadata !1, ;; Context
metadata !"Trees", ;; Name
- metadata !1, ;; Compile unit
+ metadata !1, ;; File
i32 1, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@@ -1710,17 +1734,17 @@
;;
;; Define Spruce enumerator.
;;
-!4 = metadata !{i32 458792, metadata !"Spruce", i64 100}
+!4 = metadata !{i32 524328, metadata !"Spruce", i64 100}
;;
;; Define Oak enumerator.
;;
-!5 = metadata !{i32 458792, metadata !"Oak", i64 200}
+!5 = metadata !{i32 524328, metadata !"Oak", i64 200}
;;
;; Define Maple enumerator.
;;
-!6 = metadata !{i32 458792, metadata !"Maple", i64 300}
+!6 = metadata !{i32 524328, metadata !"Maple", i64 300}
Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=98020&r1=98019&r2=98020&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Mar 8 18:44:10 2010
@@ -214,7 +214,13 @@
DIScope getContext() const { return getFieldAs(1); }
StringRef getName() const { return getStringField(2); }
- DICompileUnit getCompileUnit() const{ return getFieldAs(3); }
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs(3);
+
+ DIFile F = getFieldAs(3);
+ return F.getCompileUnit();
+ }
unsigned getLineNumber() const { return getUnsignedField(4); }
uint64_t getSizeInBits() const { return getUInt64Field(5); }
uint64_t getAlignInBits() const { return getUInt64Field(6); }
@@ -324,7 +330,14 @@
StringRef getName() const { return getStringField(3); }
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
- DICompileUnit getCompileUnit() const{ return getFieldAs(6); }
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs(6);
+
+ DIFile F = getFieldAs(6);
+ return F.getCompileUnit();
+ }
+
unsigned getLineNumber() const { return getUnsignedField(7); }
DIType getType() const { return getFieldAs(8); }
@@ -346,7 +359,13 @@
StringRef getName() const { return getStringField(3); }
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
- DICompileUnit getCompileUnit() const{ return getFieldAs(6); }
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs(6);
+
+ DIFile F = getFieldAs(6);
+ return F.getCompileUnit();
+ }
unsigned getLineNumber() const { return getUnsignedField(7); }
DICompositeType getType() const { return getFieldAs(8); }
@@ -413,7 +432,13 @@
DIScope getContext() const { return getFieldAs(1); }
StringRef getName() const { return getStringField(2); }
- DICompileUnit getCompileUnit() const{ return getFieldAs(3); }
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs(3);
+
+ DIFile F = getFieldAs(3);
+ return F.getCompileUnit();
+ }
unsigned getLineNumber() const { return getUnsignedField(4); }
DIType getType() const { return getFieldAs(5); }
@@ -461,7 +486,13 @@
StringRef getName() const { return getStringField(2); }
StringRef getDirectory() const { return getContext().getDirectory(); }
StringRef getFilename() const { return getContext().getFilename(); }
- DICompileUnit getCompileUnit() const { return getFieldAs(3);}
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs(3);
+
+ DIFile F = getFieldAs(3);
+ return F.getCompileUnit();
+ }
unsigned getLineNumber() const { return getUnsignedField(4); }
};
@@ -523,14 +554,14 @@
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
- DICompileUnit CompileUnit, unsigned LineNumber,
+ DIFile F, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
unsigned Encoding);
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
- DICompileUnit CompileUnit, unsigned LineNumber,
+ DIFile F, unsigned LineNumber,
Constant *SizeInBits, Constant *AlignInBits,
Constant *OffsetInBits, unsigned Flags,
unsigned Encoding);
@@ -539,7 +570,7 @@
/// pointer, typedef, etc.
DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
@@ -548,17 +579,18 @@
/// CreateDerivedType - Create a derived type like const qualified type,
/// pointer, typedef, etc.
DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DICompileUnit CompileUnit,
- unsigned LineNumber,
- Constant *SizeInBits, Constant *AlignInBits,
- Constant *OffsetInBits, unsigned Flags,
- DIType DerivedFrom);
+ StringRef Name,
+ DIFile F,
+ unsigned LineNumber,
+ Constant *SizeInBits,
+ Constant *AlignInBits,
+ Constant *OffsetInBits, unsigned Flags,
+ DIType DerivedFrom);
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
@@ -573,22 +605,23 @@
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DICompileUnit CompileUnit,
- unsigned LineNumber,
- Constant *SizeInBits,
- Constant *AlignInBits,
- Constant *OffsetInBits, unsigned Flags,
- DIType DerivedFrom,
- DIArray Elements,
- unsigned RunTimeLang = 0);
+ StringRef Name,
+ DIFile F,
+ unsigned LineNumber,
+ Constant *SizeInBits,
+ Constant *AlignInBits,
+ Constant *OffsetInBits,
+ unsigned Flags,
+ DIType DerivedFrom,
+ DIArray Elements,
+ unsigned RunTimeLang = 0);
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram for descriptions of these fields.
DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
- DICompileUnit CompileUnit, unsigned LineNo,
+ DIFile F, unsigned LineNo,
DIType Ty, bool isLocalToUnit,
bool isDefinition,
unsigned VK = 0,
@@ -605,21 +638,21 @@
CreateGlobalVariable(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNo, DIType Ty, bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *GV);
/// CreateVariable - Create a new descriptor for the specified variable.
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit, unsigned LineNo,
+ DIFile F, unsigned LineNo,
DIType Ty);
/// CreateComplexVariable - Create a new descriptor for the specified
/// variable which has a complex address expression for its address.
DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
- DICompileUnit CompileUnit, unsigned LineNo,
+ DIFile F, unsigned LineNo,
DIType Ty,
SmallVector &addr);
@@ -631,7 +664,7 @@
/// CreateNameSpace - This creates new descriptor for a namespace
/// with the specified parent context.
DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
- DICompileUnit CU, unsigned LineNo);
+ DIFile F, unsigned LineNo);
/// CreateLocation - Creates a debug info location.
DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
Modified: llvm/trunk/include/llvm/Support/Dwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Dwarf.h?rev=98020&r1=98019&r2=98020&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Dwarf.h (original)
+++ llvm/trunk/include/llvm/Support/Dwarf.h Mon Mar 8 18:44:10 2010
@@ -22,7 +22,8 @@
// Debug info constants.
enum {
- LLVMDebugVersion = (7 << 16), // Current version of debug information.
+ LLVMDebugVersion = (8 << 16), // Current version of debug information.
+ LLVMDebugVersion7 = (7 << 16), // Constant for version 7.
LLVMDebugVersion6 = (6 << 16), // Constant for version 6.
LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=98020&r1=98019&r2=98020&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/DebugInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon Mar 8 18:44:10 2010
@@ -41,9 +41,9 @@
DIDescriptor DI(N);
- // Check current version. Allow Version6 for now.
+ // Check current version. Allow Version7 for now.
unsigned Version = DI.getVersion();
- if (Version != LLVMDebugVersion && Version != LLVMDebugVersion6)
+ if (Version != LLVMDebugVersion && Version != LLVMDebugVersion7)
return false;
switch (DI.getTag()) {
@@ -698,7 +698,7 @@
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
@@ -708,7 +708,7 @@
GetTagConstant(dwarf::DW_TAG_base_type),
Context.getNode(),
MDString::get(VMContext, Name),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
@@ -723,7 +723,7 @@
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType DIFactory::CreateBasicTypeEx(DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
@@ -733,7 +733,7 @@
GetTagConstant(dwarf::DW_TAG_base_type),
Context.getNode(),
MDString::get(VMContext, Name),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
SizeInBits,
AlignInBits,
@@ -773,7 +773,7 @@
DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
@@ -784,7 +784,7 @@
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
@@ -801,7 +801,7 @@
DIDerivedType DIFactory::CreateDerivedTypeEx(unsigned Tag,
DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
@@ -812,7 +812,7 @@
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
SizeInBits,
AlignInBits,
@@ -828,7 +828,7 @@
DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
@@ -843,7 +843,7 @@
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
@@ -862,7 +862,7 @@
DICompositeType DIFactory::CreateCompositeTypeEx(unsigned Tag,
DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
@@ -876,7 +876,7 @@
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
SizeInBits,
AlignInBits,
@@ -897,7 +897,7 @@
StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNo, DIType Ty,
bool isLocalToUnit,
bool isDefinition,
@@ -912,7 +912,7 @@
MDString::get(VMContext, Name),
MDString::get(VMContext, DisplayName),
MDString::get(VMContext, LinkageName),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
Ty.getNode(),
ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
@@ -957,7 +957,7 @@
DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNo, DIType Ty,bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *Val) {
Value *Elts[] = {
@@ -967,7 +967,7 @@
MDString::get(VMContext, Name),
MDString::get(VMContext, DisplayName),
MDString::get(VMContext, LinkageName),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
Ty.getNode(),
ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
@@ -989,13 +989,14 @@
/// CreateVariable - Create a new descriptor for the specified variable.
DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit, unsigned LineNo,
+ DIFile F,
+ unsigned LineNo,
DIType Ty) {
Value *Elts[] = {
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
Ty.getNode(),
};
@@ -1007,7 +1008,7 @@
/// which has a complex address expression for its address.
DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNo,
DIType Ty,
SmallVector &addr) {
@@ -1015,7 +1016,7 @@
Elts.push_back(GetTagConstant(Tag));
Elts.push_back(Context.getNode());
Elts.push_back(MDString::get(VMContext, Name));
- Elts.push_back(CompileUnit.getNode());
+ Elts.push_back(F.getNode());
Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo));
Elts.push_back(Ty.getNode());
Elts.insert(Elts.end(), addr.begin(), addr.end());
@@ -1040,13 +1041,13 @@
/// CreateNameSpace - This creates new descriptor for a namespace
/// with the specified parent context.
DINameSpace DIFactory::CreateNameSpace(DIDescriptor Context, StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNo) {
Value *Elts[] = {
GetTagConstant(dwarf::DW_TAG_namespace),
Context.getNode(),
MDString::get(VMContext, Name),
- CompileUnit.getNode(),
+ F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)
};
return DINameSpace(MDNode::get(VMContext, &Elts[0], 5));
Modified: llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2010-02-17-DbgArtificialArg.cpp?rev=98020&r1=98019&r2=98020&view=diff
==============================================================================
--- llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp (original)
+++ llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp Mon Mar 8 18:44:10 2010
@@ -1,4 +1,4 @@
-// RUN: %llvmgcc -g -S %s -o - | grep DW_TAG_pointer_type | grep "i32 458767, metadata .., metadata ..., metadata .., i32 ., i64 .., i64 .., i64 0, i32 64, metadata ..."
+// RUN: %llvmgcc -g -S %s -o - | grep DW_TAG_pointer_type | grep "i32 524303, metadata .., metadata ..., metadata .., i32 ., i64 .., i64 .., i64 0, i32 64, metadata ..."
// Here, second to last argument "i32 64" indicates that artificial type is set.
// Test to artificial attribute attahed to "this" pointer type.
// Radar 7655792 and 7655002
From dpatel at apple.com Mon Mar 8 18:45:32 2010
From: dpatel at apple.com (Devang Patel)
Date: Tue, 09 Mar 2010 00:45:32 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r98022 - in /llvm-gcc-4.2/trunk/gcc:
llvm-debug.cpp llvm-debug.h
Message-ID: <20100309004532.15AA72A6C12C@llvm.org>
Author: dpatel
Date: Mon Mar 8 18:45:31 2010
New Revision: 98022
URL: http://llvm.org/viewvc/llvm-project?rev=98022&view=rev
Log:
Start using DIFile. Corresponding llvm patch is r98020.
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
llvm-gcc-4.2/trunk/gcc/llvm-debug.h
Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=98022&r1=98021&r2=98022&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Mon Mar 8 18:45:31 2010
@@ -319,7 +319,7 @@
ArtificialFnWithAbstractOrigin = true;
DIDescriptor SPContext = ArtificialFnWithAbstractOrigin ?
- getOrCreateCompileUnit(main_input_filename) :
+ getOrCreateFile(main_input_filename) :
findRegion (DECL_CONTEXT(FnDecl));
// Creating context may have triggered creation of this SP descriptor. So
@@ -361,7 +361,7 @@
DebugFactory.CreateSubprogram(SPContext,
FnName, FnName,
LinkageName,
- getOrCreateCompileUnit(Loc.file), lineno,
+ getOrCreateFile(Loc.file), lineno,
FNType,
Fn->hasInternalLinkage(),
true /*definition*/,
@@ -385,7 +385,7 @@
expanded_location Loc = GetNodeLocation(Node, false);
DINameSpace DNS =
DebugFactory.CreateNameSpace(Context, GetNodeName(Node),
- getOrCreateCompileUnit(Loc.file), Loc.line);
+ getOrCreateFile(Loc.file), Loc.line);
NameSpaceCache[Node] = WeakVH(DNS.getNode());
return DNS;
@@ -394,7 +394,7 @@
/// findRegion - Find tree_node N's region.
DIDescriptor DebugInfo::findRegion(tree Node) {
if (Node == NULL_TREE)
- return getOrCreateCompileUnit(main_input_filename);
+ return getOrCreateFile(main_input_filename);
std::map::iterator I = RegionMap.find(Node);
if (I != RegionMap.end())
@@ -422,7 +422,7 @@
}
// Otherwise main compile unit covers everything.
- return getOrCreateCompileUnit(main_input_filename);
+ return getOrCreateFile(main_input_filename);
}
/// EmitFunctionEnd - Constructs the debug code for exiting a declarative
@@ -464,7 +464,7 @@
Ty = DebugFactory.CreateArtificialType(Ty);
llvm::DIVariable D =
DebugFactory.CreateVariable(Tag, VarScope,
- Name, getOrCreateCompileUnit(Loc.file),
+ Name, getOrCreateFile(Loc.file),
Loc.line, Ty);
// Insert an llvm.dbg.declare into the current block.
@@ -553,7 +553,7 @@
LinkageName = GV->getName();
DebugFactory.CreateGlobalVariable(findRegion(DECL_CONTEXT(decl)),
DispName, DispName, LinkageName,
- getOrCreateCompileUnit(Loc.file), Loc.line,
+ getOrCreateFile(Loc.file), Loc.line,
TyD, GV->hasInternalLinkage(),
true/*definition*/, GV);
}
@@ -600,9 +600,9 @@
}
return
- DebugFactory.CreateBasicType(getOrCreateCompileUnit(main_input_filename),
+ DebugFactory.CreateBasicType(getOrCreateFile(main_input_filename),
TypeName,
- getOrCreateCompileUnit(main_input_filename),
+ getOrCreateFile(main_input_filename),
0, Size, Align,
0, 0, Encoding);
}
@@ -631,9 +631,9 @@
sprintf(FwdTypeName, "fwd.type.%d", FwdTypeCount++);
llvm::DIType FwdType =
DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
- getOrCreateCompileUnit(NULL),
+ getOrCreateFile(main_input_filename),
FwdTypeName,
- getOrCreateCompileUnit(NULL),
+ getOrCreateFile(main_input_filename),
0, 0, 0, 0, 0,
llvm::DIType(), llvm::DIArray());
llvm::TrackingVH FwdTypeNode = FwdType.getNode();
@@ -674,7 +674,7 @@
DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
findRegion(TYPE_CONTEXT(type)),
StringRef(),
- getOrCreateCompileUnit(NULL),
+ getOrCreateFile(main_input_filename),
0, 0, 0, 0, 0,
llvm::DIType(), EltTypeArray);
@@ -706,7 +706,7 @@
DIType Ty =
DebugFactory.CreateDerivedType(Tag, findRegion(DECL_CONTEXT(TyName)),
GetNodeName(TyName),
- getOrCreateCompileUnit(TypeNameLoc.file),
+ getOrCreateFile(TypeNameLoc.file),
TypeNameLoc.line,
0 /*size*/,
0 /*align*/,
@@ -722,7 +722,7 @@
DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)),
Tag == DW_TAG_pointer_type ?
StringRef() : PName,
- getOrCreateCompileUnit(NULL),
+ getOrCreateFile(main_input_filename),
0 /*line no*/,
NodeSizeInBits(type),
NodeAlignInBits(type),
@@ -784,7 +784,7 @@
return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type,
findRegion(TYPE_CONTEXT(type)),
StringRef(),
- getOrCreateCompileUnit(Loc.file), 0,
+ getOrCreateFile(Loc.file), 0,
NodeSizeInBits(type),
NodeAlignInBits(type), 0, 0,
getOrCreateType(EltTy),
@@ -816,7 +816,7 @@
return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type,
findRegion(TYPE_CONTEXT(type)),
GetNodeName(type),
- getOrCreateCompileUnit(Loc.file),
+ getOrCreateFile(Loc.file),
Loc.line,
NodeSizeInBits(type),
NodeAlignInBits(type), 0, 0,
@@ -834,8 +834,7 @@
if (TYPE_LANG_SPECIFIC (type)
&& lang_hooks.types.is_runtime_specific_type (type))
{
- DICompileUnit CU = getOrCreateCompileUnit(main_input_filename);
- unsigned CULang = CU.getLanguage();
+ unsigned CULang = TheCU.getLanguage();
switch (CULang) {
case DW_LANG_ObjC_plus_plus :
RunTimeLang = DW_LANG_ObjC_plus_plus;
@@ -890,7 +889,7 @@
DebugFactory.CreateCompositeType(Tag,
TyContext,
FwdName.c_str(),
- getOrCreateCompileUnit(Loc.file),
+ getOrCreateFile(Loc.file),
Loc.line,
0, 0, 0, SFlags | llvm::DIType::FlagFwdDecl,
llvm::DIType(), llvm::DIArray(),
@@ -940,7 +939,7 @@
DIType DTy =
DebugFactory.CreateDerivedType(DW_TAG_inheritance,
findRegion(TYPE_CONTEXT(type)), StringRef(),
- llvm::DICompileUnit(), 0,0,0,
+ llvm::DIFile(), 0,0,0,
Offset,
BFlags, BaseClass);
EltTys.push_back(DTy);
@@ -986,7 +985,7 @@
DebugFactory.CreateDerivedType(DW_TAG_member,
findRegion(DECL_CONTEXT(Member)),
MemberName,
- getOrCreateCompileUnit(MemLoc.file),
+ getOrCreateFile(MemLoc.file),
MemLoc.line, NodeSizeInBits(Member),
NodeAlignInBits(FieldNodeType),
int_bit_position(Member),
@@ -1025,7 +1024,7 @@
DebugFactory.CreateSubprogram(findRegion(DECL_CONTEXT(Member)),
MemberName, MemberName,
LinkageName,
- getOrCreateCompileUnit(MemLoc.file),
+ getOrCreateFile(MemLoc.file),
MemLoc.line, SPTy, false, false,
Virtuality, VIndex, ContainingType,
DECL_ARTIFICIAL (Member));
@@ -1050,7 +1049,7 @@
llvm::DICompositeType RealDecl =
DebugFactory.CreateCompositeType(Tag, findRegion(TYPE_CONTEXT(type)),
GetNodeName(type),
- getOrCreateCompileUnit(Loc.file),
+ getOrCreateFile(Loc.file),
Loc.line,
NodeSizeInBits(type), NodeAlignInBits(type),
0, SFlags, llvm::DIType(), Elements,
@@ -1078,7 +1077,7 @@
Ty = DebugFactory.CreateDerivedType(DW_TAG_typedef,
findRegion(DECL_CONTEXT(TyDef)),
GetNodeName(TyDef),
- getOrCreateCompileUnit(TypeDefLoc.file),
+ getOrCreateFile(TypeDefLoc.file),
TypeDefLoc.line,
0 /*size*/,
0 /*align*/,
@@ -1094,7 +1093,7 @@
Ty = DebugFactory.CreateDerivedType(DW_TAG_volatile_type,
findRegion(TYPE_CONTEXT(type)),
StringRef(),
- getOrCreateCompileUnit(NULL),
+ getOrCreateFile(main_input_filename),
0 /*line no*/,
NodeSizeInBits(type),
NodeAlignInBits(type),
@@ -1108,7 +1107,7 @@
Ty = DebugFactory.CreateDerivedType(DW_TAG_const_type,
findRegion(TYPE_CONTEXT(type)),
StringRef(),
- getOrCreateCompileUnit(NULL),
+ getOrCreateFile(main_input_filename),
0 /*line no*/,
NodeSizeInBits(type),
NodeAlignInBits(type),
@@ -1227,9 +1226,9 @@
// module does not contain any main compile unit then the code generator
// will emit multiple compile units in the output object file.
if (!strcmp (main_input_filename, ""))
- getOrCreateCompileUnit("", true);
+ TheCU = getOrCreateCompileUnit("", true);
else
- getOrCreateCompileUnit(main_input_filename, true);
+ TheCU = getOrCreateCompileUnit(main_input_filename, true);
}
/// getOrCreateCompileUnit - Get the compile unit from the cache or
@@ -1242,10 +1241,6 @@
else
FullPath = main_input_filename;
}
- std::map::iterator I = CUCache.find(FullPath);
- if (I != CUCache.end())
- if (Value *M = I->second)
- return DICompileUnit(cast(M));
// Get source file information.
std::string Directory;
@@ -1286,13 +1281,27 @@
unsigned ObjcRunTimeVer = 0;
if (flag_objc_abi != 0 && flag_objc_abi != -1)
ObjcRunTimeVer = flag_objc_abi;
- DICompileUnit NewCU = DebugFactory.CreateCompileUnit(LangTag, FileName.c_str(),
- Directory.c_str(),
- version_string, isMain,
- optimize, Flags,
- ObjcRunTimeVer);
- CUCache[FullPath] = WeakVH(NewCU.getNode());
- return NewCU;
+ return DebugFactory.CreateCompileUnit(LangTag, FileName.c_str(),
+ Directory.c_str(),
+ version_string, isMain,
+ optimize, Flags,
+ ObjcRunTimeVer);
+}
+
+/// getOrCreateFile - Get DIFile descriptor.
+DIFile DebugInfo::getOrCreateFile(const char *FullPath) {
+ if (!FullPath) {
+ if (!strcmp (main_input_filename, ""))
+ FullPath = "";
+ else
+ FullPath = main_input_filename;
+ }
+
+ // Get source file information.
+ std::string Directory;
+ std::string FileName;
+ DirectoryAndFile(FullPath, Directory, FileName);
+ return DebugFactory.CreateFile(FileName, Directory, TheCU);
}
/* LLVM LOCAL end (ENTIRE FILE!) */
Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.h?rev=98022&r1=98021&r2=98022&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.h Mon Mar 8 18:45:31 2010
@@ -62,7 +62,8 @@
const char *PrevFullPath; // Previous location file encountered.
int PrevLineNo; // Previous location line# encountered.
BasicBlock *PrevBB; // Last basic block encountered.
-
+ DICompileUnit TheCU; // The compile unit.
+
// Current GCC lexical block (or enclosing FUNCTION_DECL).
tree_node *CurrentGCCLexicalBlock;
@@ -71,7 +72,6 @@
// debug info (through MDNodes) is not shared accidently.
unsigned FwdTypeCount;
- std::map CUCache;
std::map TypeCache;
// Cache of previously constructed
// Types.
@@ -168,6 +168,9 @@
DICompileUnit getOrCreateCompileUnit(const char *FullPath,
bool isMain = false);
+ /// getOrCreateFile - Get DIFile descriptor.
+ DIFile getOrCreateFile(const char *FullPath);
+
/// findRegion - Find tree_node N's region.
DIDescriptor findRegion(tree_node *n);
From wendling at apple.com Mon Mar 8 18:46:30 2010
From: wendling at apple.com (Bill Wendling)
Date: Mon, 8 Mar 2010 16:46:30 -0800
Subject: [llvm-commits] [llvm] r98019 -
/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
In-Reply-To: <20100309004334.EADFB2A6C12C@llvm.org>
References: <20100309004334.EADFB2A6C12C@llvm.org>
Message-ID:
Um...this also has a change of behavior (it snuck in there). If a symbol that's non-lazy is pointing to a symbol that's defined in the translation unit, then output a reference to it in the non-lazy pointer itself.
-bw
On Mar 8, 2010, at 4:43 PM, Bill Wendling wrote:
> Author: void
> Date: Mon Mar 8 18:43:34 2010
> New Revision: 98019
>
> URL: http://llvm.org/viewvc/llvm-project?rev=98019&view=rev
> Log:
> Print blank line and clear stubs vector.
>
> Modified:
> llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
>
> Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=98019&r1=98018&r2=98019&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Mon Mar 8 18:43:34 2010
> @@ -1132,8 +1132,16 @@
> // L_foo$stub:
> OutStreamer.EmitLabel(Stubs[i].first);
> // .indirect_symbol _foo
> - OutStreamer.EmitSymbolAttribute(Stubs[i].second, MCSA_IndirectSymbol);
> - OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
> + MCSymbol *MCSym = Stubs[i].second;
> + OutStreamer.EmitSymbolAttribute(MCSym, MCSA_IndirectSymbol);
> +
> + if (MCSym->isUndefined())
> + // External to current translation unit.
> + OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
> + else
> + // Internal to current translation unit.
> + OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym, OutContext),
> + 4/*size*/, 0/*addrspace*/);
> }
>
> Stubs.clear();
> @@ -1152,6 +1160,9 @@
> OutContext),
> 4/*size*/, 0/*addrspace*/);
> }
> +
> + Stubs.clear();
> + OutStreamer.AddBlankLine();
> }
>
> // Funny Darwin hack: This flag tells the linker that no global symbols
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From stoklund at 2pi.dk Mon Mar 8 18:57:29 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Mon, 8 Mar 2010 16:57:29 -0800
Subject: [llvm-commits] [llvm] r98007 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
In-Reply-To: <20100308232808.91F8F2A6C12C@llvm.org>
References: <20100308232808.91F8F2A6C12C@llvm.org>
Message-ID: <12195ADE-5620-4756-8425-E09F73A9646D@2pi.dk>
On Mar 8, 2010, at 3:28 PM, Evan Cheng wrote:
> Author: evancheng
> Date: Mon Mar 8 17:28:08 2010
> New Revision: 98007
>
> URL: http://llvm.org/viewvc/llvm-project?rev=98007&view=rev
> Log:
> Restrict machine cse to really trivial coalescing. Leave the heavy lifting to a real coalescer.
>
> Modified:
> llvm/trunk/lib/CodeGen/MachineCSE.cpp
>
> Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=98007&r1=98006&r2=98007&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
> +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Mon Mar 8 17:28:08 2010
> @@ -91,7 +91,10 @@
> unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
> if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
> TargetRegisterInfo::isVirtualRegister(SrcReg) &&
> + MRI->getRegClass(SrcReg) == MRI->getRegClass(Reg) &&
> !SrcSubIdx && !DstSubIdx) {
> + DEBUG(dbgs() << "Coalescing: " << *DefMI);
> + DEBUG(dbgs() << "*** to: " << *MI);
> MO.setReg(SrcReg);
> DefMI->eraseFromParent();
> ++NumCoalesces;
You could add "|| MRI->getRegClass(Reg)->hasSubClass(MRI->getRegClass(SrcReg))" without getting too complicated. That could help a bit with the few x86_64 subclasses as well.
From stoklund at 2pi.dk Mon Mar 8 18:59:48 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Tue, 09 Mar 2010 00:59:48 -0000
Subject: [llvm-commits] [llvm] r98023 -
/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
Message-ID: <20100309005948.483A02A6C12C@llvm.org>
Author: stoklund
Date: Mon Mar 8 18:59:48 2010
New Revision: 98023
URL: http://llvm.org/viewvc/llvm-project?rev=98023&view=rev
Log:
Disable physical register coalescing when the number of live ranges for the
physreg becomes ridiculously high.
std::upper_bound may be log(N), but for sufficiently large live intervals, it
becomes log(N)*cachemiss = a long long time.
This patch improves coalescer time by 4500x for a function with 20000
function calls. The generated code is different, but not significantly worse -
the allocator hints are almost as good as physreg coalescing anyway.
Modified:
llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=98023&r1=98022&r2=98023&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Mon Mar 8 18:59:48 2010
@@ -1671,8 +1671,20 @@
// density, do not join them, instead mark the physical register as its
// allocation preference.
LiveInterval &JoinVInt = SrcIsPhys ? DstInt : SrcInt;
+ LiveInterval &JoinPInt = SrcIsPhys ? SrcInt : DstInt;
unsigned JoinVReg = SrcIsPhys ? DstReg : SrcReg;
unsigned JoinPReg = SrcIsPhys ? SrcReg : DstReg;
+
+ // Don't join with physregs that have a ridiculous number of live
+ // ranges. The data structure performance is really bad when that
+ // happens.
+ if (JoinPInt.ranges.size() > 1000) {
+ mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
+ ++numAborts;
+ DEBUG(dbgs() << "\tPhysical register too complicated, abort!\n");
+ return false;
+ }
+
const TargetRegisterClass *RC = mri_->getRegClass(JoinVReg);
unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
unsigned Length = li_->getApproximateInstructionCount(JoinVInt);
From stoklund at 2pi.dk Mon Mar 8 18:59:53 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Tue, 09 Mar 2010 00:59:53 -0000
Subject: [llvm-commits] [llvm] r98024 -
/llvm/trunk/lib/Transforms/IPO/Inliner.cpp
Message-ID: <20100309005953.5BD432A6C12D@llvm.org>
Author: stoklund
Date: Mon Mar 8 18:59:53 2010
New Revision: 98024
URL: http://llvm.org/viewvc/llvm-project?rev=98024&view=rev
Log:
Add inlining threshold to log output.
Modified:
llvm/trunk/lib/Transforms/IPO/Inliner.cpp
Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=98024&r1=98023&r2=98024&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Mon Mar 8 18:59:53 2010
@@ -219,8 +219,10 @@
Function *Caller = CS.getCaller();
int CurrentThreshold = getInlineThreshold(CS);
float FudgeFactor = getInlineFudgeFactor(CS);
- if (Cost >= (int)(CurrentThreshold * FudgeFactor)) {
+ int AdjThreshold = (int)(CurrentThreshold * FudgeFactor);
+ if (Cost >= AdjThreshold) {
DEBUG(dbgs() << " NOT Inlining: cost=" << Cost
+ << ", thres=" << AdjThreshold
<< ", Call: " << *CS.getInstruction() << "\n");
return false;
}
@@ -285,6 +287,7 @@
}
DEBUG(dbgs() << " Inlining: cost=" << Cost
+ << ", thres=" << AdjThreshold
<< ", Call: " << *CS.getInstruction() << '\n');
return true;
}
From sabre at nondot.org Mon Mar 8 19:02:30 2010
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 09 Mar 2010 01:02:30 -0000
Subject: [llvm-commits] [llvm] r98025 - in
/llvm/trunk/lib/CodeGen/AsmPrinter: AsmPrinter.cpp DwarfDebug.cpp
Message-ID: <20100309010230.90A922A6C12C@llvm.org>
Author: lattner
Date: Mon Mar 8 19:02:30 2010
New Revision: 98025
URL: http://llvm.org/viewvc/llvm-project?rev=98025&view=rev
Log:
mcstreamerize AsmPrinter::printLabel.
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=98025&r1=98024&r2=98025&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Mar 8 19:02:30 2010
@@ -1323,7 +1323,6 @@
CurDLT.getColumnNumber(),
CurDLT.getScope().getNode());
printLabel(L);
- O << '\n';
DW->BeginScope(MI, L);
PrevDLT = CurDLT.getNode();
}
@@ -1554,12 +1553,17 @@
/// printLabel - This method prints a local label used by debug and
/// exception handling tables.
void AsmPrinter::printLabelInst(const MachineInstr *MI) const {
- printLabel(MI->getOperand(0).getImm());
- OutStreamer.AddBlankLine();
+ MCSymbol *Sym =
+ OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
+ "label" + Twine(MI->getOperand(0).getImm()));
+ OutStreamer.EmitLabel(Sym);
}
void AsmPrinter::printLabel(unsigned Id) const {
- O << MAI->getPrivateGlobalPrefix() << "label" << Id << ':';
+ MCSymbol *Sym =
+ OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
+ "label" + Twine(Id));
+ OutStreamer.EmitLabel(Sym);
}
/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=98025&r1=98024&r2=98025&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 8 19:02:30 2010
@@ -1972,7 +1972,6 @@
unsigned Label = MMI->NextLabelID();
Asm->printLabel(Label);
- O << '\n';
SmallVector &SD = I->second;
for (SmallVector::iterator SDI = SD.begin(), SDE = SD.end();
@@ -2131,7 +2130,6 @@
DLT.getColumnNumber(),
DLT.getScope().getNode());
Asm->printLabel(LabelID);
- O << '\n';
}
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
From xuzhongxing at gmail.com Mon Mar 8 19:05:35 2010
From: xuzhongxing at gmail.com (Zhongxing Xu)
Date: Tue, 9 Mar 2010 09:05:35 +0800
Subject: [llvm-commits] [PATCH] remove redundant 'static'
In-Reply-To:
References: <5400aeb81003080445r3184c915j3c1471351f67d438@mail.gmail.com>
Message-ID: <5400aeb81003081705v1480ab04i1c8be003d2738b2e@mail.gmail.com>
2010/3/9 Chris Lattner :
>
> On Mar 8, 2010, at 4:45 AM, Zhongxing Xu wrote:
>
>> 'static' is redundant in this context:
>
> Um, no it's not. ?It prevents exporting the symbol from the .o file. ?What are you trying to fix?
>
'const' in namespace scope implies internal linkage. Is that
sufficient to prevent exporting the symbol from the .o file?
> -Chris
>
>>
>> Index: utils/TableGen/RegisterInfoEmitter.cpp
>> ===================================================================
>> --- utils/TableGen/RegisterInfoEmitter.cpp ? ?(?? 97892)
>> +++ utils/TableGen/RegisterInfoEmitter.cpp ? ?(????)
>> @@ -201,7 +201,7 @@
>>
>> ? ? // Emit the register list now.
>> ? ? OS << " ?// " << Name << " Register Class...\n"
>> - ? ? ? << " ?static const unsigned " << Name
>> + ? ? ? << " ?const unsigned " << Name
>> ? ? ? ?<< "[] = {\n ? ?";
>> ? ? for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
>> ? ? ? Record *Reg = RC.Elements[i];
>> @@ -223,7 +223,7 @@
>> ? ? // Emit the register list now.
>> ? ? OS << " ?// " << Name
>> ? ? ? ?<< " Register Class Value Types...\n"
>> - ? ? ? << " ?static const EVT " << Name
>> + ? ? ? << " ?const EVT " << Name
>> ? ? ? ?<< "[] = {\n ? ?";
>> ? ? for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i)
>> ? ? ? OS << getEnumName(RC.VTs[i]) << ", ";
>> @@ -252,7 +252,7 @@
>>
>> ? ? ? OS << " ?// " << Name
>> ? ? ? ? ?<< " Sub-register Classes...\n"
>> - ? ? ? ? << " ?static const TargetRegisterClass* const "
>> + ? ? ? ? << " ?const TargetRegisterClass* const "
>> ? ? ? ? ?<< Name << "SubRegClasses[] = {\n ? ?";
>>
>> ? ? ? bool Empty = true;
>> @@ -298,7 +298,7 @@
>>
>> ? ? ? OS << " ?// " << Name
>> ? ? ? ? ?<< " Super-register Classes...\n"
>> - ? ? ? ? << " ?static const TargetRegisterClass* const "
>> + ? ? ? ? << " ?const TargetRegisterClass* const "
>> ? ? ? ? ?<< Name << "SuperRegClasses[] = {\n ? ?";
>>
>> ? ? ? bool Empty = true;
>> @@ -334,7 +334,7 @@
>>
>> ? ? ? OS << " ?// " << Name
>> ? ? ? ? ?<< " Register Class sub-classes...\n"
>> - ? ? ? ? << " ?static const TargetRegisterClass* const "
>> + ? ? ? ? << " ?const TargetRegisterClass* const "
>> ? ? ? ? ?<< Name << "Subclasses[] = {\n ? ?";
>>
>> ? ? ? bool Empty = true;
>> @@ -382,7 +382,7 @@
>>
>> ? ? ? OS << " ?// " << Name
>> ? ? ? ? ?<< " Register Class super-classes...\n"
>> - ? ? ? ? << " ?static const TargetRegisterClass* const "
>> + ? ? ? ? << " ?const TargetRegisterClass* const "
>> ? ? ? ? ?<< Name << "Superclasses[] = {\n ? ?";
>>
>> ? ? ? bool Empty = true;
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
From dalej at apple.com Mon Mar 8 19:08:11 2010
From: dalej at apple.com (Dale Johannesen)
Date: Tue, 09 Mar 2010 01:08:11 -0000
Subject: [llvm-commits] [llvm] r98026 -
/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
Message-ID: <20100309010811.AE1252A6C12C@llvm.org>
Author: johannes
Date: Mon Mar 8 19:08:11 2010
New Revision: 98026
URL: http://llvm.org/viewvc/llvm-project?rev=98026&view=rev
Log:
Another place where debug info affected codegen.
Modified:
llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=98026&r1=98025&r2=98026&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Mon Mar 8 19:08:11 2010
@@ -1286,6 +1286,8 @@
// there) so that it is guaranteed to dominate any user inside the loop.
if (L && S->hasComputableLoopEvolution(L) && L != PostIncLoop)
InsertPt = L->getHeader()->getFirstNonPHI();
+ while (isa(InsertPt))
+ InsertPt = llvm::next(BasicBlock::iterator(InsertPt));
while (isInsertedInstruction(InsertPt))
InsertPt = llvm::next(BasicBlock::iterator(InsertPt));
break;
From daniel at zuster.org Mon Mar 8 19:12:20 2010
From: daniel at zuster.org (Daniel Dunbar)
Date: Tue, 09 Mar 2010 01:12:20 -0000
Subject: [llvm-commits] [llvm] r98027 - /llvm/trunk/lib/MC/MCAssembler.cpp
Message-ID: <20100309011221.024702A6C12C@llvm.org>
Author: ddunbar
Date: Mon Mar 8 19:12:20 2010
New Revision: 98027
URL: http://llvm.org/viewvc/llvm-project?rev=98027&view=rev
Log:
MC/Mach-O: Don't adjust section sizes when aligning zero fill sections, just pad the address.
Modified:
llvm/trunk/lib/MC/MCAssembler.cpp
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=98027&r1=98026&r2=98027&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Mar 8 19:12:20 2010
@@ -1281,17 +1281,13 @@
// Align this section if necessary by adding padding bytes to the previous
// section.
- if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment())) {
- assert(Prev && "Missing prev section!");
- Prev->setFileSize(Prev->getFileSize() + Pad);
+ if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment()))
Address += Pad;
- }
SD.setAddress(Address);
LayoutSection(SD);
Address += SD.getSize();
- Prev = &SD;
}
DEBUG_WITH_TYPE("mc-dump", {
From daniel at zuster.org Mon Mar 8 19:12:23 2010
From: daniel at zuster.org (Daniel Dunbar)
Date: Tue, 09 Mar 2010 01:12:23 -0000
Subject: [llvm-commits] [llvm] r98028 - /llvm/trunk/lib/MC/MCAssembler.cpp
Message-ID: <20100309011223.C0F302A6C12D@llvm.org>
Author: ddunbar
Date: Mon Mar 8 19:12:23 2010
New Revision: 98028
URL: http://llvm.org/viewvc/llvm-project?rev=98028&view=rev
Log:
MC/Mach-O: Tweak .dump() formatting.
Modified:
llvm/trunk/lib/MC/MCAssembler.cpp
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=98028&r1=98027&r2=98028&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Mar 8 19:12:23 2010
@@ -1351,7 +1351,7 @@
OS << ",\n ";
OS << " Fixups:[";
for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) {
- if (it != fixup_begin()) OS << ",\n ";
+ if (it != fixup_begin()) OS << ",\n ";
OS << *it;
}
OS << "]";
@@ -1394,7 +1394,7 @@
OS << "dump();
@@ -1422,7 +1422,7 @@
raw_ostream &OS = llvm::errs();
OS << "dump();
@@ -1431,7 +1431,7 @@
OS << " Symbols:[";
for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) {
- if (it != symbol_begin()) OS << ",\n ";
+ if (it != symbol_begin()) OS << ",\n ";
it->dump();
}
OS << "]>\n";
From clattner at apple.com Mon Mar 8 19:17:26 2010
From: clattner at apple.com (Chris Lattner)
Date: Mon, 8 Mar 2010 17:17:26 -0800
Subject: [llvm-commits] [PATCH] remove redundant 'static'
In-Reply-To: <5400aeb81003081705v1480ab04i1c8be003d2738b2e@mail.gmail.com>
References: <5400aeb81003080445r3184c915j3c1471351f67d438@mail.gmail.com>
<5400aeb81003081705v1480ab04i1c8be003d2738b2e@mail.gmail.com>
Message-ID:
On Mar 8, 2010, at 5:05 PM, Zhongxing Xu wrote:
> 2010/3/9 Chris Lattner :
>>
>> On Mar 8, 2010, at 4:45 AM, Zhongxing Xu wrote:
>>
>>> 'static' is redundant in this context:
>>
>> Um, no it's not. It prevents exporting the symbol from the .o file. What are you trying to fix?
>>
>
> 'const' in namespace scope implies internal linkage. Is that
> sufficient to prevent exporting the symbol from the .o file?
It could be, but why do this? What does it fix? IMO, static is a lot less subtle.
-Chris
From evan.cheng at apple.com Mon Mar 8 19:23:20 2010
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 8 Mar 2010 17:23:20 -0800
Subject: [llvm-commits] [llvm] r98007 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
In-Reply-To: <12195ADE-5620-4756-8425-E09F73A9646D@2pi.dk>
References: <20100308232808.91F8F2A6C12C@llvm.org>
<12195ADE-5620-4756-8425-E09F73A9646D@2pi.dk>
Message-ID: <20FB2BBD-9306-4DD8-961E-A627EE6A2FD2@apple.com>
On Mar 8, 2010, at 4:57 PM, Jakob Stoklund Olesen wrote:
>
> On Mar 8, 2010, at 3:28 PM, Evan Cheng wrote:
>
>> Author: evancheng
>> Date: Mon Mar 8 17:28:08 2010
>> New Revision: 98007
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=98007&view=rev
>> Log:
>> Restrict machine cse to really trivial coalescing. Leave the heavy lifting to a real coalescer.
>>
>> Modified:
>> llvm/trunk/lib/CodeGen/MachineCSE.cpp
>>
>> Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=98007&r1=98006&r2=98007&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Mon Mar 8 17:28:08 2010
>> @@ -91,7 +91,10 @@
>> unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
>> if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
>> TargetRegisterInfo::isVirtualRegister(SrcReg) &&
>> + MRI->getRegClass(SrcReg) == MRI->getRegClass(Reg) &&
>> !SrcSubIdx && !DstSubIdx) {
>> + DEBUG(dbgs() << "Coalescing: " << *DefMI);
>> + DEBUG(dbgs() << "*** to: " << *MI);
>> MO.setReg(SrcReg);
>> DefMI->eraseFromParent();
>> ++NumCoalesces;
>
> You could add "|| MRI->getRegClass(Reg)->hasSubClass(MRI->getRegClass(SrcReg))" without getting too complicated. That could help a bit with the few x86_64 subclasses as well.
>
I don't think it's necessary here. It's doing local coalescing here to avoid missing some obvious cse opportunities. If sub-reg class is involved, then it's already too complicated.
Evan
From evan.cheng at apple.com Mon Mar 8 19:23:49 2010
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 8 Mar 2010 17:23:49 -0800
Subject: [llvm-commits] [llvm] r98023 -
/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
In-Reply-To: <20100309005948.483A02A6C12C@llvm.org>
References: <20100309005948.483A02A6C12C@llvm.org>
Message-ID:
Is 1000 scientific? :-)
Evan
On Mar 8, 2010, at 4:59 PM, Jakob Stoklund Olesen wrote:
> Author: stoklund
> Date: Mon Mar 8 18:59:48 2010
> New Revision: 98023
>
> URL: http://llvm.org/viewvc/llvm-project?rev=98023&view=rev
> Log:
> Disable physical register coalescing when the number of live ranges for the
> physreg becomes ridiculously high.
>
> std::upper_bound may be log(N), but for sufficiently large live intervals, it
> becomes log(N)*cachemiss = a long long time.
>
> This patch improves coalescer time by 4500x for a function with 20000
> function calls. The generated code is different, but not significantly worse -
> the allocator hints are almost as good as physreg coalescing anyway.
>
> Modified:
> llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=98023&r1=98022&r2=98023&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Mon Mar 8 18:59:48 2010
> @@ -1671,8 +1671,20 @@
> // density, do not join them, instead mark the physical register as its
> // allocation preference.
> LiveInterval &JoinVInt = SrcIsPhys ? DstInt : SrcInt;
> + LiveInterval &JoinPInt = SrcIsPhys ? SrcInt : DstInt;
> unsigned JoinVReg = SrcIsPhys ? DstReg : SrcReg;
> unsigned JoinPReg = SrcIsPhys ? SrcReg : DstReg;
> +
> + // Don't join with physregs that have a ridiculous number of live
> + // ranges. The data structure performance is really bad when that
> + // happens.
> + if (JoinPInt.ranges.size() > 1000) {
> + mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
> + ++numAborts;
> + DEBUG(dbgs() << "\tPhysical register too complicated, abort!\n");
> + return false;
> + }
> +
> const TargetRegisterClass *RC = mri_->getRegClass(JoinVReg);
> unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
> unsigned Length = li_->getApproximateInstructionCount(JoinVInt);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From sabre at nondot.org Mon Mar 8 19:29:59 2010
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 09 Mar 2010 01:29:59 -0000
Subject: [llvm-commits] [llvm] r98029 -
/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
Message-ID: <20100309012959.A1D2B2A6C12C@llvm.org>
Author: lattner
Date: Mon Mar 8 19:29:59 2010
New Revision: 98029
URL: http://llvm.org/viewvc/llvm-project?rev=98029&view=rev
Log:
inline RemapLabel into its only caller and simplify.
Modified:
llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=98029&r1=98028&r2=98029&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Mon Mar 8 19:29:59 2010
@@ -217,17 +217,9 @@
/// MachineModuleInfo, for example because the code was deleted.
void InvalidateLabel(unsigned LabelID) {
// Remap to zero to indicate deletion.
- RemapLabel(LabelID, 0);
- }
-
- /// RemapLabel - Indicate that a label has been merged into another.
- ///
- void RemapLabel(unsigned OldLabelID, unsigned NewLabelID) {
- assert(0 < OldLabelID && OldLabelID <= LabelIDList.size() &&
- "Old label ID out of range.");
- assert(NewLabelID <= LabelIDList.size() &&
- "New label ID out of range.");
- LabelIDList[OldLabelID - 1] = NewLabelID;
+ assert(0 < LabelID && LabelID <= LabelIDList.size() &&
+ "Old label ID out of range.");
+ LabelIDList[LabelID - 1] = 0;
}
/// MappedLabel - Find out the label's final ID. Zero indicates deletion.
From stoklund at 2pi.dk Mon Mar 8 19:37:52 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Mon, 8 Mar 2010 17:37:52 -0800
Subject: [llvm-commits] [llvm] r98023 -
/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
In-Reply-To:
References: <20100309005948.483A02A6C12C@llvm.org>
Message-ID: <59424131-A98B-428A-9BE7-75786CE199C4@2pi.dk>
On Mar 8, 2010, at 5:23 PM, Evan Cheng wrote:
> Is 1000 scientific? :-)
No. That would require measuring when the LiveInterval size where it outgrows cache. I didn't do that :-(
I have also seen cases where a virtual register LiveInterval becomes too big. That is a lot harder to fix. I think the real problem is the extra indirection in SlotIndex. If SlotIndex were just an unsigned in disguise, each LiveRange would be just 16 bytes, and all ranges for a register would be in contiguous memory.
> On Mar 8, 2010, at 4:59 PM, Jakob Stoklund Olesen wrote:
>
>> Author: stoklund
>> Date: Mon Mar 8 18:59:48 2010
>> New Revision: 98023
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=98023&view=rev
>> Log:
>> Disable physical register coalescing when the number of live ranges for the
>> physreg becomes ridiculously high.
>>
>> std::upper_bound may be log(N), but for sufficiently large live intervals, it
>> becomes log(N)*cachemiss = a long long time.
>>
>> This patch improves coalescer time by 4500x for a function with 20000
>> function calls. The generated code is different, but not significantly worse -
>> the allocator hints are almost as good as physreg coalescing anyway.
>>
>> Modified:
>> llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
>>
>> Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=98023&r1=98022&r2=98023&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Mon Mar 8 18:59:48 2010
>> @@ -1671,8 +1671,20 @@
>> // density, do not join them, instead mark the physical register as its
>> // allocation preference.
>> LiveInterval &JoinVInt = SrcIsPhys ? DstInt : SrcInt;
>> + LiveInterval &JoinPInt = SrcIsPhys ? SrcInt : DstInt;
>> unsigned JoinVReg = SrcIsPhys ? DstReg : SrcReg;
>> unsigned JoinPReg = SrcIsPhys ? SrcReg : DstReg;
>> +
>> + // Don't join with physregs that have a ridiculous number of live
>> + // ranges. The data structure performance is really bad when that
>> + // happens.
>> + if (JoinPInt.ranges.size() > 1000) {
>> + mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
>> + ++numAborts;
>> + DEBUG(dbgs() << "\tPhysical register too complicated, abort!\n");
>> + return false;
>> + }
>> +
>> const TargetRegisterClass *RC = mri_->getRegClass(JoinVReg);
>> unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
>> unsigned Length = li_->getApproximateInstructionCount(JoinVInt);
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
From sabre at nondot.org Mon Mar 8 19:51:43 2010
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 09 Mar 2010 01:51:43 -0000
Subject: [llvm-commits] [llvm] r98031 - in /llvm/trunk:
include/llvm/CodeGen/MachineModuleInfo.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfPrinter.cpp lib/CodeGen/MachineModuleInfo.cpp
lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
Message-ID: <20100309015143.92FA52A6C12C@llvm.org>
Author: lattner
Date: Mon Mar 8 19:51:43 2010
New Revision: 98031
URL: http://llvm.org/viewvc/llvm-project?rev=98031&view=rev
Log:
strength reduce MMI::MappedLabel to MMI::isLabelDeleted,
and add a FIXME about how we are eventually going to zap this
lookup table once mc world domination is complete.
Modified:
llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=98031&r1=98030&r2=98031&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Mon Mar 8 19:51:43 2010
@@ -222,13 +222,14 @@
LabelIDList[LabelID - 1] = 0;
}
- /// MappedLabel - Find out the label's final ID. Zero indicates deletion.
- /// ID != Mapped ID indicates that the label was folded into another label.
- unsigned MappedLabel(unsigned LabelID) const {
+ /// isLabelDeleted - Return true if the label was deleted.
+ /// FIXME: This should eventually be eliminated and use the 'is emitted' bit
+ /// on MCSymbol.
+ bool isLabelDeleted(unsigned LabelID) const {
assert(LabelID <= LabelIDList.size() && "Debug label ID out of range.");
- return LabelID ? LabelIDList[LabelID - 1] : 0;
+ return LabelID == 0 || LabelIDList[LabelID - 1] == 0;
}
-
+
/// getFrameMoves - Returns a reference to a list of moves done in the current
/// function's prologue. Used to construct frame maps for debug and exception
/// handling comsumers.
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=98031&r1=98030&r2=98031&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 8 19:51:43 2010
@@ -1362,9 +1362,14 @@
/// constructLexicalScope - Construct new DW_TAG_lexical_block
/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
- unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID());
- unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID());
+ unsigned StartID = Scope->getStartLabelID();
+ unsigned EndID = Scope->getEndLabelID();
+ assert(!MMI->isLabelDeleted(StartID) &&
+ "Invalid starting label for an inlined scope!");
+ assert(!MMI->isLabelDeleted(EndID) &&
+ "Invalid end label for an inlined scope!");
+
// Ignore empty scopes.
if (StartID == EndID && StartID != 0)
return NULL;
@@ -1387,12 +1392,14 @@
/// a function. Construct DIE to represent this concrete inlined copy
/// of the function.
DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
- unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID());
- unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID());
- assert (StartID && "Invalid starting label for an inlined scope!");
- assert (EndID && "Invalid end label for an inlined scope!");
+ unsigned StartID = Scope->getStartLabelID();
+ unsigned EndID = Scope->getEndLabelID();
+ assert(!MMI->isLabelDeleted(StartID) &&
+ "Invalid starting label for an inlined scope!");
+ assert(!MMI->isLabelDeleted(EndID) &&
+ "Invalid end label for an inlined scope!");
// Ignore empty scopes.
- if (StartID == EndID && StartID != 0)
+ if (StartID == EndID)
return NULL;
if (!Scope->getScopeNode())
return NULL;
@@ -2589,8 +2596,8 @@
// Construct rows of the address, source, line, column matrix.
for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
const SrcLineInfo &LineInfo = LineInfos[i];
- unsigned LabelID = MMI->MappedLabel(LineInfo.getLabelID());
- if (!LabelID) continue;
+ unsigned LabelID = LineInfo.getLabelID();
+ if (MMI->isLabelDeleted(LabelID)) continue;
if (LineInfo.getLine() == 0) continue;
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp?rev=98031&r1=98030&r2=98031&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp Mon Mar 8 19:51:43 2010
@@ -277,12 +277,9 @@
const MachineMove &Move = Moves[i];
unsigned LabelID = Move.getLabelID();
- if (LabelID) {
- LabelID = MMI->MappedLabel(LabelID);
-
- // Throw out move if the label is invalid.
- if (!LabelID) continue;
- }
+ // Throw out move if the label is invalid.
+ if (LabelID && MMI->isLabelDeleted(LabelID))
+ continue;
const MachineLocation &Dst = Move.getDestination();
const MachineLocation &Src = Move.getSource();
Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=98031&r1=98030&r2=98031&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Mon Mar 8 19:51:43 2010
@@ -185,7 +185,8 @@
void MachineModuleInfo::TidyLandingPads() {
for (unsigned i = 0; i != LandingPads.size(); ) {
LandingPadInfo &LandingPad = LandingPads[i];
- LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
+ if (isLabelDeleted(LandingPad.LandingPadLabel))
+ LandingPad.LandingPadLabel = 0;
// Special case: we *should* emit LPs with null LP MBB. This indicates
// "nounwind" case.
@@ -195,17 +196,14 @@
}
for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) {
- unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]);
- unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]);
-
- if (!BeginLabel || !EndLabel) {
+ unsigned BeginLabel = LandingPad.BeginLabels[j];
+ unsigned EndLabel = LandingPad.EndLabels[j];
+ if (isLabelDeleted(BeginLabel) || isLabelDeleted(EndLabel)) {
LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
continue;
}
- LandingPad.BeginLabels[j] = BeginLabel;
- LandingPad.EndLabels[j] = EndLabel;
++j;
}
Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp?rev=98031&r1=98030&r2=98031&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp Mon Mar 8 19:51:43 2010
@@ -75,10 +75,9 @@
unsigned LabelID = Move.getLabelID();
if (LabelID) {
- LabelID = MMI->MappedLabel(LabelID);
-
// Throw out move if the label is invalid.
- if (!LabelID) continue;
+ if (MMI->isLabelDeleted(LabelID))
+ continue;
}
intptr_t LabelPtr = 0;
@@ -722,10 +721,9 @@
unsigned LabelID = Move.getLabelID();
if (LabelID) {
- LabelID = MMI->MappedLabel(LabelID);
-
// Throw out move if the label is invalid.
- if (!LabelID) continue;
+ if (MMI->isLabelDeleted(LabelID))
+ continue;
}
intptr_t LabelPtr = 0;
From sabre at nondot.org Mon Mar 8 19:52:43 2010
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 09 Mar 2010 01:52:43 -0000
Subject: [llvm-commits] [llvm] r98032 -
/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Message-ID: <20100309015243.9E41A2A6C12C@llvm.org>
Author: lattner
Date: Mon Mar 8 19:52:43 2010
New Revision: 98032
URL: http://llvm.org/viewvc/llvm-project?rev=98032&view=rev
Log:
remove a useless optimization: now that label replacement never
happens, the start/end of a scope can never be the same.
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=98032&r1=98031&r2=98032&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 8 19:52:43 2010
@@ -1370,10 +1370,6 @@
assert(!MMI->isLabelDeleted(EndID) &&
"Invalid end label for an inlined scope!");
- // Ignore empty scopes.
- if (StartID == EndID && StartID != 0)
- return NULL;
-
DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
if (Scope->isAbstractScope())
return ScopeDIE;
@@ -1398,9 +1394,6 @@
"Invalid starting label for an inlined scope!");
assert(!MMI->isLabelDeleted(EndID) &&
"Invalid end label for an inlined scope!");
- // Ignore empty scopes.
- if (StartID == EndID)
- return NULL;
if (!Scope->getScopeNode())
return NULL;
DIScope DS(Scope->getScopeNode());
From gohman at apple.com Mon Mar 8 19:53:33 2010
From: gohman at apple.com (Dan Gohman)
Date: Tue, 09 Mar 2010 01:53:33 -0000
Subject: [llvm-commits] [llvm] r98033 - in /llvm/trunk:
lib/Analysis/LoopInfo.cpp test/Transforms/LCSSA/unreachable-use.ll
Message-ID: <20100309015333.B19B12A6C12C@llvm.org>
Author: djg
Date: Mon Mar 8 19:53:33 2010
New Revision: 98033
URL: http://llvm.org/viewvc/llvm-project?rev=98033&view=rev
Log:
Make isLCSSA ignore uses in blocks not reachable from the entry block,
as LCSSA no longer transforms such uses.
Added:
llvm/trunk/test/Transforms/LCSSA/unreachable-use.ll
Modified:
llvm/trunk/lib/Analysis/LoopInfo.cpp
Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=98033&r1=98032&r2=98033&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LoopInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LoopInfo.cpp Mon Mar 8 19:53:33 2010
@@ -264,6 +264,13 @@
/// isLCSSAForm - Return true if the Loop is in LCSSA form
bool Loop::isLCSSAForm() const {
+ // Collect all the reachable blocks in the function, for fast lookups.
+ SmallPtrSet ReachableBBs;
+ BasicBlock *EntryBB = getHeader()->getParent()->begin();
+ for (df_iterator NI = df_begin(EntryBB),
+ NE = df_end(EntryBB); NI != NE; ++NI)
+ ReachableBBs.insert(*NI);
+
// Sort the blocks vector so that we can use binary search to do quick
// lookups.
SmallPtrSet LoopBBs(block_begin(), block_end());
@@ -277,9 +284,13 @@
if (PHINode *P = dyn_cast(*UI))
UserBB = P->getIncomingBlock(UI);
- // Check the current block, as a fast-path. Most values are used in
- // the same block they are defined in.
- if (UserBB != BB && !LoopBBs.count(UserBB))
+ // Check the current block, as a fast-path, before checking whether
+ // the use is anywhere in the loop. Most values are used in the same
+ // block they are defined in. Also, blocks not reachable from the
+ // entry are special; uses in them don't need to go through PHIs.
+ if (UserBB != BB &&
+ !LoopBBs.count(UserBB) &&
+ ReachableBBs.count(UserBB))
return false;
}
}
Added: llvm/trunk/test/Transforms/LCSSA/unreachable-use.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LCSSA/unreachable-use.ll?rev=98033&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LCSSA/unreachable-use.ll (added)
+++ llvm/trunk/test/Transforms/LCSSA/unreachable-use.ll Mon Mar 8 19:53:33 2010
@@ -0,0 +1,27 @@
+; RUN: opt < %s -lcssa -S -verify-loop-info | grep {\[%\]tmp33 = load i1\\*\\* \[%\]tmp}
+; PR6546
+
+; LCSSA doesn't need to transform uses in blocks not reachable
+; from the entry block.
+
+define fastcc void @dfs() nounwind {
+bb:
+ br label %bb44
+
+bb44:
+ br i1 undef, label %bb7, label %bb45
+
+bb7:
+ %tmp = bitcast i1** undef to i1**
+ br label %bb15
+
+bb15:
+ br label %bb44
+
+bb32:
+ %tmp33 = load i1** %tmp, align 8
+ br label %bb45
+
+bb45:
+ unreachable
+}
From sabre at nondot.org Mon Mar 8 19:58:53 2010
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 09 Mar 2010 01:58:53 -0000
Subject: [llvm-commits] [llvm] r98034 -
/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Message-ID: <20100309015853.E61222A6C12C@llvm.org>
Author: lattner
Date: Mon Mar 8 19:58:53 2010
New Revision: 98034
URL: http://llvm.org/viewvc/llvm-project?rev=98034&view=rev
Log:
change DbgScope to keep track of the start/end label as MCSymbol*
now that the dependence on ID is removed from MMI.
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=98034&r1=98033&r2=98034&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 8 19:58:53 2010
@@ -16,9 +16,10 @@
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
@@ -171,8 +172,8 @@
// Location at which this scope is inlined.
AssertingVH InlinedAtLocation;
bool AbstractScope; // Abstract Scope
- unsigned StartLabelID; // Label ID of the beginning of scope.
- unsigned EndLabelID; // Label ID of the end of scope.
+ MCSymbol *StartLabel; // Label ID of the beginning of scope.
+ MCSymbol *EndLabel; // Label ID of the end of scope.
const MachineInstr *LastInsn; // Last instruction of this scope.
const MachineInstr *FirstInsn; // First instruction of this scope.
SmallVector Scopes; // Scopes defined in scope.
@@ -183,7 +184,7 @@
public:
DbgScope(DbgScope *P, DIDescriptor D, MDNode *I = 0)
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false),
- StartLabelID(0), EndLabelID(0),
+ StartLabel(0), EndLabel(0),
LastInsn(0), FirstInsn(0), IndentLevel(0) {}
virtual ~DbgScope();
@@ -195,12 +196,12 @@
return InlinedAtLocation;
}
MDNode *getScopeNode() const { return Desc.getNode(); }
- unsigned getStartLabelID() const { return StartLabelID; }
- unsigned getEndLabelID() const { return EndLabelID; }
+ MCSymbol *getStartLabel() const { return StartLabel; }
+ MCSymbol *getEndLabel() const { return EndLabel; }
SmallVector &getScopes() { return Scopes; }
SmallVector &getVariables() { return Variables; }
- void setStartLabelID(unsigned S) { StartLabelID = S; }
- void setEndLabelID(unsigned E) { EndLabelID = E; }
+ void setStartLabel(MCSymbol *S) { StartLabel = S; }
+ void setEndLabel(MCSymbol *E) { EndLabel = E; }
void setLastInsn(const MachineInstr *MI) { LastInsn = MI; }
const MachineInstr *getLastInsn() { return LastInsn; }
void setFirstInsn(const MachineInstr *MI) { FirstInsn = MI; }
@@ -264,7 +265,7 @@
err.indent(IndentLevel);
MDNode *N = Desc.getNode();
N->dump();
- err << " [" << StartLabelID << ", " << EndLabelID << "]\n";
+ err << " [" << StartLabel << ", " << EndLabel << "]\n";
if (AbstractScope)
err << "Abstract Scope\n";
@@ -1362,24 +1363,20 @@
/// constructLexicalScope - Construct new DW_TAG_lexical_block
/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
- unsigned StartID = Scope->getStartLabelID();
- unsigned EndID = Scope->getEndLabelID();
+ MCSymbol *Start = Scope->getStartLabel();
+ MCSymbol *End = Scope->getEndLabel();
- assert(!MMI->isLabelDeleted(StartID) &&
- "Invalid starting label for an inlined scope!");
- assert(!MMI->isLabelDeleted(EndID) &&
- "Invalid end label for an inlined scope!");
+ assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
+ assert(End->isDefined() && "Invalid end label for an inlined scope!");
DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
if (Scope->isAbstractScope())
return ScopeDIE;
addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- StartID ? getDWLabel("label", StartID)
- : getDWLabel("func_begin", SubprogramCount));
+ Start ? Start : getDWLabel("func_begin", SubprogramCount));
addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- EndID ? getDWLabel("label", EndID)
- : getDWLabel("func_end", SubprogramCount));
+ End ? End : getDWLabel("func_end", SubprogramCount));
return ScopeDIE;
}
@@ -1388,11 +1385,11 @@
/// a function. Construct DIE to represent this concrete inlined copy
/// of the function.
DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
- unsigned StartID = Scope->getStartLabelID();
- unsigned EndID = Scope->getEndLabelID();
- assert(!MMI->isLabelDeleted(StartID) &&
+ MCSymbol *StartLabel = Scope->getStartLabel();
+ MCSymbol *EndLabel = Scope->getEndLabel();
+ assert(StartLabel->isDefined() &&
"Invalid starting label for an inlined scope!");
- assert(!MMI->isLabelDeleted(EndID) &&
+ assert(EndLabel->isDefined() &&
"Invalid end label for an inlined scope!");
if (!Scope->getScopeNode())
return NULL;
@@ -1405,11 +1402,8 @@
addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin,
dwarf::DW_FORM_ref4, OriginDIE);
- MCSymbol *StartLabel = getDWLabel("label", StartID);
-
addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel);
- addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- getDWLabel("label", EndID));
+ addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel);
InlinedSubprogramDIEs.insert(OriginDIE);
@@ -1961,7 +1955,7 @@
ScopeVector &SD = I->second;
for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end();
SDI != SDE; ++SDI)
- (*SDI)->setStartLabelID(Label);
+ (*SDI)->setStartLabel(getDWLabel("label", Label));
}
/// endScope - Process end of a scope.
@@ -1970,13 +1964,13 @@
if (I == DbgScopeEndMap.end())
return;
- unsigned Label = MMI->NextLabelID();
- Asm->printLabel(Label);
+ MCSymbol *Label = getDWLabel("label", MMI->NextLabelID());
+ Asm->OutStreamer.EmitLabel(Label);
- SmallVector &SD = I->second;
+ SmallVector &SD = I->second;
for (SmallVector::iterator SDI = SD.begin(), SDE = SD.end();
SDI != SDE; ++SDI)
- (*SDI)->setEndLabelID(Label);
+ (*SDI)->setEndLabel(Label);
return;
}
@@ -2120,16 +2114,17 @@
DebugLoc FDL = MF->getDefaultDebugLoc();
if (!FDL.isUnknown()) {
DILocation DLT = MF->getDILocation(FDL);
- unsigned LabelID = 0;
DISubprogram SP = getDISubprogram(DLT.getScope().getNode());
- if (SP.Verify())
- LabelID = recordSourceLine(SP.getLineNumber(), 0,
- DLT.getScope().getNode());
- else
- LabelID = recordSourceLine(DLT.getLineNumber(),
- DLT.getColumnNumber(),
- DLT.getScope().getNode());
- Asm->printLabel(LabelID);
+ unsigned Line, Col;
+ if (SP.Verify()) {
+ Line = SP.getLineNumber();
+ Col = 0;
+ } else {
+ Line = DLT.getLineNumber();
+ Col = DLT.getColumnNumber();
+ }
+
+ Asm->printLabel(recordSourceLine(Line, Col, DLT.getScope().getNode()));
}
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
From sabre at nondot.org Mon Mar 8 20:08:02 2010
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 09 Mar 2010 02:08:02 -0000
Subject: [llvm-commits] [llvm] r98035 - in /llvm/trunk:
include/llvm/CodeGen/DwarfWriter.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/CodeGen/AsmPrinter/DwarfWriter.cpp
Message-ID: <20100309020802.A8D122A6C12C@llvm.org>
Author: lattner
Date: Mon Mar 8 20:08:02 2010
New Revision: 98035
URL: http://llvm.org/viewvc/llvm-project?rev=98035&view=rev
Log:
Now that setStartLabel takes an MCSymbol, we can de-ID'ize
beginScope and RecordSourceLine.
Modified:
llvm/trunk/include/llvm/CodeGen/DwarfWriter.h
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=98035&r1=98034&r2=98035&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Mon Mar 8 20:08:02 2010
@@ -35,6 +35,7 @@
class Module;
class MDNode;
class MCAsmInfo;
+class MCSymbol;
class raw_ostream;
class Instruction;
class DICompileUnit;
@@ -82,10 +83,10 @@
///
void EndFunction(const MachineFunction *MF);
- /// RecordSourceLine - Register a source line with debug info. Returns a
- /// unique label ID used to generate a label and provide correspondence to
+ /// RecordSourceLine - Register a source line with debug info. Returns the
+ /// unique label that was emitted and which provides correspondence to
/// the source line list.
- unsigned RecordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
+ MCSymbol *RecordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
/// getRecordSourceLineCount - Count source lines.
unsigned getRecordSourceLineCount();
@@ -94,7 +95,7 @@
/// be emitted.
bool ShouldEmitDwarfDebug() const;
- void BeginScope(const MachineInstr *MI, unsigned Label);
+ void BeginScope(const MachineInstr *MI, MCSymbol *Label);
void EndScope(const MachineInstr *MI);
};
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=98035&r1=98034&r2=98035&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Mar 8 20:08:02 2010
@@ -1319,10 +1319,9 @@
// After printing instruction
DW->EndScope(MI);
} else if (CurDLT.getNode() != PrevDLT) {
- unsigned L = DW->RecordSourceLine(CurDLT.getLineNumber(),
- CurDLT.getColumnNumber(),
- CurDLT.getScope().getNode());
- printLabel(L);
+ MCSymbol *L = DW->RecordSourceLine(CurDLT.getLineNumber(),
+ CurDLT.getColumnNumber(),
+ CurDLT.getScope().getNode());
DW->BeginScope(MI, L);
PrevDLT = CurDLT.getNode();
}
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=98035&r1=98034&r2=98035&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 8 20:08:02 2010
@@ -1948,14 +1948,14 @@
}
/// beginScope - Process beginning of a scope starting at Label.
-void DwarfDebug::beginScope(const MachineInstr *MI, unsigned Label) {
+void DwarfDebug::beginScope(const MachineInstr *MI, MCSymbol *Label) {
InsnToDbgScopeMapTy::iterator I = DbgScopeBeginMap.find(MI);
if (I == DbgScopeBeginMap.end())
return;
ScopeVector &SD = I->second;
for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end();
SDI != SDE; ++SDI)
- (*SDI)->setStartLabel(getDWLabel("label", Label));
+ (*SDI)->setStartLabel(Label);
}
/// endScope - Process end of a scope.
@@ -2124,7 +2124,7 @@
Col = DLT.getColumnNumber();
}
- Asm->printLabel(recordSourceLine(Line, Col, DLT.getScope().getNode()));
+ recordSourceLine(Line, Col, DLT.getScope().getNode());
}
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
@@ -2180,11 +2180,10 @@
DebugTimer->stopTimer();
}
-/// recordSourceLine - Records location information and associates it with a
-/// label. Returns a unique label ID used to generate a label and provide
-/// correspondence to the source line list.
-unsigned DwarfDebug::recordSourceLine(unsigned Line, unsigned Col,
- MDNode *S) {
+/// recordSourceLine - Register a source line with debug info. Returns the
+/// unique label that was emitted and which provides correspondence to
+/// the source line list.
+MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
if (!MMI)
return 0;
@@ -2217,7 +2216,9 @@
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
- return ID;
+ MCSymbol *Label = getDWLabel("label", ID);
+ Asm->OutStreamer.EmitLabel(Label);
+ return Label;
}
/// getOrCreateSourceID - Public version of GetOrCreateSourceID. This can be
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=98035&r1=98034&r2=98035&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Mon Mar 8 20:08:02 2010
@@ -512,10 +512,10 @@
///
void endFunction(const MachineFunction *MF);
- /// recordSourceLine - Records location information and associates it with a
- /// label. Returns a unique label ID used to generate a label and provide
- /// correspondence to the source line list.
- unsigned recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
+ /// recordSourceLine - Register a source line with debug info. Returns the
+ /// unique label that was emitted and which provides correspondence to
+ /// the source line list.
+ MCSymbol *recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
/// getSourceLineCount - Return the number of source lines in the debug
/// info.
@@ -539,7 +539,7 @@
void collectVariableInfo();
/// beginScope - Process beginning of a scope starting at Label.
- void beginScope(const MachineInstr *MI, unsigned Label);
+ void beginScope(const MachineInstr *MI, MCSymbol *Label);
/// endScope - Prcess end of a scope.
void endScope(const MachineInstr *MI);
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=98035&r1=98034&r2=98035&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Mon Mar 8 20:08:02 2010
@@ -73,11 +73,11 @@
MMI->EndFunction();
}
-/// RecordSourceLine - Records location information and associates it with a
-/// label. Returns a unique label ID used to generate a label and provide
-/// correspondence to the source line list.
-unsigned DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
- MDNode *Scope) {
+/// RecordSourceLine - Register a source line with debug info. Returns the
+/// unique label that was emitted and which provides correspondence to
+/// the source line list.
+MCSymbol *DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
+ MDNode *Scope) {
return DD->recordSourceLine(Line, Col, Scope);
}
@@ -92,7 +92,7 @@
return DD && DD->ShouldEmitDwarfDebug();
}
-void DwarfWriter::BeginScope(const MachineInstr *MI, unsigned L) {
+void DwarfWriter::BeginScope(const MachineInstr *MI, MCSymbol *L) {
DD->beginScope(MI, L);
}
void DwarfWriter::EndScope(const MachineInstr *MI) {
From gohman at apple.com Mon Mar 8 20:15:05 2010
From: gohman at apple.com (Dan Gohman)
Date: Tue, 09 Mar 2010 02:15:05 -0000
Subject: [llvm-commits] [llvm] r98036 -
/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Message-ID: <20100309021505.D57DC2A6C12C@llvm.org>
Author: djg
Date: Mon Mar 8 20:15:05 2010
New Revision: 98036
URL: http://llvm.org/viewvc/llvm-project?rev=98036&view=rev
Log:
Attempt to make this debug output meaningful, both in the case of
multibyte opcodes and in the case of multiple scopes.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=98036&r1=98035&r2=98036&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Mar 8 20:15:05 2010
@@ -2141,6 +2141,9 @@
while (1) {
assert(MatcherIndex < TableSize && "Invalid index");
+#ifndef NDEBUG
+ unsigned CurrentOpcodeIndex = MatcherIndex;
+#endif
BuiltinOpcodes Opcode = (BuiltinOpcodes)MatcherTable[MatcherIndex++];
switch (Opcode) {
case OPC_Scope: {
@@ -2666,6 +2669,7 @@
// If the code reached this point, then the match failed. See if there is
// another child to try in the current 'Scope', otherwise pop it until we
// find a case to check.
+ DEBUG(errs() << " Match failed at index " << CurrentOpcodeIndex << "\n");
while (1) {
if (MatchScopes.empty()) {
CannotYetSelect(NodeToMatch);
@@ -2680,13 +2684,12 @@
NodeStack.append(LastScope.NodeStack.begin(), LastScope.NodeStack.end());
N = NodeStack.back();
- DEBUG(errs() << " Match failed at index " << (MatcherIndex-1)
- << " continuing at " << LastScope.FailIndex << "\n");
-
if (LastScope.NumMatchedMemRefs != MatchedMemRefs.size())
MatchedMemRefs.resize(LastScope.NumMatchedMemRefs);
MatcherIndex = LastScope.FailIndex;
+ DEBUG(errs() << " Continuing at " << MatcherIndex << "\n");
+
InputChain = LastScope.InputChain;
InputFlag = LastScope.InputFlag;
if (!LastScope.HasChainNodesMatched)
From echristo at apple.com Mon Mar 8 20:36:31 2010
From: echristo at apple.com (Eric Christopher)
Date: Tue, 09 Mar 2010 02:36:31 -0000
Subject: [llvm-commits] [llvm] r98039 - in /llvm/trunk:
include/llvm/CodeGen/DwarfWriter.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/CodeGen/AsmPrinter/DwarfWriter.cpp
Message-ID: <20100309023631.A699B2A6C12C@llvm.org>
Author: echristo
Date: Mon Mar 8 20:36:31 2010
New Revision: 98039
URL: http://llvm.org/viewvc/llvm-project?rev=98039&view=rev
Log:
Speculatively revert r98035. It appears to have caused a set of buildbot
failures.
Modified:
llvm/trunk/include/llvm/CodeGen/DwarfWriter.h
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=98039&r1=98038&r2=98039&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Mon Mar 8 20:36:31 2010
@@ -35,7 +35,6 @@
class Module;
class MDNode;
class MCAsmInfo;
-class MCSymbol;
class raw_ostream;
class Instruction;
class DICompileUnit;
@@ -83,10 +82,10 @@
///
void EndFunction(const MachineFunction *MF);
- /// RecordSourceLine - Register a source line with debug info. Returns the
- /// unique label that was emitted and which provides correspondence to
+ /// RecordSourceLine - Register a source line with debug info. Returns a
+ /// unique label ID used to generate a label and provide correspondence to
/// the source line list.
- MCSymbol *RecordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
+ unsigned RecordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
/// getRecordSourceLineCount - Count source lines.
unsigned getRecordSourceLineCount();
@@ -95,7 +94,7 @@
/// be emitted.
bool ShouldEmitDwarfDebug() const;
- void BeginScope(const MachineInstr *MI, MCSymbol *Label);
+ void BeginScope(const MachineInstr *MI, unsigned Label);
void EndScope(const MachineInstr *MI);
};
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=98039&r1=98038&r2=98039&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Mar 8 20:36:31 2010
@@ -1319,9 +1319,10 @@
// After printing instruction
DW->EndScope(MI);
} else if (CurDLT.getNode() != PrevDLT) {
- MCSymbol *L = DW->RecordSourceLine(CurDLT.getLineNumber(),
- CurDLT.getColumnNumber(),
- CurDLT.getScope().getNode());
+ unsigned L = DW->RecordSourceLine(CurDLT.getLineNumber(),
+ CurDLT.getColumnNumber(),
+ CurDLT.getScope().getNode());
+ printLabel(L);
DW->BeginScope(MI, L);
PrevDLT = CurDLT.getNode();
}
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=98039&r1=98038&r2=98039&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 8 20:36:31 2010
@@ -1948,14 +1948,14 @@
}
/// beginScope - Process beginning of a scope starting at Label.
-void DwarfDebug::beginScope(const MachineInstr *MI, MCSymbol *Label) {
+void DwarfDebug::beginScope(const MachineInstr *MI, unsigned Label) {
InsnToDbgScopeMapTy::iterator I = DbgScopeBeginMap.find(MI);
if (I == DbgScopeBeginMap.end())
return;
ScopeVector &SD = I->second;
for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end();
SDI != SDE; ++SDI)
- (*SDI)->setStartLabel(Label);
+ (*SDI)->setStartLabel(getDWLabel("label", Label));
}
/// endScope - Process end of a scope.
@@ -2124,7 +2124,7 @@
Col = DLT.getColumnNumber();
}
- recordSourceLine(Line, Col, DLT.getScope().getNode());
+ Asm->printLabel(recordSourceLine(Line, Col, DLT.getScope().getNode()));
}
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
@@ -2180,10 +2180,11 @@
DebugTimer->stopTimer();
}
-/// recordSourceLine - Register a source line with debug info. Returns the
-/// unique label that was emitted and which provides correspondence to
-/// the source line list.
-MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
+/// recordSourceLine - Records location information and associates it with a
+/// label. Returns a unique label ID used to generate a label and provide
+/// correspondence to the source line list.
+unsigned DwarfDebug::recordSourceLine(unsigned Line, unsigned Col,
+ MDNode *S) {
if (!MMI)
return 0;
@@ -2216,9 +2217,7 @@
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
- MCSymbol *Label = getDWLabel("label", ID);
- Asm->OutStreamer.EmitLabel(Label);
- return Label;
+ return ID;
}
/// getOrCreateSourceID - Public version of GetOrCreateSourceID. This can be
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=98039&r1=98038&r2=98039&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Mon Mar 8 20:36:31 2010
@@ -512,10 +512,10 @@
///
void endFunction(const MachineFunction *MF);
- /// recordSourceLine - Register a source line with debug info. Returns the
- /// unique label that was emitted and which provides correspondence to
- /// the source line list.
- MCSymbol *recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
+ /// recordSourceLine - Records location information and associates it with a
+ /// label. Returns a unique label ID used to generate a label and provide
+ /// correspondence to the source line list.
+ unsigned recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
/// getSourceLineCount - Return the number of source lines in the debug
/// info.
@@ -539,7 +539,7 @@
void collectVariableInfo();
/// beginScope - Process beginning of a scope starting at Label.
- void beginScope(const MachineInstr *MI, MCSymbol *Label);
+ void beginScope(const MachineInstr *MI, unsigned Label);
/// endScope - Prcess end of a scope.
void endScope(const MachineInstr *MI);
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=98039&r1=98038&r2=98039&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Mon Mar 8 20:36:31 2010
@@ -73,11 +73,11 @@
MMI->EndFunction();
}
-/// RecordSourceLine - Register a source line with debug info. Returns the
-/// unique label that was emitted and which provides correspondence to
-/// the source line list.
-MCSymbol *DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
- MDNode *Scope) {
+/// RecordSourceLine - Records location information and associates it with a
+/// label. Returns a unique label ID used to generate a label and provide
+/// correspondence to the source line list.
+unsigned DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
+ MDNode *Scope) {
return DD->recordSourceLine(Line, Col, Scope);
}
@@ -92,7 +92,7 @@
return DD && DD->ShouldEmitDwarfDebug();
}
-void DwarfWriter::BeginScope(const MachineInstr *MI, MCSymbol *L) {
+void DwarfWriter::BeginScope(const MachineInstr *MI, unsigned L) {
DD->beginScope(MI, L);
}
void DwarfWriter::EndScope(const MachineInstr *MI) {
From isanbard at gmail.com Mon Mar 8 20:46:12 2010
From: isanbard at gmail.com (Bill Wendling)
Date: Tue, 09 Mar 2010 02:46:12 -0000
Subject: [llvm-commits] [llvm] r98040 -
/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
Message-ID: <20100309024612.ED6212A6C12C@llvm.org>
Author: void
Date: Mon Mar 8 20:46:12 2010
New Revision: 98040
URL: http://llvm.org/viewvc/llvm-project?rev=98040&view=rev
Log:
This is part of an LLC-beta test used to test . Please
bear with the awful code. It won't last in its current state beyond tonight.
Modified:
llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=98040&r1=98039&r2=98040&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Mar 8 20:46:12 2010
@@ -37,14 +37,20 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/MC/MCSectionMachO.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include
using namespace llvm;
+using namespace dwarf;
+
+static cl::opt EnableARMEHTest("enable-arm-eh-test", cl::Hidden,
+ cl::desc("Enable ARM EH Test"));
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
CCValAssign::LocInfo &LocInfo,
@@ -128,9 +134,33 @@
addTypeForNEON(VT, MVT::v2f64, MVT::v4i32);
}
+namespace llvm {
+
+ // FIXME: This is a test of .
+ class ARMMachOTargetObjectFile : public TargetLoweringObjectFileMachO {
+ public:
+ virtual void Initialize(MCContext &Ctx, const TargetMachine &TM) {
+ TargetLoweringObjectFileMachO::Initialize(Ctx, TM);
+
+ // Exception Handling.
+ LSDASection = getMachOSection("__TEXT", "__gcc_except_tab", 0,
+ SectionKind::getReadOnlyWithRel());
+ }
+
+ virtual unsigned getTTypeEncoding() const {
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ }
+ };
+
+}
+
static TargetLoweringObjectFile *createTLOF(TargetMachine &TM) {
if (TM.getSubtarget().isTargetDarwin())
- return new TargetLoweringObjectFileMachO();
+ if (EnableARMEHTest)
+ return new ARMMachOTargetObjectFile();
+ else
+ return new TargetLoweringObjectFileMachO();
+
return new ARMElfTargetObjectFile();
}
From isanbard at gmail.com Mon Mar 8 20:46:47 2010
From: isanbard at gmail.com (Bill Wendling)
Date: Tue, 09 Mar 2010 02:46:47 -0000
Subject: [llvm-commits] [test-suite] r98041 -
/test-suite/trunk/Makefile.programs
Message-ID: <20100309024647.9DD282A6C12C@llvm.org>
Author: void
Date: Mon Mar 8 20:46:47 2010
New Revision: 98041
URL: http://llvm.org/viewvc/llvm-project?rev=98041&view=rev
Log:
Enable LLC-beta test for ARM EH test.
Modified:
test-suite/trunk/Makefile.programs
Modified: test-suite/trunk/Makefile.programs
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=98041&r1=98040&r2=98041&view=diff
==============================================================================
--- test-suite/trunk/Makefile.programs (original)
+++ test-suite/trunk/Makefile.programs Mon Mar 8 20:46:47 2010
@@ -241,7 +241,8 @@
LLCBETAOPTION := -enable-sparc-v9-insts
endif
ifeq ($(ARCH),ARM)
-LLCBETAOPTION := -enable-machine-cse
+LLCBETAOPTION := -enable-arm-eh-test
+# -enable-machine-cse
endif
ifeq ($(ARCH),THUMB)
LLCBETAOPTION := -enable-machine-cse
From evan.cheng at apple.com Mon Mar 8 20:53:20 2010
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 8 Mar 2010 18:53:20 -0800
Subject: [llvm-commits] [llvm] r98007 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
In-Reply-To: <20FB2BBD-9306-4DD8-961E-A627EE6A2FD2@apple.com>
References: <20100308232808.91F8F2A6C12C@llvm.org>
<12195ADE-5620-4756-8425-E09F73A9646D@2pi.dk>
<20FB2BBD-9306-4DD8-961E-A627EE6A2FD2@apple.com>
Message-ID:
On Mar 8, 2010, at 5:23 PM, Evan Cheng wrote:
>
> On Mar 8, 2010, at 4:57 PM, Jakob Stoklund Olesen wrote:
>
>>
>> On Mar 8, 2010, at 3:28 PM, Evan Cheng wrote:
>>
>>> Author: evancheng
>>> Date: Mon Mar 8 17:28:08 2010
>>> New Revision: 98007
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=98007&view=rev
>>> Log:
>>> Restrict machine cse to really trivial coalescing. Leave the heavy lifting to a real coalescer.
>>>
>>> Modified:
>>> llvm/trunk/lib/CodeGen/MachineCSE.cpp
>>>
>>> Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=98007&r1=98006&r2=98007&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
>>> +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Mon Mar 8 17:28:08 2010
>>> @@ -91,7 +91,10 @@
>>> unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
>>> if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
>>> TargetRegisterInfo::isVirtualRegister(SrcReg) &&
>>> + MRI->getRegClass(SrcReg) == MRI->getRegClass(Reg) &&
>>> !SrcSubIdx && !DstSubIdx) {
>>> + DEBUG(dbgs() << "Coalescing: " << *DefMI);
>>> + DEBUG(dbgs() << "*** to: " << *MI);
>>> MO.setReg(SrcReg);
>>> DefMI->eraseFromParent();
>>> ++NumCoalesces;
>>
>> You could add "|| MRI->getRegClass(Reg)->hasSubClass(MRI->getRegClass(SrcReg))" without getting too complicated. That could help a bit with the few x86_64 subclasses as well.
>>
>
> I don't think it's necessary here. It's doing local coalescing here to avoid missing some obvious cse opportunities. If sub-reg class is involved, then it's already too complicated.
Actually I do need to make it more complicated. But then BlackFin hates me (I wonder if it's related to its author).
Evan
>
> Evan
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From xuzhongxing at gmail.com Mon Mar 8 20:59:31 2010
From: xuzhongxing at gmail.com (Zhongxing Xu)
Date: Tue, 9 Mar 2010 10:59:31 +0800
Subject: [llvm-commits] [PATCH] remove redundant 'static'
In-Reply-To:
References: <5400aeb81003080445r3184c915j3c1471351f67d438@mail.gmail.com>
<5400aeb81003081705v1480ab04i1c8be003d2738b2e@mail.gmail.com>
Message-ID: <5400aeb81003081859m7ede3cbdr333ef6069ed533cc@mail.gmail.com>
2010/3/9 Chris Lattner :
>
> On Mar 8, 2010, at 5:05 PM, Zhongxing Xu wrote:
>
>> 2010/3/9 Chris Lattner :
>>>
>>> On Mar 8, 2010, at 4:45 AM, Zhongxing Xu wrote:
>>>
>>>> 'static' is redundant in this context:
>>>
>>> Um, no it's not. ?It prevents exporting the symbol from the .o file. ?What are you trying to fix?
>>>
>>
>> 'const' in namespace scope implies internal linkage. Is that
>> sufficient to prevent exporting the symbol from the .o file?
>
> It could be, but why do this? ?What does it fix? ?IMO, static is a lot less subtle.
I think it makes the code more concise. But never mind. It does not
fix anything real.
From gohman at apple.com Mon Mar 8 21:01:40 2010
From: gohman at apple.com (Dan Gohman)
Date: Tue, 09 Mar 2010 03:01:40 -0000
Subject: [llvm-commits] [llvm] r98042 -
/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
Message-ID: <20100309030140.66F632A6C12C@llvm.org>
Author: djg
Date: Mon Mar 8 21:01:40 2010
New Revision: 98042
URL: http://llvm.org/viewvc/llvm-project?rev=98042&view=rev
Log:
Don't try to fold V_SET0 and V_SETALLONES to loads in medium and
large code models.
Modified:
llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=98042&r1=98041&r2=98042&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Mar 8 21:01:40 2010
@@ -2525,6 +2525,11 @@
// Folding a V_SET0 or V_SETALLONES as a load, to ease register pressure.
// Create a constant-pool entry and operands to load from it.
+ // Medium and large mode can't fold loads this way.
+ if (TM.getCodeModel() != CodeModel::Small &&
+ TM.getCodeModel() != CodeModel::Kernel)
+ return NULL;
+
// x86-32 PIC requires a PIC base register for constant pools.
unsigned PICBase = 0;
if (TM.getRelocationModel() == Reloc::PIC_) {
From stoklund at 2pi.dk Mon Mar 8 21:14:31 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Mon, 8 Mar 2010 19:14:31 -0800
Subject: [llvm-commits] [llvm] r98007 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
In-Reply-To:
References: <20100308232808.91F8F2A6C12C@llvm.org>
<12195ADE-5620-4756-8425-E09F73A9646D@2pi.dk>
<20FB2BBD-9306-4DD8-961E-A627EE6A2FD2@apple.com>
Message-ID:
On Mar 8, 2010, at 6:53 PM, Evan Cheng wrote:
>
> On Mar 8, 2010, at 5:23 PM, Evan Cheng wrote:
>
>>
>> On Mar 8, 2010, at 4:57 PM, Jakob Stoklund Olesen wrote:
>>
>>>
>>> You could add "|| MRI->getRegClass(Reg)->hasSubClass(MRI->getRegClass(SrcReg))" without getting too complicated. That could help a bit with the few x86_64 subclasses as well.
>>>
>>
>> I don't think it's necessary here. It's doing local coalescing here to avoid missing some obvious cse opportunities. If sub-reg class is involved, then it's already too complicated.
>
> Actually I do need to make it more complicated. But then BlackFin hates me (I wonder if it's related to its author).
Hehe. Blackfin not hating you is a good sign that you got your register classes right ;-)
Basic register class algebra: If an instruction operand specifies register class X, a virtual register must belong to X or a subclass of X.
If you want to eliminate a copy "%x = mov %y", the resulting register must make the users of %x and %y happy at the same time. That means the new register must belong to the intersection of X and Y, the register classes of %x and %y.
The function getCommonSubClass(X, Y) finds the largest existing register class that is a subclass of both X and Y. If getCommonSubClass returns NULL, the classes are disjoint, and you cannot eliminate the copy - no register would be legal.
I think Blackfin is the only target with disjoint register classes - maybe that is why it hates you.
From evan.cheng at apple.com Mon Mar 8 21:17:25 2010
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 8 Mar 2010 19:17:25 -0800
Subject: [llvm-commits] [llvm] r98007 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
In-Reply-To:
References: <20100308232808.91F8F2A6C12C@llvm.org>
<12195ADE-5620-4756-8425-E09F73A9646D@2pi.dk>
<20FB2BBD-9306-4DD8-961E-A627EE6A2FD2@apple.com>
Message-ID:
On Mar 8, 2010, at 7:14 PM, Jakob Stoklund Olesen wrote:
>
> On Mar 8, 2010, at 6:53 PM, Evan Cheng wrote:
>
>>
>> On Mar 8, 2010, at 5:23 PM, Evan Cheng wrote:
>>
>>>
>>> On Mar 8, 2010, at 4:57 PM, Jakob Stoklund Olesen wrote:
>>>
>>>>
>>>> You could add "|| MRI->getRegClass(Reg)->hasSubClass(MRI->getRegClass(SrcReg))" without getting too complicated. That could help a bit with the few x86_64 subclasses as well.
>>>>
>>>
>>> I don't think it's necessary here. It's doing local coalescing here to avoid missing some obvious cse opportunities. If sub-reg class is involved, then it's already too complicated.
>>
>> Actually I do need to make it more complicated. But then BlackFin hates me (I wonder if it's related to its author).
>
> Hehe. Blackfin not hating you is a good sign that you got your register classes right ;-)
>
> Basic register class algebra: If an instruction operand specifies register class X, a virtual register must belong to X or a subclass of X.
>
> If you want to eliminate a copy "%x = mov %y", the resulting register must make the users of %x and %y happy at the same time. That means the new register must belong to the intersection of X and Y, the register classes of %x and %y.
>
> The function getCommonSubClass(X, Y) finds the largest existing register class that is a subclass of both X and Y. If getCommonSubClass returns NULL, the classes are disjoint, and you cannot eliminate the copy - no register would be legal.
>
> I think Blackfin is the only target with disjoint register classes - maybe that is why it hates you.
I don't think that's the issue here. For example, 2009-08-15-LiveIn-SubReg.ll:
Coalescing: %reg1031 = MOVE %reg1028
*** to: %reg1030 = SETEQdd %reg1027, %reg1031
*** Bad machine code: Illegal virtual register for instruction ***
- function: foo
- basic block: entry 0x2036ee4 (BB#0)
- instruction: %reg1030 = SETEQdd %reg1027, %reg1028
- operand 2: %reg1028
Expected a D register, but got a GR register
I'm going to commit my changes to machine cse (which is not turned on yet). Can you take a look at it? Thanks.
Evan
>
>
From evan.cheng at apple.com Mon Mar 8 21:21:12 2010
From: evan.cheng at apple.com (Evan Cheng)
Date: Tue, 09 Mar 2010 03:21:12 -0000
Subject: [llvm-commits] [llvm] r98043 - in /llvm/trunk/lib/CodeGen:
LLVMTargetMachine.cpp MachineCSE.cpp
Message-ID: <20100309032112.894672A6C12C@llvm.org>
Author: evancheng
Date: Mon Mar 8 21:21:12 2010
New Revision: 98043
URL: http://llvm.org/viewvc/llvm-project?rev=98043&view=rev
Log:
- Make the machine cse dumb coalescer (as opposed to the more awesome simple
coalescer) handle sub-register classes.
- Add heuristics to avoid non-profitable cse. Given the current lack of live
range splitting, avoid cse when an expression has PHI use and the would be
new use is in a BB where the expression wasn't already being used.
Modified:
llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
llvm/trunk/lib/CodeGen/MachineCSE.cpp
Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=98043&r1=98042&r2=98043&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)
+++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Mon Mar 8 21:21:12 2010
@@ -328,11 +328,11 @@
PM.add(createOptimizeExtsPass());
if (!DisableMachineLICM)
PM.add(createMachineLICMPass());
- if (EnableMachineCSE)
+ //if (EnableMachineCSE)
PM.add(createMachineCSEPass());
if (!DisableMachineSink)
PM.add(createMachineSinkingPass());
- printAndVerify(PM, "After MachineLICM and MachineSinking",
+ printAndVerify(PM, "After Machine LICM, CSE and Sinking passes",
/* allowDoubleDefs= */ true);
}
Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=98043&r1=98042&r2=98043&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Mon Mar 8 21:21:12 2010
@@ -33,9 +33,9 @@
class MachineCSE : public MachineFunctionPass {
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
- MachineRegisterInfo *MRI;
- MachineDominatorTree *DT;
AliasAnalysis *AA;
+ MachineDominatorTree *DT;
+ MachineRegisterInfo *MRI;
public:
static char ID; // Pass identification
MachineCSE() : MachineFunctionPass(&ID), CurrVN(0) {}
@@ -61,6 +61,7 @@
MachineBasicBlock::const_iterator E);
bool hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB);
bool isCSECandidate(MachineInstr *MI);
+ bool isProfitableToCSE(unsigned Reg, MachineInstr *MI);
bool ProcessBlock(MachineDomTreeNode *Node);
};
} // end anonymous namespace
@@ -91,14 +92,17 @@
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
TargetRegisterInfo::isVirtualRegister(SrcReg) &&
- MRI->getRegClass(SrcReg) == MRI->getRegClass(Reg) &&
!SrcSubIdx && !DstSubIdx) {
- DEBUG(dbgs() << "Coalescing: " << *DefMI);
- DEBUG(dbgs() << "*** to: " << *MI);
- MO.setReg(SrcReg);
- DefMI->eraseFromParent();
- ++NumCoalesces;
- Changed = true;
+ const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
+ const TargetRegisterClass *RC = MRI->getRegClass(Reg);
+ if (SRC == RC || SRC->hasSubClass(RC) || RC->hasSubClass(SRC)) {
+ DEBUG(dbgs() << "Coalescing: " << *DefMI);
+ DEBUG(dbgs() << "*** to: " << *MI);
+ MO.setReg(SrcReg);
+ DefMI->eraseFromParent();
+ ++NumCoalesces;
+ Changed = true;
+ }
}
}
@@ -201,9 +205,31 @@
return true;
}
+/// isProfitableToCSE - Return true if it's profitable to eliminate MI with a
+/// common expression that defines Reg.
+bool MachineCSE::isProfitableToCSE(unsigned Reg, MachineInstr *MI) {
+ // FIXME: This "heuristic" works around the lack the live range splitting.
+ // If the common subexpression is used by PHIs, do not reuse it unless the
+ // defined value is already used in the BB of the new use.
+ bool HasPHI = false;
+ SmallPtrSet CSBBs;
+ for (MachineRegisterInfo::use_nodbg_iterator I =
+ MRI->use_nodbg_begin(Reg),
+ E = MRI->use_nodbg_end(); I != E; ++I) {
+ MachineInstr *Use = &*I;
+ HasPHI |= Use->isPHI();
+ CSBBs.insert(Use->getParent());
+ }
+
+ if (!HasPHI)
+ return true;
+ return CSBBs.count(MI->getParent());
+}
+
bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
bool Changed = false;
+ SmallVector, 8> CSEPairs;
ScopedHashTableScope VNTS(VNT);
MachineBasicBlock *MBB = Node->getBlock();
@@ -238,6 +264,9 @@
MachineInstr *CSMI = Exps[CSVN];
DEBUG(dbgs() << "Examining: " << *MI);
DEBUG(dbgs() << "*** Found a common subexpression: " << *CSMI);
+
+ // Check if it's profitable to perform this CSE.
+ bool DoCSE = true;
unsigned NumDefs = MI->getDesc().getNumDefs();
for (unsigned i = 0, e = MI->getNumOperands(); NumDefs && i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
@@ -250,11 +279,26 @@
assert(TargetRegisterInfo::isVirtualRegister(OldReg) &&
TargetRegisterInfo::isVirtualRegister(NewReg) &&
"Do not CSE physical register defs!");
- MRI->replaceRegWith(OldReg, NewReg);
+ if (!isProfitableToCSE(NewReg, MI)) {
+ DoCSE = false;
+ break;
+ }
+ CSEPairs.push_back(std::make_pair(OldReg, NewReg));
--NumDefs;
}
- MI->eraseFromParent();
- ++NumCSEs;
+
+ // Actually perform the elimination.
+ if (DoCSE) {
+ for (unsigned i = 0, e = CSEPairs.size(); i != e; ++i)
+ MRI->replaceRegWith(CSEPairs[i].first, CSEPairs[i].second);
+ MI->eraseFromParent();
+ ++NumCSEs;
+ } else {
+ DEBUG(dbgs() << "*** Not profitable, avoid CSE!\n");
+ VNT.insert(MI, CurrVN++);
+ Exps.push_back(MI);
+ }
+ CSEPairs.clear();
}
// Recursively call ProcessBlock with childred.
@@ -269,7 +313,7 @@
TII = MF.getTarget().getInstrInfo();
TRI = MF.getTarget().getRegisterInfo();
MRI = &MF.getRegInfo();
- DT = &getAnalysis();
AA = &getAnalysis();
+ DT = &getAnalysis();
return ProcessBlock(DT->getRootNode());
}
From stoklund at 2pi.dk Mon Mar 8 21:29:56 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Mon, 8 Mar 2010 19:29:56 -0800
Subject: [llvm-commits] [llvm] r98007 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
In-Reply-To:
References: <20100308232808.91F8F2A6C12C@llvm.org>
<12195ADE-5620-4756-8425-E09F73A9646D@2pi.dk>
<20FB2BBD-9306-4DD8-961E-A627EE6A2FD2@apple.com>
Message-ID:
On Mar 8, 2010, at 7:17 PM, Evan Cheng wrote:
>
> On Mar 8, 2010, at 7:14 PM, Jakob Stoklund Olesen wrote:
>
>>
>> On Mar 8, 2010, at 6:53 PM, Evan Cheng wrote:
>>
>>>
>>> On Mar 8, 2010, at 5:23 PM, Evan Cheng wrote:
>>>
>>>>
>>>> On Mar 8, 2010, at 4:57 PM, Jakob Stoklund Olesen wrote:
>>>>
>>>>>
>>>>> You could add "|| MRI->getRegClass(Reg)->hasSubClass(MRI->getRegClass(SrcReg))" without getting too complicated. That could help a bit with the few x86_64 subclasses as well.
>>>>>
>>>>
>>>> I don't think it's necessary here. It's doing local coalescing here to avoid missing some obvious cse opportunities. If sub-reg class is involved, then it's already too complicated.
>>>
>>> Actually I do need to make it more complicated. But then BlackFin hates me (I wonder if it's related to its author).
>>
>> Hehe. Blackfin not hating you is a good sign that you got your register classes right ;-)
>>
>> Basic register class algebra: If an instruction operand specifies register class X, a virtual register must belong to X or a subclass of X.
>>
>> If you want to eliminate a copy "%x = mov %y", the resulting register must make the users of %x and %y happy at the same time. That means the new register must belong to the intersection of X and Y, the register classes of %x and %y.
>>
>> The function getCommonSubClass(X, Y) finds the largest existing register class that is a subclass of both X and Y. If getCommonSubClass returns NULL, the classes are disjoint, and you cannot eliminate the copy - no register would be legal.
>>
>> I think Blackfin is the only target with disjoint register classes - maybe that is why it hates you.
>
> I don't think that's the issue here. For example, 2009-08-15-LiveIn-SubReg.ll:
> Coalescing: %reg1031 = MOVE %reg1028
> *** to: %reg1030 = SETEQdd %reg1027, %reg1031
>
> *** Bad machine code: Illegal virtual register for instruction ***
> - function: foo
> - basic block: entry 0x2036ee4 (BB#0)
> - instruction: %reg1030 = SETEQdd %reg1027, %reg1028
> - operand 2: %reg1028
> Expected a D register, but got a GR register
Sure. D is a subclass of GR.
%reg1028 is GR
%reg1031 is D
When you coalesce the resulting register class should be getCommonSubClass(GR, D) = D, but you are using %reg1028 which is GR - too big.
The copy was probably created by InstrEmitter::AddRegisterOperand to make the register classes match.
> I'm going to commit my changes to machine cse (which is not turned on yet). Can you take a look at it? Thanks.
Sure.
From stoklund at 2pi.dk Mon Mar 8 21:41:25 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Mon, 8 Mar 2010 19:41:25 -0800
Subject: [llvm-commits] [llvm] r98043 - in /llvm/trunk/lib/CodeGen:
LLVMTargetMachine.cpp MachineCSE.cpp
In-Reply-To: <20100309032112.894672A6C12C@llvm.org>
References: <20100309032112.894672A6C12C@llvm.org>
Message-ID:
On Mar 8, 2010, at 7:21 PM, Evan Cheng wrote:
> @@ -91,14 +92,17 @@
> unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
> if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
> TargetRegisterInfo::isVirtualRegister(SrcReg) &&
> - MRI->getRegClass(SrcReg) == MRI->getRegClass(Reg) &&
> !SrcSubIdx && !DstSubIdx) {
> - DEBUG(dbgs() << "Coalescing: " << *DefMI);
> - DEBUG(dbgs() << "*** to: " << *MI);
> - MO.setReg(SrcReg);
> - DefMI->eraseFromParent();
> - ++NumCoalesces;
> - Changed = true;
> + const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
> + const TargetRegisterClass *RC = MRI->getRegClass(Reg);
> + if (SRC == RC || SRC->hasSubClass(RC) || RC->hasSubClass(SRC)) {
> + DEBUG(dbgs() << "Coalescing: " << *DefMI);
> + DEBUG(dbgs() << "*** to: " << *MI);
> + MO.setReg(SrcReg);
> + DefMI->eraseFromParent();
> + ++NumCoalesces;
> + Changed = true;
> + }
> }
> }
The case "SRC->hasSubClass(RC)" is not valid. MO requires an RC operand, and SRC is a larger register class. It may contain registers that are illegal for MO.
If you don't want to change the register class of SrcReg, you have to make do with:
> + if (SRC == RC || RC->hasSubClass(SRC)) {
If you are not afraid of switching register classes, you can go:
> + const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
> + const TargetRegisterClass *RC = MRI->getRegClass(Reg);
> + const TargetRegisterClass *NewRC = getCommonSubClass(SRC, RC);
> + if (NewRC) {
> + DEBUG(dbgs() << "Coalescing: " << *DefMI);
> + DEBUG(dbgs() << "*** to: " << *MI);
> + MO.setReg(SrcReg);
> + if (SRC != NewRC)
> + MRI->setRegClass(SrcReg, NewRC);
The problem with both approaches is that you are producing a longer live range of a smaller register class: Higher register pressure.
/jakob
From stoklund at 2pi.dk Mon Mar 8 21:56:06 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Tue, 09 Mar 2010 03:56:06 -0000
Subject: [llvm-commits] [llvm] r98044 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
Message-ID: <20100309035606.8AB922A6C12C@llvm.org>
Author: stoklund
Date: Mon Mar 8 21:56:06 2010
New Revision: 98044
URL: http://llvm.org/viewvc/llvm-project?rev=98044&view=rev
Log:
Don't do illegal cross-class coalescing.
Modified:
llvm/trunk/lib/CodeGen/MachineCSE.cpp
Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=98044&r1=98043&r2=98044&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Mon Mar 8 21:56:06 2010
@@ -95,7 +95,7 @@
!SrcSubIdx && !DstSubIdx) {
const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
const TargetRegisterClass *RC = MRI->getRegClass(Reg);
- if (SRC == RC || SRC->hasSubClass(RC) || RC->hasSubClass(SRC)) {
+ if (SRC == RC || RC->hasSubClass(SRC)) {
DEBUG(dbgs() << "Coalescing: " << *DefMI);
DEBUG(dbgs() << "*** to: " << *MI);
MO.setReg(SrcReg);
From evan.cheng at apple.com Mon Mar 8 22:04:38 2010
From: evan.cheng at apple.com (Evan Cheng)
Date: Tue, 09 Mar 2010 04:04:38 -0000
Subject: [llvm-commits] [llvm] r98045 -
/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
Message-ID: <20100309040438.D51592A6C12C@llvm.org>
Author: evancheng
Date: Mon Mar 8 22:04:38 2010
New Revision: 98045
URL: http://llvm.org/viewvc/llvm-project?rev=98045&view=rev
Log:
Revert accidental commit.
Modified:
llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=98045&r1=98044&r2=98045&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)
+++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Mon Mar 8 22:04:38 2010
@@ -328,7 +328,7 @@
PM.add(createOptimizeExtsPass());
if (!DisableMachineLICM)
PM.add(createMachineLICMPass());
- //if (EnableMachineCSE)
+ if (EnableMachineCSE)
PM.add(createMachineCSEPass());
if (!DisableMachineSink)
PM.add(createMachineSinkingPass());
From stoklund at 2pi.dk Mon Mar 8 22:10:06 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Mon, 8 Mar 2010 20:10:06 -0800
Subject: [llvm-commits] [llvm] r98044 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
In-Reply-To: <20100309035606.8AB922A6C12C@llvm.org>
References: <20100309035606.8AB922A6C12C@llvm.org>
Message-ID: <2C469486-A4A0-41C8-AE44-B5DBCD776042@2pi.dk>
On Mar 8, 2010, at 7:56 PM, Jakob Stoklund Olesen wrote:
> Author: stoklund
> Date: Mon Mar 8 21:56:06 2010
> New Revision: 98044
>
> URL: http://llvm.org/viewvc/llvm-project?rev=98044&view=rev
> Log:
> Don't do illegal cross-class coalescing.
>
> Modified:
> llvm/trunk/lib/CodeGen/MachineCSE.cpp
>
> Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=98044&r1=98043&r2=98044&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
> +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Mon Mar 8 21:56:06 2010
> @@ -95,7 +95,7 @@
> !SrcSubIdx && !DstSubIdx) {
> const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
> const TargetRegisterClass *RC = MRI->getRegClass(Reg);
> - if (SRC == RC || SRC->hasSubClass(RC) || RC->hasSubClass(SRC)) {
> + if (SRC == RC || RC->hasSubClass(SRC)) {
> DEBUG(dbgs() << "Coalescing: " << *DefMI);
> DEBUG(dbgs() << "*** to: " << *MI);
> MO.setReg(SrcReg);
That fixed the Blackfin failures. These remain:
LLVM :: CodeGen/ARM/indirectbr.ll
LLVM :: CodeGen/PowerPC/indirectbr.ll
LLVM :: CodeGen/Thumb/2009-08-20-ISelBug.ll
LLVM :: CodeGen/Thumb2/machine-licm.ll
LLVM :: CodeGen/X86/2007-10-16-IllegalAsm.ll
LLVM :: CodeGen/X86/coalesce-esp.ll
LLVM :: CodeGen/X86/pre-split6.ll
LLVM :: CodeGen/X86/stack-color-with-reg.ll
From evan.cheng at apple.com Mon Mar 8 22:14:57 2010
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 8 Mar 2010 20:14:57 -0800
Subject: [llvm-commits] [llvm] r98007 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
In-Reply-To:
References: <20100308232808.91F8F2A6C12C@llvm.org>
<12195ADE-5620-4756-8425-E09F73A9646D@2pi.dk>
<20FB2BBD-9306-4DD8-961E-A627EE6A2FD2@apple.com>
Message-ID:
On Mar 8, 2010, at 7:29 PM, Jakob Stoklund Olesen wrote:
>
> On Mar 8, 2010, at 7:17 PM, Evan Cheng wrote:
>
>>
>> On Mar 8, 2010, at 7:14 PM, Jakob Stoklund Olesen wrote:
>>
>>>
>>> On Mar 8, 2010, at 6:53 PM, Evan Cheng wrote:
>>>
>>>>
>>>> On Mar 8, 2010, at 5:23 PM, Evan Cheng wrote:
>>>>
>>>>>
>>>>> On Mar 8, 2010, at 4:57 PM, Jakob Stoklund Olesen wrote:
>>>>>
>>>>>>
>>>>>> You could add "|| MRI->getRegClass(Reg)->hasSubClass(MRI->getRegClass(SrcReg))" without getting too complicated. That could help a bit with the few x86_64 subclasses as well.
>>>>>>
>>>>>
>>>>> I don't think it's necessary here. It's doing local coalescing here to avoid missing some obvious cse opportunities. If sub-reg class is involved, then it's already too complicated.
>>>>
>>>> Actually I do need to make it more complicated. But then BlackFin hates me (I wonder if it's related to its author).
>>>
>>> Hehe. Blackfin not hating you is a good sign that you got your register classes right ;-)
>>>
>>> Basic register class algebra: If an instruction operand specifies register class X, a virtual register must belong to X or a subclass of X.
>>>
>>> If you want to eliminate a copy "%x = mov %y", the resulting register must make the users of %x and %y happy at the same time. That means the new register must belong to the intersection of X and Y, the register classes of %x and %y.
>>>
>>> The function getCommonSubClass(X, Y) finds the largest existing register class that is a subclass of both X and Y. If getCommonSubClass returns NULL, the classes are disjoint, and you cannot eliminate the copy - no register would be legal.
>>>
>>> I think Blackfin is the only target with disjoint register classes - maybe that is why it hates you.
>>
>> I don't think that's the issue here. For example, 2009-08-15-LiveIn-SubReg.ll:
>> Coalescing: %reg1031 = MOVE %reg1028
>> *** to: %reg1030 = SETEQdd %reg1027, %reg1031
>>
>> *** Bad machine code: Illegal virtual register for instruction ***
>> - function: foo
>> - basic block: entry 0x2036ee4 (BB#0)
>> - instruction: %reg1030 = SETEQdd %reg1027, %reg1028
>> - operand 2: %reg1028
>> Expected a D register, but got a GR register
>
> Sure. D is a subclass of GR.
>
> %reg1028 is GR
> %reg1031 is D
>
> When you coalesce the resulting register class should be getCommonSubClass(GR, D) = D, but you are using %reg1028 which is GR - too big.
>
> The copy was probably created by InstrEmitter::AddRegisterOperand to make the register classes match.
>
>> I'm going to commit my changes to machine cse (which is not turned on yet). Can you take a look at it? Thanks.
>
> Sure.
Ok, I think the issue is more subtle. Your patch disabled some critical coalescing that's required. It probably should be allowed but then changes the register class.
Evan
>
>
From stoklund at 2pi.dk Mon Mar 8 22:21:05 2010
From: stoklund at 2pi.dk (Jakob Stoklund Olesen)
Date: Mon, 8 Mar 2010 20:21:05 -0800
Subject: [llvm-commits] [llvm] r98007 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
In-Reply-To:
References: <20100308232808.91F8F2A6C12C@llvm.org>
<12195ADE-5620-4756-8425-E09F73A9646D@2pi.dk>
<20FB2BBD-9306-4DD8-961E-A627EE6A2FD2@apple.com>
Message-ID: <4AE8D63B-1C47-44CF-849D-FE7AB42B8390@2pi.dk>
On Mar 8, 2010, at 8:14 PM, Evan Cheng wrote:
>
> Ok, I think the issue is more subtle. Your patch disabled some critical coalescing that's required. It probably should be allowed but then changes the register class.
Switching the register class to a subclass should not give any problems besides increased register pressure.
From clattner at apple.com Mon Mar 8 22:30:25 2010
From: clattner at apple.com (Chris Lattner)
Date: Mon, 8 Mar 2010 20:30:25 -0800
Subject: [llvm-commits] [llvm] r98036 -
/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
In-Reply-To: <20100309021505.D57DC2A6C12C@llvm.org>
References: <20100309021505.D57DC2A6C12C@llvm.org>
Message-ID:
Looks great, thanks Dan.
-Chris
On Mar 8, 2010, at 6:15 PM, Dan Gohman wrote:
> Author: djg
> Date: Mon Mar 8 20:15:05 2010
> New Revision: 98036
>
> URL: http://llvm.org/viewvc/llvm-project?rev=98036&view=rev
> Log:
> Attempt to make this debug output meaningful, both in the case of
> multibyte opcodes and in the case of multiple scopes.
>
> Modified:
> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=98036&r1=98035&r2=98036&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Mar 8 20:15:05 2010
> @@ -2141,6 +2141,9 @@
>
> while (1) {
> assert(MatcherIndex < TableSize && "Invalid index");
> +#ifndef NDEBUG
> + unsigned CurrentOpcodeIndex = MatcherIndex;
> +#endif
> BuiltinOpcodes Opcode = (BuiltinOpcodes)MatcherTable[MatcherIndex++];
> switch (Opcode) {
> case OPC_Scope: {
> @@ -2666,6 +2669,7 @@
> // If the code reached this point, then the match failed. See if there is
> // another child to try in the current 'Scope', otherwise pop it until we
> // find a case to check.
> + DEBUG(errs() << " Match failed at index " << CurrentOpcodeIndex << "\n");
> while (1) {
> if (MatchScopes.empty()) {
> CannotYetSelect(NodeToMatch);
> @@ -2680,13 +2684,12 @@
> NodeStack.append(LastScope.NodeStack.begin(), LastScope.NodeStack.end());
> N = NodeStack.back();
>
> - DEBUG(errs() << " Match failed at index " << (MatcherIndex-1)
> - << " continuing at " << LastScope.FailIndex << "\n");
> -
> if (LastScope.NumMatchedMemRefs != MatchedMemRefs.size())
> MatchedMemRefs.resize(LastScope.NumMatchedMemRefs);
> MatcherIndex = LastScope.FailIndex;
>
> + DEBUG(errs() << " Continuing at " << MatcherIndex << "\n");
> +
> InputChain = LastScope.InputChain;
> InputFlag = LastScope.InputFlag;
> if (!LastScope.HasChainNodesMatched)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From sabre at nondot.org Mon Mar 8 22:48:35 2010
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 09 Mar 2010 04:48:35 -0000
Subject: [llvm-commits] [llvm] r98046 -
/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Message-ID: <20100309044835.E4F172A6C12C@llvm.org>
Author: lattner
Date: Mon Mar 8 22:48:35 2010
New Revision: 98046
URL: http://llvm.org/viewvc/llvm-project?rev=98046&view=rev
Log:
add some extra checks. I'm not sure why, but this does unbreak a
failure remaining on mainline.
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=98046&r1=98045&r2=98046&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 8 22:48:35 2010
@@ -1365,6 +1365,7 @@
DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
MCSymbol *Start = Scope->getStartLabel();
MCSymbol *End = Scope->getEndLabel();
+ if (Start == 0) return 0;
assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
assert(End->isDefined() && "Invalid end label for an inlined scope!");
@@ -1387,6 +1388,8 @@
DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
MCSymbol *StartLabel = Scope->getStartLabel();
MCSymbol *EndLabel = Scope->getEndLabel();
+ if (StartLabel == 0) return 0;
+
assert(StartLabel->isDefined() &&
"Invalid starting label for an inlined scope!");
assert(EndLabel->isDefined() &&
From sabre at nondot.org Mon Mar 8 22:54:43 2010
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 09 Mar 2010 04:54:43 -0000
Subject: [llvm-commits] [llvm] r98047 - in /llvm/trunk:
include/llvm/CodeGen/DwarfWriter.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/CodeGen/AsmPrinter/DwarfWriter.cpp
Message-ID: <20100309045444.1175B2A6C12C@llvm.org>
Author: lattner
Date: Mon Mar 8 22:54:43 2010
New Revision: 98047
URL: http://llvm.org/viewvc/llvm-project?rev=98047&view=rev
Log:
reapply r98035:
Now that setStartLabel takes an MCSymbol, we can de-ID'ize
beginScope and RecordSourceLine.
Modified:
llvm/trunk/include/llvm/CodeGen/DwarfWriter.h
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
Modified: llvm/trunk/include/llvm/CodeGen/DwarfWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DwarfWriter.h?rev=98047&r1=98046&r2=98047&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DwarfWriter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/DwarfWriter.h Mon Mar 8 22:54:43 2010
@@ -35,6 +35,7 @@
class Module;
class MDNode;
class MCAsmInfo;
+class MCSymbol;
class raw_ostream;
class Instruction;
class DICompileUnit;
@@ -82,10 +83,10 @@
///
void EndFunction(const MachineFunction *MF);
- /// RecordSourceLine - Register a source line with debug info. Returns a
- /// unique label ID used to generate a label and provide correspondence to
+ /// RecordSourceLine - Register a source line with debug info. Returns the
+ /// unique label that was emitted and which provides correspondence to
/// the source line list.
- unsigned RecordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
+ MCSymbol *RecordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
/// getRecordSourceLineCount - Count source lines.
unsigned getRecordSourceLineCount();
@@ -94,7 +95,7 @@
/// be emitted.
bool ShouldEmitDwarfDebug() const;
- void BeginScope(const MachineInstr *MI, unsigned Label);
+ void BeginScope(const MachineInstr *MI, MCSymbol *Label);
void EndScope(const MachineInstr *MI);
};
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=98047&r1=98046&r2=98047&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Mar 8 22:54:43 2010
@@ -1319,10 +1319,9 @@
// After printing instruction
DW->EndScope(MI);
} else if (CurDLT.getNode() != PrevDLT) {
- unsigned L = DW->RecordSourceLine(CurDLT.getLineNumber(),
- CurDLT.getColumnNumber(),
- CurDLT.getScope().getNode());
- printLabel(L);
+ MCSymbol *L = DW->RecordSourceLine(CurDLT.getLineNumber(),
+ CurDLT.getColumnNumber(),
+ CurDLT.getScope().getNode());
DW->BeginScope(MI, L);
PrevDLT = CurDLT.getNode();
}
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=98047&r1=98046&r2=98047&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 8 22:54:43 2010
@@ -1951,14 +1951,14 @@
}
/// beginScope - Process beginning of a scope starting at Label.
-void DwarfDebug::beginScope(const MachineInstr *MI, unsigned Label) {
+void DwarfDebug::beginScope(const MachineInstr *MI, MCSymbol *Label) {
InsnToDbgScopeMapTy::iterator I = DbgScopeBeginMap.find(MI);
if (I == DbgScopeBeginMap.end())
return;
ScopeVector &SD = I->second;
for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end();
SDI != SDE; ++SDI)
- (*SDI)->setStartLabel(getDWLabel("label", Label));
+ (*SDI)->setStartLabel(Label);
}
/// endScope - Process end of a scope.
@@ -2127,7 +2127,7 @@
Col = DLT.getColumnNumber();
}
- Asm->printLabel(recordSourceLine(Line, Col, DLT.getScope().getNode()));
+ recordSourceLine(Line, Col, DLT.getScope().getNode());
}
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
@@ -2183,11 +2183,10 @@
DebugTimer->stopTimer();
}
-/// recordSourceLine - Records location information and associates it with a
-/// label. Returns a unique label ID used to generate a label and provide
-/// correspondence to the source line list.
-unsigned DwarfDebug::recordSourceLine(unsigned Line, unsigned Col,
- MDNode *S) {
+/// recordSourceLine - Register a source line with debug info. Returns the
+/// unique label that was emitted and which provides correspondence to
+/// the source line list.
+MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
if (!MMI)
return 0;
@@ -2220,7 +2219,9 @@
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
- return ID;
+ MCSymbol *Label = getDWLabel("label", ID);
+ Asm->OutStreamer.EmitLabel(Label);
+ return Label;
}
/// getOrCreateSourceID - Public version of GetOrCreateSourceID. This can be
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=98047&r1=98046&r2=98047&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Mon Mar 8 22:54:43 2010
@@ -512,10 +512,10 @@
///
void endFunction(const MachineFunction *MF);
- /// recordSourceLine - Records location information and associates it with a
- /// label. Returns a unique label ID used to generate a label and provide
- /// correspondence to the source line list.
- unsigned recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
+ /// recordSourceLine - Register a source line with debug info. Returns the
+ /// unique label that was emitted and which provides correspondence to
+ /// the source line list.
+ MCSymbol *recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
/// getSourceLineCount - Return the number of source lines in the debug
/// info.
@@ -539,7 +539,7 @@
void collectVariableInfo();
/// beginScope - Process beginning of a scope starting at Label.
- void beginScope(const MachineInstr *MI, unsigned Label);
+ void beginScope(const MachineInstr *MI, MCSymbol *Label);
/// endScope - Prcess end of a scope.
void endScope(const MachineInstr *MI);
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=98047&r1=98046&r2=98047&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Mon Mar 8 22:54:43 2010
@@ -73,11 +73,11 @@
MMI->EndFunction();
}
-/// RecordSourceLine - Records location information and associates it with a
-/// label. Returns a unique label ID used to generate a label and provide
-/// correspondence to the source line list.
-unsigned DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
- MDNode *Scope) {
+/// RecordSourceLine - Register a source line with debug info. Returns the
+/// unique label that was emitted and which provides correspondence to
+/// the source line list.
+MCSymbol *DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
+ MDNode *Scope) {
return DD->recordSourceLine(Line, Col, Scope);
}
@@ -92,7 +92,7 @@
return DD && DD->ShouldEmitDwarfDebug();
}
-void DwarfWriter::BeginScope(const MachineInstr *MI, unsigned L) {
+void DwarfWriter::BeginScope(const MachineInstr *MI, MCSymbol *L) {
DD->beginScope(MI, L);
}
void DwarfWriter::EndScope(const MachineInstr *MI) {
From evan.cheng at apple.com Tue Mar 9 00:38:18 2010
From: evan.cheng at apple.com (Evan Cheng)
Date: Tue, 09 Mar 2010 06:38:18 -0000
Subject: [llvm-commits] [llvm] r98048 -
/llvm/trunk/lib/CodeGen/MachineCSE.cpp
Message-ID: <20100309063818.0E9A22A6C12C@llvm.org>
Author: evancheng
Date: Tue Mar 9 00:38:17 2010
New Revision: 98048
URL: http://llvm.org/viewvc/llvm-project?rev=98048&view=rev
Log:
Allow more cross-rc coalescing.
Modified:
llvm/trunk/lib/CodeGen/MachineCSE.cpp
Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=98048&r1=98047&r2=98048&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Tue Mar 9 00:38:17 2010
@@ -93,16 +93,19 @@
if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
TargetRegisterInfo::isVirtualRegister(SrcReg) &&
!SrcSubIdx && !DstSubIdx) {
- const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
- const TargetRegisterClass *RC = MRI->getRegClass(Reg);
- if (SRC == RC || RC->hasSubClass(SRC)) {
- DEBUG(dbgs() << "Coalescing: " << *DefMI);
- DEBUG(dbgs() << "*** to: " << *MI);
- MO.setReg(SrcReg);
- DefMI->eraseFromParent();
- ++NumCoalesces;
- Changed = true;
- }
+ const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
+ const TargetRegisterClass *RC = MRI->getRegClass(Reg);
+ const TargetRegisterClass *NewRC = getCommonSubClass(RC, SRC);
+ if (!NewRC)
+ continue;
+ DEBUG(dbgs() << "Coalescing: " << *DefMI);
+ DEBUG(dbgs() << "*** to: " << *MI);
+ MO.setReg(SrcReg);
+ if (NewRC != SRC)
+ MRI->setRegClass(SrcReg, NewRC);
+ DefMI->eraseFromParent();
+ ++NumCoalesces;
+ Changed = true;
}
}
From baldrick at free.fr Tue Mar 9 01:06:28 2010
From: baldrick at free.fr (Duncan Sands)
Date: Tue, 09 Mar 2010 08:06:28 +0100
Subject: [llvm-commits] [llvm-gcc-4.2] r97989
- /llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
In-Reply-To: <20100308213302.618102A6C12C@llvm.org>
References: <20100308213302.618102A6C12C@llvm.org>
Message-ID: <4B95F374.4070505@free.fr>
Hi Dan,
> // If this function returns via a shadow argument, the dest loc is passed
> - // in as a pointer. Mark that pointer as struct-ret and noalias.
> + // in as a pointer. Mark that pointer as struct-ret.
> + //
> + // It's tempting to want NoAlias here too, however even though llvm-gcc
> + // itself currently always passes a dedicated alloca as the actual argument,
> + // this isn't mandated by the ABI. There are other compilers which don't
> + // always pass a dedicated alloca. Using NoAlias here would make code which
> + // isn't interoperable with that of other compilers.
> if (ABIConverter.isShadowReturn())
> Attrs.push_back(AttributeWithIndex::get(ArgTys.size(),
> - Attribute::StructRet | Attribute::NoAlias));
> + Attribute::StructRet));
what does the ABI say exactly? Is it really valid to pass something which may
get "accidentally" altered when the callee (for example) writes to a global or
to some other argument?
Ciao,
Duncan.
From baldrick at free.fr Tue Mar 9 03:03:21 2010
From: baldrick at free.fr (Duncan Sands)
Date: Tue, 09 Mar 2010 09:03:21 -0000
Subject: [llvm-commits] [llvm] r98054 - /llvm/trunk/tools/Makefile
Message-ID: <20100309090321.8856A2A6C12C@llvm.org>
Author: baldrick
Date: Tue Mar 9 03:03:21 2010
New Revision: 98054
URL: http://llvm.org/viewvc/llvm-project?rev=98054&view=rev
Log:
Attempt to fix random build failures seen when doing highly
parallel builds: the gold plugin fails to link because the lto
library is in the middle of being written out by the linker.
Modified:
llvm/trunk/tools/Makefile
Modified: llvm/trunk/tools/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=98054&r1=98053&r2=98054&view=diff
==============================================================================
--- llvm/trunk/tools/Makefile (original)
+++ llvm/trunk/tools/Makefile Tue Mar 9 03:03:21 2010
@@ -42,8 +42,7 @@
# gold only builds if binutils is around. It requires "lto" to build before
# it so it is added to DIRS.
ifdef BINUTILS_INCDIR
- PARALLEL_DIRS += gold
- DIRS += lto
+ DIRS += lto gold
else
PARALLEL_DIRS += lto
endif
From richard at xmos.com Tue Mar 9 10:07:47 2010
From: richard at xmos.com (Richard Osborne)
Date: Tue, 09 Mar 2010 16:07:47 -0000
Subject: [llvm-commits] [llvm] r98057 - in /llvm/trunk:
lib/Target/XCore/XCoreISelLowering.cpp lib/Target/XCore/XCoreISelLowering.h
test/CodeGen/XCore/ladd_lsub_combine.ll
Message-ID: <20100309160747.883462A6C12C@llvm.org>
Author: friedgold
Date: Tue Mar 9 10:07:47 2010
New Revision: 98057
URL: http://llvm.org/viewvc/llvm-project?rev=98057&view=rev
Log:
Add DAG combine for ladd / lsub.
Added:
llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll
Modified:
llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
llvm/trunk/lib/Target/XCore/XCoreISelLowering.h
Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=98057&r1=98056&r2=98057&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Tue Mar 9 10:07:47 2010
@@ -1097,6 +1097,48 @@
DebugLoc dl = N->getDebugLoc();
switch (N->getOpcode()) {
default: break;
+ case XCoreISD::LADD: {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
+ ConstantSDNode *N0C = dyn_cast(N0);
+ ConstantSDNode *N1C = dyn_cast(N1);
+ EVT VT = N0.getValueType();
+
+ // fold (ladd 0, 0, x) -> 0, x & 1
+ if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) {
+ SDValue Carry = DAG.getConstant(0, VT);
+ SDValue Result = DAG.getNode(ISD::AND, dl, VT, N2,
+ DAG.getConstant(1, VT));
+ SDValue Ops [] = { Carry, Result };
+ return DAG.getMergeValues(Ops, 2, dl);
+ }
+ }
+ break;
+ case XCoreISD::LSUB: {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
+ ConstantSDNode *N0C = dyn_cast(N0);
+ ConstantSDNode *N1C = dyn_cast(N1);
+ EVT VT = N0.getValueType();
+
+ // fold (lsub 0, 0, x) -> x, -x iff x has only the low bit set
+ if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) {
+ APInt KnownZero, KnownOne;
+ APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(),
+ VT.getSizeInBits() - 1);
+ DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne);
+ if (KnownZero == Mask) {
+ SDValue Borrow = N2;
+ SDValue Result = DAG.getNode(ISD::SUB, dl, VT,
+ DAG.getConstant(0, VT), N2);
+ SDValue Ops [] = { Borrow, Result };
+ return DAG.getMergeValues(Ops, 2, dl);
+ }
+ }
+ }
+ break;
case ISD::STORE: {
// Replace unaligned store of unaligned load with memmove.
StoreSDNode *ST = cast(N);
@@ -1137,6 +1179,27 @@
return SDValue();
}
+void XCoreTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
+ const APInt &Mask,
+ APInt &KnownZero,
+ APInt &KnownOne,
+ const SelectionDAG &DAG,
+ unsigned Depth) const {
+ KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
+ switch (Op.getOpcode()) {
+ default: break;
+ case XCoreISD::LADD:
+ case XCoreISD::LSUB:
+ if (Op.getResNo() == 0) {
+ // Top bits of carry / borrow are clear.
+ KnownZero = APInt::getHighBitsSet(Mask.getBitWidth(),
+ Mask.getBitWidth() - 1);
+ KnownZero &= Mask;
+ }
+ break;
+ }
+}
+
//===----------------------------------------------------------------------===//
// Addressing mode description hooks
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.h?rev=98057&r1=98056&r2=98057&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.h (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.h Tue Mar 9 10:07:47 2010
@@ -144,6 +144,13 @@
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
+ virtual void computeMaskedBitsForTargetNode(const SDValue Op,
+ const APInt &Mask,
+ APInt &KnownZero,
+ APInt &KnownOne,
+ const SelectionDAG &DAG,
+ unsigned Depth = 0) const;
+
virtual SDValue
LowerFormalArguments(SDValue Chain,
CallingConv::ID CallConv,
Added: llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll?rev=98057&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll (added)
+++ llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll Tue Mar 9 10:07:47 2010
@@ -0,0 +1,28 @@
+; RUN: llvm-as < %s | llc -march=xcore | FileCheck %s
+
+; Only needs one ladd
+define i64 @f1(i32 %x, i32 %y) nounwind {
+entry:
+ %0 = zext i32 %x to i64 ; [#uses=1]
+ %1 = zext i32 %y to i64 ; [#uses=1]
+ %2 = add i64 %1, %0 ; [#uses=1]
+ ret i64 %2
+}
+; CHECK: f1:
+; CHECK: ldc r2, 0
+; CHECK-NEXT: ladd r1, r0, r1, r0, r2
+; CHECK-NEXT: retsp 0
+
+; Only needs one lsub and one neg
+define i64 @f2(i32 %x, i32 %y) nounwind {
+entry:
+ %0 = zext i32 %x to i64 ; [#uses=1]
+ %1 = zext i32 %y to i64 ; [#uses=1]
+ %2 = sub i64 %1, %0 ; [#uses=1]
+ ret i64 %2
+}
+; CHECK: f2:
+; CHECK: ldc r2, 0
+; CHECK-NEXT: lsub r1, r0, r1, r0, r2
+; CHECK-NEXT: neg r1, r1
+; CHECK-NEXT: retsp 0
From richard at xmos.com Tue Mar 9 10:13:58 2010
From: richard at xmos.com (Richard Osborne)
Date: Tue, 09 Mar 2010 16:13:58 -0000
Subject: [llvm-commits] [llvm] r98058 -
/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
Message-ID: <20100309161358.0E3772A6C12C@llvm.org>
Author: friedgold
Date: Tue Mar 9 10:13:57 2010
New Revision: 98058
URL: http://llvm.org/viewvc/llvm-project?rev=98058&view=rev
Log:
Canonicalize ladd constant to RHS.
Modified:
llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=98058&r1=98057&r2=98058&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Tue Mar 9 10:13:57 2010
@@ -1105,6 +1105,10 @@
ConstantSDNode *N1C = dyn_cast(N1);
EVT VT = N0.getValueType();
+ // canonicalize constant to RHS
+ if (N0C && !N1C)
+ return DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N1, N0, N2);
+
// fold (ladd 0, 0, x) -> 0, x & 1
if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) {
SDValue Carry = DAG.getConstant(0, VT);
From richard at xmos.com Tue Mar 9 10:34:25 2010
From: richard at xmos.com (Richard Osborne)
Date: Tue, 09 Mar 2010 16:34:25 -0000
Subject: [llvm-commits] [llvm] r98059 - in /llvm/trunk:
lib/Target/XCore/XCoreISelLowering.cpp
test/CodeGen/XCore/ladd_lsub_combine.ll
Message-ID: <20100309163425.EEBFF2A6C12C@llvm.org>
Author: friedgold
Date: Tue Mar 9 10:34:25 2010
New Revision: 98059
URL: http://llvm.org/viewvc/llvm-project?rev=98059&view=rev
Log:
In cases where the carry / borrow unused converted ladd / lsub
to an add or a sub.
Modified:
llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll
Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=98059&r1=98058&r2=98059&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Tue Mar 9 10:34:25 2010
@@ -1117,6 +1117,21 @@
SDValue Ops [] = { Carry, Result };
return DAG.getMergeValues(Ops, 2, dl);
}
+
+ // fold (ladd x, 0, y) -> 0, add x, y iff carry is unused and y has only the
+ // low bit set
+ if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 0)) {
+ APInt KnownZero, KnownOne;
+ APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(),
+ VT.getSizeInBits() - 1);
+ DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne);
+ if (KnownZero == Mask) {
+ SDValue Carry = DAG.getConstant(0, VT);
+ SDValue Result = DAG.getNode(ISD::ADD, dl, VT, N0, N2);
+ SDValue Ops [] = { Carry, Result };
+ return DAG.getMergeValues(Ops, 2, dl);
+ }
+ }
}
break;
case XCoreISD::LSUB: {
@@ -1141,6 +1156,21 @@
return DAG.getMergeValues(Ops, 2, dl);
}
}
+
+ // fold (lsub x, 0, y) -> 0, sub x, y iff borrow is unused and y has only the
+ // low bit set
+ if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 0)) {
+ APInt KnownZero, KnownOne;
+ APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(),
+ VT.getSizeInBits() - 1);
+ DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne);
+ if (KnownZero == Mask) {
+ SDValue Borrow = DAG.getConstant(0, VT);
+ SDValue Result = DAG.getNode(ISD::SUB, dl, VT, N0, N2);
+ SDValue Ops [] = { Borrow, Result };
+ return DAG.getMergeValues(Ops, 2, dl);
+ }
+ }
}
break;
case ISD::STORE: {
Modified: llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll?rev=98059&r1=98058&r2=98059&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll (original)
+++ llvm/trunk/test/CodeGen/XCore/ladd_lsub_combine.ll Tue Mar 9 10:34:25 2010
@@ -26,3 +26,42 @@
; CHECK-NEXT: lsub r1, r0, r1, r0, r2
; CHECK-NEXT: neg r1, r1
; CHECK-NEXT: retsp 0
+
+; Should compile to one ladd and one add
+define i64 @f3(i64 %x, i32 %y) nounwind {
+entry:
+ %0 = zext i32 %y to i64 ; [#uses=1]
+ %1 = add i64 %x, %0 ; [#uses=1]
+ ret i64 %1
+}
+; CHECK: f3:
+; CHECK: ldc r3, 0
+; CHECK-NEXT: ladd r2, r0, r0, r2, r3
+; CHECK-NEXT: add r1, r1, r2
+; CHECK-NEXT: retsp 0
+
+; Should compile to one ladd and one add
+define i64 @f4(i32 %x, i64 %y) nounwind {
+entry:
+ %0 = zext i32 %x to i64 ; [#uses=1]
+ %1 = add i64 %0, %y ; [#uses=1]
+ ret i64 %1
+}
+; CHECK: f4:
+; CHECK: ldc r3, 0
+; CHECK-NEXT: ladd r1, r0, r0, r1, r3
+; CHECK-NEXT: add r1, r2, r1
+; CHECK-NEXT: retsp 0
+
+; Should compile to one lsub and one sub
+define i64 @f5(i64 %x, i32 %y) nounwind {
+entry:
+ %0 = zext i32 %y to i64 ; [#uses=1]
+ %1 = sub i64 %x, %0 ; [#uses=1]
+ ret i64 %1
+}
+; CHECK: f5:
+; CHECK: ldc r3, 0
+; CHECK-NEXT: lsub r2, r0, r0, r2, r3
+; CHECK-NEXT: sub r1, r1, r2
+; CHECK-NEXT: retsp 0
From alenhar2 at llvm.org Tue Mar 9 10:42:42 2010
From: alenhar2 at llvm.org (alenhar2 at llvm.org)
Date: Tue, 09 Mar 2010 16:42:42 -0000
Subject: [llvm-commits] [poolalloc] r98060 -
/poolalloc/trunk/include/LinkDSA.h
Message-ID: <20100309164242.5D45F2A6C12C@llvm.org>
Author: alenhar2
Date: Tue Mar 9 10:42:42 2010
New Revision: 98060
URL: http://llvm.org/viewvc/llvm-project?rev=98060&view=rev
Log:
A file to pull to link dsa into a tool
Added:
poolalloc/trunk/include/LinkDSA.h
Added: poolalloc/trunk/include/LinkDSA.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/LinkDSA.h?rev=98060&view=auto
==============================================================================
--- poolalloc/trunk/include/LinkDSA.h (added)
+++ poolalloc/trunk/include/LinkDSA.h Tue Mar 9 10:42:42 2010
@@ -0,0 +1,23 @@
+namespace {
+ struct ForceDSALinking {
+ ForceDSALinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ (void)new llvm::BasicDataStructures();
+ (void)new llvm::LocalDataStructures();
+ (void)new llvm::StdLibDataStructures();
+ (void)new llvm::BUDataStructures();
+ (void)new llvm::CompleteBUDataStructures();
+ (void)new llvm::EquivBUDataStructures();
+ (void)new llvm::TDDataStructures();
+ (void)new llvm::EQTDDataStructures();
+ (void)new llvm::SteensgaardDataStructures();
+ (void)new llvm::RTAssociate();
+ }
+ } ForceDSALinking; // Force link by creating a global definition.
+}
From alenhar2 at llvm.org Tue Mar 9 10:43:02 2010
From: alenhar2 at llvm.org (alenhar2 at llvm.org)
Date: Tue, 09 Mar 2010 16:43:02 -0000
Subject: [llvm-commits] [poolalloc] r98061 - in /poolalloc/trunk: README
lib/DSA/README
Message-ID: <20100309164302.3F9A62A6C12C@llvm.org>
Author: alenhar2
Date: Tue Mar 9 10:43:02 2010
New Revision: 98061
URL: http://llvm.org/viewvc/llvm-project?rev=98061&view=rev
Log:
Update readme with known issues
Added:
poolalloc/trunk/lib/DSA/README
Modified:
poolalloc/trunk/README
Modified: poolalloc/trunk/README
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/README?rev=98061&r1=98060&r2=98061&view=diff
==============================================================================
--- poolalloc/trunk/README (original)
+++ poolalloc/trunk/README Tue Mar 9 10:43:02 2010
@@ -5,6 +5,20 @@
Before using the Automatic Pool Allocator, you should read the pre-release
license in LICENSE.TXT.
+KNOWN ISSUES:
+=============
+
+Automatic Pool Allocation is currently broken on 2.7 due to malloc and
+free instructions being removed. Use the release_26 branch of llvm
+and poolalloc for a working poolalloc module.
+
+DSA is undergoing significant changes and may not be entirely stable or
+correct. See lib/DSA/README.
+
+Windows does not support loadable modules in llvm, so poolalloc must
+be linked into opt.
+
+
BUILDING:
=========
To build the Automatic Pool Allocator, you will need to have installed and
Added: poolalloc/trunk/lib/DSA/README
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/README?rev=98061&view=auto
==============================================================================
--- poolalloc/trunk/lib/DSA/README (added)
+++ poolalloc/trunk/lib/DSA/README Tue Mar 9 10:43:02 2010
@@ -0,0 +1,15 @@
+DSA is changed since PLDI07 in (at least) the following ways:
+
+1) DSA tracks types per offset.
+2) DSA does not assume that all clients will want to collapse a node if types
+ conflict. Many clients don't care that an offset is used as an int or a
+ double, they just care about the points-to result.
+
+In Progress:
+
+1) DSA handles multiple entry points in a module.
+2) Optional assumption that only legal targets are called at indirect call sites
+3) Positional arguments, rather than pointer relative arguments. This handles
+ the case where pointer and ints are assumed compatible and function pointers
+ containing them are cast freely.
+
From alenhar2 at llvm.org Tue Mar 9 10:48:35 2010
From: alenhar2 at llvm.org (alenhar2 at llvm.org)
Date: Tue, 09 Mar 2010 16:48:35 -0000
Subject: [llvm-commits] [poolalloc] r98062 - in /poolalloc/trunk:
include/dsa/DSGraph.h include/dsa/DSGraphTraits.h include/dsa/DSNode.h
include/dsa/DSSupport.h lib/DSA/Basic.cpp lib/DSA/BottomUpClosure.cpp
lib/DSA/DataStructure.cpp lib/DSA/Local.cpp lib/DSA/Printer.cpp
lib/DSA/TopDownClosure.cpp
Message-ID: <20100309164836.1E11F2A6C12C@llvm.org>
Author: alenhar2
Date: Tue Mar 9 10:48:35 2010
New Revision: 98062
URL: http://llvm.org/viewvc/llvm-project?rev=98062&view=rev
Log:
Add byte offset based sets of types
Add byte offset links
add multiple entry points, WIP
get rid of stl/ext hash_
fix graph printer
api update to 2.7
handle malloc, sometimes (TODO: free, generalized allocator framework)
remove cruft
factor common operations out
Modified:
poolalloc/trunk/include/dsa/DSGraph.h
poolalloc/trunk/include/dsa/DSGraphTraits.h
poolalloc/trunk/include/dsa/DSNode.h
poolalloc/trunk/include/dsa/DSSupport.h
poolalloc/trunk/lib/DSA/Basic.cpp
poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
poolalloc/trunk/lib/DSA/DataStructure.cpp
poolalloc/trunk/lib/DSA/Local.cpp
poolalloc/trunk/lib/DSA/Printer.cpp
poolalloc/trunk/lib/DSA/TopDownClosure.cpp
Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Tue Mar 9 10:48:35 2010
@@ -24,7 +24,7 @@
namespace llvm {
-
+class TargetData;
class GlobalValue;
//===----------------------------------------------------------------------===//
Modified: poolalloc/trunk/include/dsa/DSGraphTraits.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraphTraits.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraphTraits.h (original)
+++ poolalloc/trunk/include/dsa/DSGraphTraits.h Tue Mar 9 10:48:35 2010
@@ -34,7 +34,7 @@
DSNodeIterator(NodeTy *N) : Node(N), Offset(0) {} // begin iterator
DSNodeIterator(NodeTy *N, bool) : Node(N) { // Create end iterator
if (N != 0) {
- Offset = N->getNumLinks();
+ Offset = N->getSize();
if (Offset == 0 && Node->getForwardNode() &&
Node->isDeadNode()) // Model Forward link
Offset += 1;
Modified: poolalloc/trunk/include/dsa/DSNode.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSNode.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSNode.h (original)
+++ poolalloc/trunk/include/dsa/DSNode.h Tue Mar 9 10:48:35 2010
@@ -15,6 +15,8 @@
#define LLVM_ANALYSIS_DSNODE_H
#include "dsa/DSSupport.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/ilist_node.h"
#include