[llvm-commits] [PATCH] Extend the builder interface to use the new instruction positioning code.
Gordon Henriksen
gordonhenriksen at mac.com
Sun Mar 23 21:20:13 PDT 2008
At Sun Mar 23 22:25:54 CDT 2008, Erick Trzelaar wrote:
> This builds off of the code gordonh recently added for manipulating
> iterators. This adds support for instruction iterators, as well as
> rewriting the builder code to use these new functions. This lets us
> eliminate the c bindings for moving around the builder. It also adds
> some convenience functions like "builder_at_start".
Hi Erick,
Looks great overall. A bit of nitpicking inline. Only thing missing is
a test.
Thanks,
Gordon
> diff --git bindings/ocaml/llvm/llvm.ml bindings/ocaml/llvm/llvm.ml
> index 56bfa7b..c168ead 100644
> --- bindings/ocaml/llvm/llvm.ml
> +++ bindings/ocaml/llvm/llvm.ml
> @@ -531,6 +531,55 @@ let fold_right_blocks f fn init =
>
> (*--... Operations on
> instructions .........................................--*)
> external instr_parent : llvalue -> llbasicblock =
> "LLVMGetInstructionParent"
> +external instr_begin : llbasicblock -> (llbasicblock, llvalue) llpos
> + = "llvm_instr_begin"
> +external instr_succ : llvalue -> (llbasicblock, llvalue) llpos
> + = "llvm_instr_succ"
> +external instr_end : llbasicblock -> (llbasicblock, llvalue)
> llrev_pos
> + = "llvm_instr_end"
> +external instr_pred : llvalue -> (llbasicblock, llvalue) llrev_pos
> + = "llvm_instr_pred"
> +
> +let rec iter_instrs_range f i e =
> + if i = e then () else
> + match i with
> + | At_end _ -> raise (Invalid_argument "Invalid instruction range.")
> + | Before i ->
> + f i;
> + iter_instrs_range f (instr_succ i) e
> +
> +let iter_instrs f bb =
> + iter_instrs_range f (instr_begin bb) (At_end bb)
> +
> +let rec fold_left_instrs_range f init i e =
> + if i = e then init else
> + match i with
> + | At_end _ -> raise (Invalid_argument "Invalid instruction range.")
> + | Before i -> fold_left_instrs_range f (f init i) (instr_succ i) e
> +
> +let fold_left_instrs f init bb =
> + fold_left_instrs_range f init (instr_begin bb) (At_end bb)
> +
> +let rec rev_iter_instrs_range f i e =
> + if i = e then () else
> + match i with
> + | At_start _ -> raise (Invalid_argument "Invalid instruction
> range.")
> + | After i ->
> + f i;
> + rev_iter_instrs_range f (instr_pred i) e
> +
> +let rev_iter_instrs f bb =
> + rev_iter_instrs_range f (instr_end bb) (At_start bb)
> +
> +let rec fold_right_instr_range f i e init =
> + if i = e then init else
> + match i with
> + | At_start _ -> raise (Invalid_argument "Invalid instruction
> range.")
> + | After i -> fold_right_instr_range f (instr_pred i) e (f i init)
> +
> +let fold_right_instrs f bb init =
> + fold_right_instr_range f (instr_end bb) (At_start bb) init
> +
Looks good. ;)
>
> (*--... Operations on call
> sites ...........................................--*)
> external instruction_call_conv: llvalue -> int
> @@ -545,14 +594,27 @@ external incoming : llvalue -> (llvalue *
> llbasicblock) list = "llvm_incoming"
>
>
> (*===-- Instruction builders
> ----------------------------------------------===*)
> -external builder: unit-> llbuilder = "llvm_builder"
> -external builder_before : llvalue -> llbuilder =
> "llvm_builder_before"
> -external builder_at_end : llbasicblock -> llbuilder =
> "llvm_builder_at_end"
> -external position_before : llvalue -> llbuilder -> unit =
> "llvm_position_before"
> -external position_at_end : llbasicblock -> llbuilder -> unit
> - = "llvm_position_at_end"
> +external builder : unit -> llbuilder = "llvm_builder"
> +external position_builder : (llbasicblock, llvalue) llpos ->
> llbuilder -> unit
> + = "llvm_position_builder"
> external insertion_block : llbuilder -> llbasicblock =
> "llvm_insertion_block"
>
> +let builder_at ip =
> + let b = builder () in
> + position_builder ip b;
> + b
> +
> +let builder_before i = builder_at (Before i)
> +let builder_after i = builder_at (instr_succ i)
> +let builder_at_start bb = builder_at (instr_begin bb)
> +let builder_at_end bb = builder_at (At_end bb)
> +
> +let position_before i = position_builder (Before i)
> +let position_after i = position_builder (instr_succ i)
> +let position_at_start bb = position_builder (instr_begin bb)
> +let position_at_end bb = position_builder (At_end bb)
I think these 8 are largely redundant since they're so trivial, with
the exception of the *_after and *_at_end variants that are modestly
more important for maintaining compatibility. Though I'm happy to add
them if you really prefer.
> +
> +
> (*--...
> Terminators
> ........................................................--*)
> external build_ret_void : llbuilder -> llvalue =
> "llvm_build_ret_void"
> external build_ret : llvalue -> llbuilder -> llvalue =
> "llvm_build_ret"
> diff --git bindings/ocaml/llvm/llvm.mli bindings/ocaml/llvm/llvm.mli
> index 8be5c65..e5f7835 100644
> --- bindings/ocaml/llvm/llvm.mli
> +++ bindings/ocaml/llvm/llvm.mli
> @@ -1077,6 +1077,43 @@ external block_of_value : llvalue ->
> llbasicblock = "LLVMValueAsBasicBlock"
> See the method [llvm::Instruction::getParent]. *)
> external instr_parent : llvalue -> llbasicblock =
> "LLVMGetInstructionParent"
>
> +(** [instr_begin bb] returns the first position i the basic block
> [bb]'s
'first position i'?
> + instruction list. [instr_begin] and [instr_succ] can be used to
> iterate
> + over the global list in order.
> + See the method [llvm::Instruction::begin]. *)
llvm::BasicBlock::begin
> +external instr_begin : llbasicblock -> (llbasicblock, llvalue) llpos
> + = "llvm_instr_begin"
> +
> +(** [instr_succ i] returns the instr variable list position
> succeeding
instruction list
> + [Before i].
> + See the method [llvm::BasicBlock::iterator::operator++]. *)
> +external instr_succ : llvalue -> (llbasicblock, llvalue) llpos
> + = "llvm_instr_succ"
> +
> +(** [iter_instrs f bb] applies function [f] to each of the
> instructions of basic
> + block [bb] in order. Tail recursive. *)
> +val iter_instrs: (llvalue -> unit) -> llbasicblock -> unit
> +
> +(** [fold_left_instrs f init bb] is [f (... (f init g1) ...) gN]
> where
> + [g1,...,gN] are the instructions of basic block [bb]. Tail
> recursive. *)
> +val fold_left_instrs: ('a -> llvalue -> 'a) -> 'a -> llbasicblock -
> > 'a
> +
> +(** [instr_end bb] returns the last position i the basic block [bb]'s
'last position i'?
> + instruction list. [instr_end] and [instr_succ] can be used to
> iterate over
> + the global list in order.
again
> + See the method [llvm::BasicBlock::end]. *)
> +external instr_end : llbasicblock -> (llbasicblock, llvalue)
> llrev_pos
> + = "llvm_instr_end"
> +
> +(** [instr_pred i] returns the instr variable list position
> preceding [After i].
instruction list
> + See the method [llvm::BasicBlock::iterator::operator--]. *)
> +external instr_pred : llvalue -> (llbasicblock, llvalue) llrev_pos
> + = "llvm_instr_pred"
> +
> +(** [fold_right_instrs f bb init] is [f (... (f init fN) ...) f1]
> where
> + [f1,...,fN] are the instructions of basicblock [bb]. Tail
> recursive. *)
basic block
> +val fold_right_instrs: (llvalue -> 'a -> 'a) -> llbasicblock -> 'a -
> > 'a
> +
>
> (** {7 Operations on call sites} *)
>
> @@ -1114,25 +1151,50 @@ external incoming : llvalue -> (llvalue *
> llbasicblock) list = "llvm_incoming"
> (** [builder ()] creates an instruction builder with no position.
> It is invalid
> to use this builder until its position is set with {!
> position_before} or
> {!position_at_end}. See the constructor for
> [llvm::LLVMBuilder]. *)
> -external builder: unit-> llbuilder
> - = "llvm_builder"
> +external builder : unit -> llbuilder = "llvm_builder"
> +
> +(** [builder_at ip] creates an instruction builder positioned at
> [ip].
> + See the constructor for [llvm::LLVMBuilder]. *)
> +val builder_at : (llbasicblock, llvalue) llpos -> llbuilder
>
> (** [builder_before ins] creates an instruction builder positioned
> before the
> instruction [isn]. See the constructor for [llvm::LLVMBuilder].
> *)
> -external builder_before : llvalue -> llbuilder =
> "llvm_builder_before"
> +val builder_before : llvalue -> llbuilder
> +
> +(** [builder_after ins] creates an instruction builder positioned
> after the
> + instruction [isn]. See the constructor for [llvm::LLVMBuilder].
> *)
> +val builder_after: llvalue -> llbuilder
> +
> +(** [builder_at_start bb] creates an instruction builder positioned
> at the start
> + of the basic block [bb]. See the constructor for
> [llvm::LLVMBuilder]. *)
> +val builder_at_start: llbasicblock -> llbuilder
>
> (** [builder_at_end bb] creates an instruction builder positioned
> at the end of
> the basic block [bb]. See the constructor for
> [llvm::LLVMBuilder]. *)
> -external builder_at_end : llbasicblock -> llbuilder =
> "llvm_builder_at_end"
> +val builder_at_end : llbasicblock -> llbuilder
> +
> +(** [position_builder ip bb] moves the instruction builder [bb] to
> the position
> + [ip].
> + See the constructor for [llvm::LLVMBuilder]. *)
> +external position_builder : (llbasicblock, llvalue) llpos ->
> llbuilder -> unit
> + = "llvm_position_builder"
>
> (** [position_before ins b] moves the instruction builder [b] to
> before the
> instruction [isn]. See the method
> [llvm::LLVMBuilder::SetInsertPoint]. *)
> -external position_before : llvalue -> llbuilder -> unit =
> "llvm_position_before"
> +val position_before : llvalue -> llbuilder -> unit
> +
> +(** [position_after ins b] moves the instruction builder [b] to
> after the
> + instruction [isn]. See the method
> [llvm::LLVMBuilder::SetInsertPoint]. *)
> +val position_after : llvalue -> llbuilder -> unit
> +
> +(** [position_at_start bb b] moves the instruction builder [b] to
> the start of
> + the of basic block [bb]. See the method
> + [llvm::LLVMBuilder::SetInsertPoint]. *)
> +val position_at_start : llbasicblock -> llbuilder -> unit
>
> (** [position_at_end bb b] moves the instruction builder [b] to the
> end of the
> basic block [bb]. See the method
> [llvm::LLVMBuilder::SetInsertPoint]. *)
> -external position_at_end : llbasicblock -> llbuilder -> unit
> - = "llvm_position_at_end"
> +val position_at_end : llbasicblock -> llbuilder -> unit
>
> (** [insertion_block b] returns the basic block that the builder
> [b] is
> positioned to insert into. Raises [Not_Found] if the
> instruction builder is
> diff --git bindings/ocaml/llvm/llvm_ocaml.c bindings/ocaml/llvm/
> llvm_ocaml.c
> index 1b76488..a4a940e 100644
> --- bindings/ocaml/llvm/llvm_ocaml.c
> +++ bindings/ocaml/llvm/llvm_ocaml.c
> @@ -714,6 +714,12 @@ CAMLprim value llvm_value_is_block(LLVMValueRef
> Val) {
> return Val_bool(LLVMValueIsBasicBlock(Val));
> }
>
> +/*--... Operations on
> instructions .........................................--*/
> +
> +DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef,
> + LLVMGetInstructionParent)
> +
> +
Isn't there already a section for this? I think llvm_instr_parent is
bound already.
> /*--... Operations on call
> sites ...........................................--*/
>
> /* llvalue -> int */
> @@ -789,29 +795,15 @@ CAMLprim value llvm_builder(value Unit) {
> return alloc_builder(LLVMCreateBuilder());
> }
>
> -/* llvalue -> llbuilder */
> -CAMLprim value llvm_builder_before(LLVMValueRef Inst) {
> - LLVMBuilderRef B = LLVMCreateBuilder();
> - LLVMPositionBuilderBefore(B, Inst);
> - return alloc_builder(B);
> -}
> -
> -/* llbasicblock -> llbuilder */
> -CAMLprim value llvm_builder_at_end(LLVMBasicBlockRef BB) {
> - LLVMBuilderRef B = LLVMCreateBuilder();
> - LLVMPositionBuilderAtEnd(B, BB);
> - return alloc_builder(B);
> -}
> -
> -/* llvalue -> llbuilder -> unit */
> -CAMLprim value llvm_position_before(LLVMValueRef Inst, value B) {
> - LLVMPositionBuilderBefore(Builder_val(B), Inst);
> - return Val_unit;
> -}
> -
> -/* llbasicblock -> llbuilder -> unit */
> -CAMLprim value llvm_position_at_end(LLVMBasicBlockRef BB, value B) {
> - LLVMPositionBuilderAtEnd(Builder_val(B), BB);
> +/* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
> +CAMLprim value llvm_position_builder(value Pos, value B) {
> + if (Tag_val(Pos) == 0) {
> + LLVMBasicBlockRef BB = (LLVMBasicBlockRef) Op_val(Field(Pos, 0));
> + LLVMPositionBuilderAtEnd(Builder_val(B), BB);
> + } else {
> + LLVMValueRef I = (LLVMValueRef) Op_val(Field(Pos, 0));
> + LLVMPositionBuilderBefore(Builder_val(B), I);
> + }
> return Val_unit;
> }
>
Mm. Delicious -'s!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20080324/2a5cc2a9/attachment.html>
More information about the llvm-commits
mailing list