Skip to content

Commit d732a32

Browse files
authored
[RemoveDIs] C API: Add before-dbg-record versions of IRBuilder position funcs (#92417)
Add `LLVMPositionBuilderBeforeDbgRecords` and `LLVMPositionBuilderBeforeInstrAndDbgRecords` to `llvm/include/llvm-c/Core.h` which behave the same as `LLVMPositionBuilder` and `LVMPositionBuilderBefore` except that the position is set before debug records attached to the target instruction (the existing functions set the insertion point to after any attached debug records). More info on debug records and the migration towards using them can be found here: https://llvm.org/docs/RemoveDIsDebugInfo.html The distinction is important in some situations. An important example is when inserting a phi before another instruction which has debug records attached to it (these come "before" the instruction). Inserting before the instruction but after the debug records would result in having debug records before a phi, which is illegal. That results in an assertion failure: `llvm/lib/IR/Instruction.cpp:166: Assertion '!isa<PHINode>(this) && "Inserting PHI after debug-records!"' failed.` In llvm (C++) we've added bit to instruction iterators that carries around the extra information. Adding dedicated functions seemed like the least invasive and least suprising way to update the C API. Update llvm/tools/llvm-c-test/debuginfo.c to test this functionality. Update the OCaml bindings, the migration docs and release notes.
1 parent 26224ca commit d732a32

File tree

11 files changed

+111
-7
lines changed

11 files changed

+111
-7
lines changed

llvm/bindings/ocaml/llvm/llvm.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,9 @@ external delete_instruction : llvalue -> unit = "llvm_delete_instruction"
11351135
external builder : llcontext -> llbuilder = "llvm_builder"
11361136
external position_builder : (llbasicblock, llvalue) llpos -> llbuilder -> unit
11371137
= "llvm_position_builder"
1138+
external position_builder_before_dbg_records : (llbasicblock, llvalue) llpos ->
1139+
llbuilder -> unit
1140+
= "llvm_position_builder_before_dbg_records"
11381141
external insertion_block : llbuilder -> llbasicblock = "llvm_insertion_block"
11391142
external insert_into_builder : llvalue -> string -> llbuilder -> unit
11401143
= "llvm_insert_into_builder"
@@ -1148,6 +1151,8 @@ let builder_before context i = builder_at context (Before i)
11481151
let builder_at_end context bb = builder_at context (At_end bb)
11491152

11501153
let position_before i = position_builder (Before i)
1154+
let position_before_dbg_records i =
1155+
position_builder_before_dbg_records (Before i)
11511156
let position_at_end bb = position_builder (At_end bb)
11521157

11531158

llvm/bindings/ocaml/llvm/llvm.mli

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,10 +1874,22 @@ val builder_at_end : llcontext -> llbasicblock -> llbuilder
18741874
See the constructor for [llvm::LLVMBuilder]. *)
18751875
val position_builder : (llbasicblock, llvalue) llpos -> llbuilder -> unit
18761876

1877+
(** [position_builder_before_dbg_records ip bb before_dbg_records] moves the
1878+
instruction builder [bb] to the position [ip], before any debug records
1879+
there.
1880+
See the constructor for [llvm::LLVMBuilder]. *)
1881+
val position_builder_before_dbg_records : (llbasicblock, llvalue) llpos ->
1882+
llbuilder -> unit
1883+
18771884
(** [position_before ins b] moves the instruction builder [b] to before the
18781885
instruction [isn]. See the method [llvm::LLVMBuilder::SetInsertPoint]. *)
18791886
val position_before : llvalue -> llbuilder -> unit
18801887

1888+
(** [position_before_dbg_records ins b] moves the instruction builder [b]
1889+
to before the instruction [isn] and any debug records attached to it.
1890+
See the method [llvm::LLVMBuilder::SetInsertPoint]. *)
1891+
val position_before_dbg_records : llvalue -> llbuilder -> unit
1892+
18811893
(** [position_at_end bb b] moves the instruction builder [b] to the end of the
18821894
basic block [bb]. See the method [llvm::LLVMBuilder::SetInsertPoint]. *)
18831895
val position_at_end : llbasicblock -> llbuilder -> unit

llvm/bindings/ocaml/llvm/llvm_ocaml.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,18 @@ value llvm_builder(value C) {
20042004
return alloc_builder(LLVMCreateBuilderInContext(Context_val(C)));
20052005
}
20062006

2007+
/* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
2008+
value llvm_position_builder_before_dbg_records(value Pos, value B) {
2009+
if (Tag_val(Pos) == 0) {
2010+
LLVMBasicBlockRef BB = BasicBlock_val(Field(Pos, 0));
2011+
LLVMPositionBuilderAtEnd(Builder_val(B), BB);
2012+
} else {
2013+
LLVMValueRef I = Value_val(Field(Pos, 0));
2014+
LLVMPositionBuilderBeforeInstrAndDbgRecords(Builder_val(B), I);
2015+
}
2016+
return Val_unit;
2017+
}
2018+
20072019
/* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
20082020
value llvm_position_builder(value Pos, value B) {
20092021
if (Tag_val(Pos) == 0) {

llvm/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ Changes to the C API
214214
* ``LLVMConstICmp``
215215
* ``LLVMConstFCmp``
216216

217+
* Added ``LLVMPositionBuilderBeforeDbgRecords`` and ``LLVMPositionBuilderBeforeInstrAndDbgRecords``. Same as ``LLVMPositionBuilder`` and ``LLVMPositionBuilderBefore`` except the insertion position is set to before the debug records that precede the target instruction. See the `debug info migration guide <https://llvm.org/docs/RemoveDIsDebugInfo.html>`_ for more info. ``LLVMPositionBuilder`` and ``LLVMPositionBuilderBefore`` are unchanged; they insert before the indicated instruction but after any attached debug records.
218+
217219
Changes to the CodeGen infrastructure
218220
-------------------------------------
219221

llvm/docs/RemoveDIsDebugInfo.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ For a more in-depth overview of how to update existing code to support debug rec
3636

3737
# C-API changes
3838

39-
All the functions that have been added are temporary and will be deprecated in the future. The intention is that they'll help downstream projects adapt during the transition period.
39+
Some new functions that have been added are temporary and will be deprecated in the future. The intention is that they'll help downstream projects adapt during the transition period.
4040

4141
```
4242
New functions (all to be deprecated)
@@ -60,8 +60,20 @@ LLVMDIBuilderInsertDeclareBefore # Insert a debug record (new debug info forma
6060
LLVMDIBuilderInsertDeclareAtEnd # Same as above.
6161
LLVMDIBuilderInsertDbgValueBefore # Same as above.
6262
LLVMDIBuilderInsertDbgValueAtEnd # Same as above.
63+
64+
New functions (no plans to deprecate)
65+
----------------------------------
66+
LLVMPositionBuilderBeforeDbgRecords # See info below.
67+
LLVMPositionBuilderBeforeInstrAndDbgRecords # See info below.
6368
```
6469

70+
`LLVMPositionBuilderBeforeDbgRecords` and `LLVMPositionBuilderBeforeInstrAndDbgRecords` behave the same as `LLVMPositionBuilder` and `LLVMPositionBuilderBefore` except the insertion position is set before the debug records that precede the target instruction. Note that this doesn't mean that debug intrinsics before the chosen instruction are skipped, only debug records (which unlike debug records are not themselves instructions).
71+
72+
If you don't know which function to call then follow this rule:
73+
If you are trying to insert at the start of a block, or purposfully skip debug intrinsics to determine the insertion point for any other reason, then call the new functions.
74+
75+
`LLVMPositionBuilder` and `LLVMPositionBuilderBefore` are unchanged. They insert before the indicated instruction but after any attached debug records.
76+
6577
# The new "Debug Record" model
6678

6779
Below is a brief overview of the new representation that replaces debug intrinsics; for an instructive guide on updating old code, see [here](#how-to-update-existing-code).

llvm/include/llvm-c/Core.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3951,9 +3951,28 @@ const unsigned *LLVMGetIndices(LLVMValueRef Inst);
39513951

39523952
LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C);
39533953
LLVMBuilderRef LLVMCreateBuilder(void);
3954+
/**
3955+
* Set the builder poisiton before Instr but after any attached debug records,
3956+
* or if Instr is null set the position to the end of Block.
3957+
*/
39543958
void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block,
39553959
LLVMValueRef Instr);
3960+
/**
3961+
* Set the builder poisiton before Instr and any attached debug records,
3962+
* or if Instr is null set the position to the end of Block.
3963+
*/
3964+
void LLVMPositionBuilderBeforeDbgRecords(LLVMBuilderRef Builder,
3965+
LLVMBasicBlockRef Block,
3966+
LLVMValueRef Inst);
3967+
/**
3968+
* Set the builder poisiton before Instr but after any attached debug records.
3969+
*/
39563970
void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr);
3971+
/**
3972+
* Set the builder poisiton before Instr and any attached debug records.
3973+
*/
3974+
void LLVMPositionBuilderBeforeInstrAndDbgRecords(LLVMBuilderRef Builder,
3975+
LLVMValueRef Instr);
39573976
void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block);
39583977
LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder);
39593978
void LLVMClearInsertionPosition(LLVMBuilderRef Builder);

llvm/lib/IR/Core.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3137,16 +3137,35 @@ LLVMBuilderRef LLVMCreateBuilder(void) {
31373137
return LLVMCreateBuilderInContext(LLVMGetGlobalContext());
31383138
}
31393139

3140+
static void LLVMPositionBuilderImpl(IRBuilder<> *Builder, BasicBlock *Block,
3141+
Instruction *Instr, bool BeforeDbgRecords) {
3142+
BasicBlock::iterator I = Instr ? Instr->getIterator() : Block->end();
3143+
I.setHeadBit(BeforeDbgRecords);
3144+
Builder->SetInsertPoint(Block, I);
3145+
}
3146+
31403147
void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block,
31413148
LLVMValueRef Instr) {
3142-
BasicBlock *BB = unwrap(Block);
3143-
auto I = Instr ? unwrap<Instruction>(Instr)->getIterator() : BB->end();
3144-
unwrap(Builder)->SetInsertPoint(BB, I);
3149+
return LLVMPositionBuilderImpl(unwrap(Builder), unwrap(Block),
3150+
unwrap<Instruction>(Instr), false);
3151+
}
3152+
3153+
void LLVMPositionBuilderBeforeDbgRecords(LLVMBuilderRef Builder,
3154+
LLVMBasicBlockRef Block,
3155+
LLVMValueRef Instr) {
3156+
return LLVMPositionBuilderImpl(unwrap(Builder), unwrap(Block),
3157+
unwrap<Instruction>(Instr), true);
31453158
}
31463159

31473160
void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr) {
31483161
Instruction *I = unwrap<Instruction>(Instr);
3149-
unwrap(Builder)->SetInsertPoint(I->getParent(), I->getIterator());
3162+
return LLVMPositionBuilderImpl(unwrap(Builder), I->getParent(), I, false);
3163+
}
3164+
3165+
void LLVMPositionBuilderBeforeInstrAndDbgRecords(LLVMBuilderRef Builder,
3166+
LLVMValueRef Instr) {
3167+
Instruction *I = unwrap<Instruction>(Instr);
3168+
return LLVMPositionBuilderImpl(unwrap(Builder), I->getParent(), I, true);
31503169
}
31513170

31523171
void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block) {

llvm/test/Bindings/OCaml/core.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ let test_builder () =
11501150
(* CHECK: ret{{.*}}P1
11511151
*)
11521152
let ret = build_ret p1 atentry in
1153-
position_before ret atentry
1153+
position_before_dbg_records ret atentry
11541154
end;
11551155

11561156
(* see test/Feature/exception.ll *)

llvm/test/Bindings/llvm-c/debug_info.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
; CHECK-NEXT: call void @llvm.dbg.declare(metadata i64 0, metadata !40, metadata !DIExpression()), !dbg !43
1111
; CHECK-NEXT: br label %vars
1212
; CHECK: vars:
13+
; CHECK-NEXT: %p1 = phi i64 [ 0, %entry ]
14+
; CHECK-NEXT: %p2 = phi i64 [ 0, %entry ]
1315
; CHECK-NEXT: call void @llvm.dbg.value(metadata i64 0, metadata !41, metadata !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)), !dbg !44
16+
; CHECK-NEXT: %a = add i64 %p1, %p2
1417
; CHECK-NEXT: ret i64 0
1518
; CHECK-NEXT: }
1619

llvm/test/Bindings/llvm-c/debug_info_new_format.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
; CHECK-NEXT: #dbg_declare(i64 0, !40, !DIExpression(), !43)
1212
; CHECK-NEXT: br label %vars
1313
; CHECK: vars:
14+
; CHECK-NEXT: %p1 = phi i64 [ 0, %entry ]
15+
; CHECK-NEXT: %p2 = phi i64 [ 0, %entry ]
1416
; CHECK-NEXT: #dbg_value(i64 0, !41, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !44)
17+
; CHECK-NEXT: %a = add i64 %p1, %p2
1518
; CHECK-NEXT: ret i64 0
1619
; CHECK-NEXT: }
1720

llvm/tools/llvm-c-test/debuginfo.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,24 @@ int llvm_test_dibuilder(bool NewDebugInfoFormat) {
228228
LLVMPositionBuilderAtEnd(Builder, FooVarBlock);
229229
LLVMTypeRef I64 = LLVMInt64TypeInContext(Ctx);
230230
LLVMValueRef Zero = LLVMConstInt(I64, 0, false);
231-
LLVMBuildRet(Builder, Zero);
231+
LLVMValueRef Ret = LLVMBuildRet(Builder, Zero);
232+
233+
// Insert a `phi` before the `ret`. In the new debug info mode we need to
234+
// be careful to insert before debug records too, else the debug records
235+
// will come before the `phi` (and be absorbed onto it) which is an invalid
236+
// state.
237+
LLVMValueRef InsertPos = LLVMGetFirstInstruction(FooVarBlock);
238+
LLVMPositionBuilderBeforeInstrAndDbgRecords(Builder, InsertPos);
239+
LLVMValueRef Phi1 = LLVMBuildPhi(Builder, I64, "p1");
240+
LLVMAddIncoming(Phi1, &Zero, &FooEntryBlock, 1);
241+
// Do the same again using the other position-setting function.
242+
LLVMPositionBuilderBeforeDbgRecords(Builder, FooVarBlock, InsertPos);
243+
LLVMValueRef Phi2 = LLVMBuildPhi(Builder, I64, "p2");
244+
LLVMAddIncoming(Phi2, &Zero, &FooEntryBlock, 1);
245+
// Insert a non-phi before the `ret` but not before the debug records to
246+
// test that works as expected.
247+
LLVMPositionBuilder(Builder, FooVarBlock, Ret);
248+
LLVMBuildAdd(Builder, Phi1, Phi2, "a");
232249

233250
char *MStr = LLVMPrintModuleToString(M);
234251
puts(MStr);

0 commit comments

Comments
 (0)