llvm.org GIT mirror llvm / 686e157
[OCaml] PR19859: Add functions to query and modify branches. Patch by Gabriel Radanne <drupyog@zoho.com>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220818 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Zotov 5 years ago
4 changed file(s) with 152 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
10251025 external is_volatile : llvalue -> bool = "llvm_is_volatile"
10261026 external set_volatile : bool -> llvalue -> unit = "llvm_set_volatile"
10271027
1028 (*--... Operations on terminators ..........................................--*)
1029
1030 let is_terminator llv =
1031 let open ValueKind in
1032 let open Opcode in
1033 match classify_value llv with
1034 | Instruction (Br | IndirectBr | Invoke | Resume | Ret | Switch | Unreachable)
1035 -> true
1036 | _ -> false
1037
1038 external successor : llvalue -> int -> llbasicblock = "llvm_successor"
1039 external set_successor : llvalue -> int -> llbasicblock -> unit
1040 = "llvm_set_successor"
1041 external num_successors : llvalue -> int = "llvm_num_successors"
1042
1043 let successors llv =
1044 if not (is_terminator llv) then
1045 raise (Invalid_argument "Llvm.successors can only be used on terminators")
1046 else
1047 Array.init (num_successors llv) (successor llv)
1048
1049 let iter_successors f llv =
1050 if not (is_terminator llv) then
1051 raise (Invalid_argument "Llvm.iter_successors can only be used on terminators")
1052 else
1053 for i = 0 to num_successors llv - 1 do
1054 f (successor llv i)
1055 done
1056
1057 let fold_successors f llv z =
1058 if not (is_terminator llv) then
1059 raise (Invalid_argument "Llvm.fold_successors can only be used on terminators")
1060 else
1061 let n = num_successors llv in
1062 let rec aux i acc =
1063 if i >= n then acc
1064 else begin
1065 let llb = successor llv i in
1066 aux (i+1) (f llb acc)
1067 end
1068 in aux 0 z
1069
1070
1071 (*--... Operations on branches .............................................--*)
1072 external condition : llvalue -> llvalue = "llvm_condition"
1073 external set_condition : llvalue -> llvalue -> unit
1074 = "llvm_set_condition"
1075 external is_conditional : llvalue -> bool = "llvm_is_conditional"
1076
1077 let get_branch llv =
1078 if classify_value llv <> ValueKind.Instruction Opcode.Br then
1079 None
1080 else if is_conditional llv then
1081 Some (`Conditional (condition llv, successor llv 0, successor llv 1))
1082 else
1083 Some (`Unconditional (successor llv 0))
1084
10281085 (*--... Operations on phi nodes ............................................--*)
10291086 external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit
10301087 = "llvm_add_incoming"
17661766 [llvm::StoreInst::setVolatile]. *)
17671767 val set_volatile : bool -> llvalue -> unit
17681768
1769 (** {7 Operations on terminators} *)
1770
1771 (** [is_terminator v] returns true if the instruction [v] is a terminator. *)
1772 val is_terminator : llvalue -> bool
1773
1774 (** [successor v i] returns the successor at index [i] for the value [v].
1775 See the method [llvm::TerminatorInst::getSuccessor]. *)
1776 val successor : llvalue -> int -> llbasicblock
1777
1778 (** [set_successor v i o] sets the successor of the value [v] at the index [i] to
1779 the value [o].
1780 See the method [llvm::TerminatorInst::setSuccessor]. *)
1781 val set_successor : llvalue -> int -> llbasicblock -> unit
1782
1783 (** [num_successors v] returns the number of successors for the value [v].
1784 See the method [llvm::TerminatorInst::getNumSuccessors]. *)
1785 val num_successors : llvalue -> int
1786
1787 (** [successors v] returns the successors of [v]. *)
1788 val successors : llvalue -> llbasicblock array
1789
1790 (** [iter_successors f v] applies function f to each successor [v] in order. Tail recursive. *)
1791 val iter_successors : (llbasicblock -> unit) -> llvalue -> unit
1792
1793 (** [fold_successors f v init] is [f (... (f init vN) ...) v1] where [v1,...,vN] are the successors of [v]. Tail recursive. *)
1794 val fold_successors : (llbasicblock -> 'a -> 'a) -> llvalue -> 'a -> 'a
1795
1796 (** {7 Operations on branches} *)
1797
1798 (** [is_conditional v] returns true if the branch instruction [v] is conditional.
1799 See the method [llvm::BranchInst::isConditional]. *)
1800 val is_conditional : llvalue -> bool
1801
1802 (** [condition v] return the condition of the branch instruction [v].
1803 See the method [llvm::BranchInst::getCondition]. *)
1804 val condition : llvalue -> llvalue
1805
1806 (** [set_condition v c] sets the condition of the branch instruction [v] to the value [c].
1807 See the method [llvm::BranchInst::setCondition]. *)
1808 val set_condition : llvalue -> llvalue -> unit
1809
1810 (** [get_branch c] returns a description of the branch instruction [c]. *)
1811 val get_branch : llvalue ->
1812 [ `Conditional of llvalue * llbasicblock * llbasicblock
1813 | `Unconditional of llbasicblock ]
1814 option
17691815
17701816 (** {7 Operations on phi nodes} *)
17711817
14501450 return Val_unit;
14511451 }
14521452
1453
1454 /*--.. Operations on terminators ...........................................--*/
1455
1456 /* llvalue -> int -> llbasicblock */
1457 CAMLprim LLVMBasicBlockRef llvm_successor(LLVMValueRef V, value I) {
1458 return LLVMGetSuccessor(V, Int_val(I));
1459 }
1460
1461 /* llvalue -> int -> llvalue -> unit */
1462 CAMLprim value llvm_set_successor(LLVMValueRef U, value I, LLVMBasicBlockRef B) {
1463 LLVMSetSuccessor(U, Int_val(I), B);
1464 return Val_unit;
1465 }
1466
1467 /* llvalue -> int */
1468 CAMLprim value llvm_num_successors(LLVMValueRef V) {
1469 return Val_int(LLVMGetNumSuccessors(V));
1470 }
1471
1472 /*--.. Operations on branch ................................................--*/
1473
1474 /* llvalue -> llvalue */
1475 CAMLprim LLVMValueRef llvm_condition(LLVMValueRef V) {
1476 return LLVMGetCondition(V);
1477 }
1478
1479 /* llvalue -> llvalue -> unit */
1480 CAMLprim value llvm_set_condition(LLVMValueRef B, LLVMValueRef C) {
1481 LLVMSetCondition(B, C);
1482 return Val_unit;
1483 }
1484
1485 /* llvalue -> bool */
1486 CAMLprim value llvm_is_conditional(LLVMValueRef V) {
1487 return Val_bool(LLVMIsConditional(V));
1488 }
1489
14531490 /*--... Operations on phi nodes ............................................--*/
14541491
14551492 /* (llvalue * llbasicblock) -> llvalue -> unit */
11961196 *)
11971197 let bb02 = append_block context "Bb02" fn in
11981198 let b = builder_at_end context bb02 in
1199 ignore (build_br bb02 b)
1199 let br = build_br bb02 b in
1200 insist (successors br = [| bb02 |]) ;
1201 insist (is_conditional br = false) ;
1202 insist (get_branch br = Some (`Unconditional bb02)) ;
12001203 end;
12011204
12021205 group "cond_br"; begin
12051208 let bb03 = append_block context "Bb03" fn in
12061209 let b = builder_at_end context bb03 in
12071210 let cond = build_trunc p1 i1_type "build_br" b in
1208 ignore (build_cond_br cond bb03 bb00 b)
1211 let br = build_cond_br cond bb03 bb00 b in
1212 insist (num_successors br = 2) ;
1213 insist (successor br 0 = bb03) ;
1214 insist (successor br 1 = bb00) ;
1215 insist (is_conditional br = true) ;
1216 insist (get_branch br = Some (`Conditional (cond, bb03, bb00))) ;
12091217 end;
12101218
12111219 group "switch"; begin
12211229 ignore (add_case si (const_int i32_type 2) bb2);
12221230 insist (switch_default_dest si = bb3);
12231231 end;
1232 insist (num_successors si = 2) ;
1233 insist (get_branch si = None) ;
12241234 end;
12251235
12261236 group "malloc/free"; begin