[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