Skip to content

Commit eb7d535

Browse files
authored
[LLVM] Add a C API for creating instructions with custom syncscopes. (#104775)
Another upstreaming of C API extensions we have in Julia/LLVM.jl. Although [we went](JuliaLLVM/LLVM.jl#431) with a string-based API there, here I'm proposing something that's similar to existing metadata/attribute APIs: - explicit functions to map syncscope names to IDs, and back - `LLVM*SyncScope` versions of builder APIs that already take a `SingleThread` argument: atomic rmw, atomic xchg, fence - `LLVMGetAtomicSyncScopeID` and `LLVMSetAtomicSyncScopeID` for other atomic instructions - testing through `llvm-c-test`'s `--echo` functionality
1 parent 7cfc9a3 commit eb7d535

File tree

10 files changed

+210
-56
lines changed

10 files changed

+210
-56
lines changed

llvm/docs/ReleaseNotes.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,19 @@ Changes to the C API
169169
* It is now also possible to run the new pass manager on a single function, by calling
170170
``LLVMRunPassesOnFunction`` instead of ``LLVMRunPasses``.
171171

172+
* Support for creating instructions with custom synchronization scopes has been added:
173+
174+
* ``LLVMGetSyncScopeID`` to map a synchronization scope name to an ID.
175+
* ``LLVMBuildFenceSyncScope``, ``LLVMBuildAtomicRMWSyncScope`` and
176+
``LLVMBuildAtomicCmpXchgSyncScope`` versions of the existing builder functions
177+
with an additional synchronization scope ID parameter.
178+
* ``LLVMGetAtomicSyncScopeID`` and ``LLVMSetAtomicSyncScopeID`` to get and set the
179+
synchronization scope of any atomic instruction.
180+
* ``LLVMIsAtomic`` to check if an instruction is atomic, for use with the above functions.
181+
Because of backwards compatibility, ``LLVMIsAtomicSingleThread`` and
182+
``LLVMSetAtomicSingleThread`` continue to work with any instruction type.
183+
184+
172185
Changes to the CodeGen infrastructure
173186
-------------------------------------
174187

llvm/include/llvm-c/Core.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,11 @@ unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char *Name,
646646
unsigned SLen);
647647
unsigned LLVMGetMDKindID(const char *Name, unsigned SLen);
648648

649+
/**
650+
* Maps a synchronization scope name to a ID unique within this context.
651+
*/
652+
unsigned LLVMGetSyncScopeID(LLVMContextRef C, const char *Name, size_t SLen);
653+
649654
/**
650655
* Return an unique id given the name of a enum attribute,
651656
* or 0 if no attribute by that name exists.
@@ -4592,15 +4597,28 @@ LLVMValueRef LLVMBuildPtrDiff2(LLVMBuilderRef, LLVMTypeRef ElemTy,
45924597
const char *Name);
45934598
LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering ordering,
45944599
LLVMBool singleThread, const char *Name);
4600+
LLVMValueRef LLVMBuildFenceSyncScope(LLVMBuilderRef B,
4601+
LLVMAtomicOrdering ordering, unsigned SSID,
4602+
const char *Name);
45954603
LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B, LLVMAtomicRMWBinOp op,
45964604
LLVMValueRef PTR, LLVMValueRef Val,
45974605
LLVMAtomicOrdering ordering,
45984606
LLVMBool singleThread);
4607+
LLVMValueRef LLVMBuildAtomicRMWSyncScope(LLVMBuilderRef B,
4608+
LLVMAtomicRMWBinOp op,
4609+
LLVMValueRef PTR, LLVMValueRef Val,
4610+
LLVMAtomicOrdering ordering,
4611+
unsigned SSID);
45994612
LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr,
46004613
LLVMValueRef Cmp, LLVMValueRef New,
46014614
LLVMAtomicOrdering SuccessOrdering,
46024615
LLVMAtomicOrdering FailureOrdering,
46034616
LLVMBool SingleThread);
4617+
LLVMValueRef LLVMBuildAtomicCmpXchgSyncScope(LLVMBuilderRef B, LLVMValueRef Ptr,
4618+
LLVMValueRef Cmp, LLVMValueRef New,
4619+
LLVMAtomicOrdering SuccessOrdering,
4620+
LLVMAtomicOrdering FailureOrdering,
4621+
unsigned SSID);
46044622

46054623
/**
46064624
* Get the number of elements in the mask of a ShuffleVector instruction.
@@ -4625,6 +4643,22 @@ int LLVMGetMaskValue(LLVMValueRef ShuffleVectorInst, unsigned Elt);
46254643
LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst);
46264644
void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool SingleThread);
46274645

4646+
/**
4647+
* Returns whether an instruction is an atomic instruction, e.g., atomicrmw,
4648+
* cmpxchg, fence, or loads and stores with atomic ordering.
4649+
*/
4650+
LLVMBool LLVMIsAtomic(LLVMValueRef Inst);
4651+
4652+
/**
4653+
* Returns the synchronization scope ID of an atomic instruction.
4654+
*/
4655+
unsigned LLVMGetAtomicSyncScopeID(LLVMValueRef AtomicInst);
4656+
4657+
/**
4658+
* Sets the synchronization scope ID of an atomic instruction.
4659+
*/
4660+
void LLVMSetAtomicSyncScopeID(LLVMValueRef AtomicInst, unsigned SSID);
4661+
46284662
LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst);
46294663
void LLVMSetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst,
46304664
LLVMAtomicOrdering Ordering);

llvm/include/llvm/IR/Instructions.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4942,6 +4942,23 @@ inline std::optional<SyncScope::ID> getAtomicSyncScopeID(const Instruction *I) {
49424942
llvm_unreachable("unhandled atomic operation");
49434943
}
49444944

4945+
/// A helper function that sets an atomic operation's sync scope.
4946+
inline void setAtomicSyncScopeID(Instruction *I, SyncScope::ID SSID) {
4947+
assert(I->isAtomic());
4948+
if (auto *AI = dyn_cast<LoadInst>(I))
4949+
AI->setSyncScopeID(SSID);
4950+
else if (auto *AI = dyn_cast<StoreInst>(I))
4951+
AI->setSyncScopeID(SSID);
4952+
else if (auto *AI = dyn_cast<FenceInst>(I))
4953+
AI->setSyncScopeID(SSID);
4954+
else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I))
4955+
AI->setSyncScopeID(SSID);
4956+
else if (auto *AI = dyn_cast<AtomicRMWInst>(I))
4957+
AI->setSyncScopeID(SSID);
4958+
else
4959+
llvm_unreachable("unhandled atomic operation");
4960+
}
4961+
49454962
//===----------------------------------------------------------------------===//
49464963
// FreezeInst Class
49474964
//===----------------------------------------------------------------------===//

llvm/lib/IR/Core.cpp

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/IR/GlobalVariable.h"
2525
#include "llvm/IR/IRBuilder.h"
2626
#include "llvm/IR/InlineAsm.h"
27+
#include "llvm/IR/Instructions.h"
2728
#include "llvm/IR/IntrinsicInst.h"
2829
#include "llvm/IR/LLVMContext.h"
2930
#include "llvm/IR/LegacyPassManager.h"
@@ -146,6 +147,10 @@ unsigned LLVMGetMDKindID(const char *Name, unsigned SLen) {
146147
return LLVMGetMDKindIDInContext(LLVMGetGlobalContext(), Name, SLen);
147148
}
148149

150+
unsigned LLVMGetSyncScopeID(LLVMContextRef C, const char *Name, size_t SLen) {
151+
return unwrap(C)->getOrInsertSyncScopeID(StringRef(Name, SLen));
152+
}
153+
149154
unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen) {
150155
return Attribute::getAttrKindFromName(StringRef(Name, SLen));
151156
}
@@ -3957,8 +3962,6 @@ static LLVMAtomicRMWBinOp mapToLLVMRMWBinOp(AtomicRMWInst::BinOp BinOp) {
39573962
llvm_unreachable("Invalid AtomicRMWBinOp value!");
39583963
}
39593964

3960-
// TODO: Should this and other atomic instructions support building with
3961-
// "syncscope"?
39623965
LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering Ordering,
39633966
LLVMBool isSingleThread, const char *Name) {
39643967
return wrap(
@@ -3968,6 +3971,13 @@ LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering Ordering,
39683971
Name));
39693972
}
39703973

3974+
LLVMValueRef LLVMBuildFenceSyncScope(LLVMBuilderRef B,
3975+
LLVMAtomicOrdering Ordering, unsigned SSID,
3976+
const char *Name) {
3977+
return wrap(
3978+
unwrap(B)->CreateFence(mapFromLLVMOrdering(Ordering), SSID, Name));
3979+
}
3980+
39713981
LLVMValueRef LLVMBuildGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
39723982
LLVMValueRef Pointer, LLVMValueRef *Indices,
39733983
unsigned NumIndices, const char *Name) {
@@ -4317,6 +4327,17 @@ LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op,
43174327
singleThread ? SyncScope::SingleThread : SyncScope::System));
43184328
}
43194329

4330+
LLVMValueRef LLVMBuildAtomicRMWSyncScope(LLVMBuilderRef B,
4331+
LLVMAtomicRMWBinOp op,
4332+
LLVMValueRef PTR, LLVMValueRef Val,
4333+
LLVMAtomicOrdering ordering,
4334+
unsigned SSID) {
4335+
AtomicRMWInst::BinOp intop = mapFromLLVMRMWBinOp(op);
4336+
return wrap(unwrap(B)->CreateAtomicRMW(intop, unwrap(PTR), unwrap(Val),
4337+
MaybeAlign(),
4338+
mapFromLLVMOrdering(ordering), SSID));
4339+
}
4340+
43204341
LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr,
43214342
LLVMValueRef Cmp, LLVMValueRef New,
43224343
LLVMAtomicOrdering SuccessOrdering,
@@ -4330,6 +4351,17 @@ LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr,
43304351
singleThread ? SyncScope::SingleThread : SyncScope::System));
43314352
}
43324353

4354+
LLVMValueRef LLVMBuildAtomicCmpXchgSyncScope(LLVMBuilderRef B, LLVMValueRef Ptr,
4355+
LLVMValueRef Cmp, LLVMValueRef New,
4356+
LLVMAtomicOrdering SuccessOrdering,
4357+
LLVMAtomicOrdering FailureOrdering,
4358+
unsigned SSID) {
4359+
return wrap(unwrap(B)->CreateAtomicCmpXchg(
4360+
unwrap(Ptr), unwrap(Cmp), unwrap(New), MaybeAlign(),
4361+
mapFromLLVMOrdering(SuccessOrdering),
4362+
mapFromLLVMOrdering(FailureOrdering), SSID));
4363+
}
4364+
43334365
unsigned LLVMGetNumMaskElements(LLVMValueRef SVInst) {
43344366
Value *P = unwrap(SVInst);
43354367
ShuffleVectorInst *I = cast<ShuffleVectorInst>(P);
@@ -4344,34 +4376,39 @@ int LLVMGetMaskValue(LLVMValueRef SVInst, unsigned Elt) {
43444376

43454377
int LLVMGetUndefMaskElem(void) { return PoisonMaskElem; }
43464378

4379+
LLVMBool LLVMIsAtomic(LLVMValueRef Inst) {
4380+
return unwrap<Instruction>(Inst)->isAtomic();
4381+
}
4382+
43474383
LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst) {
4348-
Value *P = unwrap(AtomicInst);
4384+
// Backwards compatibility: return false for non-atomic instructions
4385+
Instruction *I = unwrap<Instruction>(AtomicInst);
4386+
if (!I->isAtomic())
4387+
return 0;
43494388

4350-
if (AtomicRMWInst *I = dyn_cast<AtomicRMWInst>(P))
4351-
return I->getSyncScopeID() == SyncScope::SingleThread;
4352-
else if (FenceInst *FI = dyn_cast<FenceInst>(P))
4353-
return FI->getSyncScopeID() == SyncScope::SingleThread;
4354-
else if (StoreInst *SI = dyn_cast<StoreInst>(P))
4355-
return SI->getSyncScopeID() == SyncScope::SingleThread;
4356-
else if (LoadInst *LI = dyn_cast<LoadInst>(P))
4357-
return LI->getSyncScopeID() == SyncScope::SingleThread;
4358-
return cast<AtomicCmpXchgInst>(P)->getSyncScopeID() ==
4359-
SyncScope::SingleThread;
4389+
return *getAtomicSyncScopeID(I) == SyncScope::SingleThread;
43604390
}
43614391

43624392
void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool NewValue) {
4363-
Value *P = unwrap(AtomicInst);
4393+
// Backwards compatibility: ignore non-atomic instructions
4394+
Instruction *I = unwrap<Instruction>(AtomicInst);
4395+
if (!I->isAtomic())
4396+
return;
4397+
43644398
SyncScope::ID SSID = NewValue ? SyncScope::SingleThread : SyncScope::System;
4399+
setAtomicSyncScopeID(I, SSID);
4400+
}
43654401

4366-
if (AtomicRMWInst *I = dyn_cast<AtomicRMWInst>(P))
4367-
return I->setSyncScopeID(SSID);
4368-
else if (FenceInst *FI = dyn_cast<FenceInst>(P))
4369-
return FI->setSyncScopeID(SSID);
4370-
else if (StoreInst *SI = dyn_cast<StoreInst>(P))
4371-
return SI->setSyncScopeID(SSID);
4372-
else if (LoadInst *LI = dyn_cast<LoadInst>(P))
4373-
return LI->setSyncScopeID(SSID);
4374-
return cast<AtomicCmpXchgInst>(P)->setSyncScopeID(SSID);
4402+
unsigned LLVMGetAtomicSyncScopeID(LLVMValueRef AtomicInst) {
4403+
Instruction *I = unwrap<Instruction>(AtomicInst);
4404+
assert(I->isAtomic() && "Expected an atomic instruction");
4405+
return *getAtomicSyncScopeID(I);
4406+
}
4407+
4408+
void LLVMSetAtomicSyncScopeID(LLVMValueRef AtomicInst, unsigned SSID) {
4409+
Instruction *I = unwrap<Instruction>(AtomicInst);
4410+
assert(I->isAtomic() && "Expected an atomic instruction");
4411+
setAtomicSyncScopeID(I, SSID);
43754412
}
43764413

43774414
LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst) {

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,23 @@ define void @memops(ptr %ptr) {
216216
%b = load volatile i8, ptr %ptr
217217
%c = load i8, ptr %ptr, align 8
218218
%d = load atomic i8, ptr %ptr acquire, align 32
219+
%e = load atomic i8, ptr %ptr syncscope("singlethread") acquire, align 32
219220
store i8 0, ptr %ptr
220221
store volatile i8 0, ptr %ptr
221222
store i8 0, ptr %ptr, align 8
222223
store atomic i8 0, ptr %ptr release, align 32
223-
%e = atomicrmw add ptr %ptr, i8 0 monotonic, align 1
224-
%f = atomicrmw volatile xchg ptr %ptr, i8 0 acq_rel, align 8
225-
%g = cmpxchg ptr %ptr, i8 1, i8 2 seq_cst acquire, align 1
226-
%h = cmpxchg weak ptr %ptr, i8 1, i8 2 seq_cst acquire, align 8
227-
%i = cmpxchg volatile ptr %ptr, i8 1, i8 2 monotonic monotonic, align 16
224+
store atomic i8 0, ptr %ptr syncscope("singlethread") release, align 32
225+
%f = atomicrmw add ptr %ptr, i8 0 monotonic, align 1
226+
%g = atomicrmw volatile xchg ptr %ptr, i8 0 acq_rel, align 8
227+
%h = atomicrmw volatile xchg ptr %ptr, i8 0 syncscope("singlethread") acq_rel, align 8
228+
%i = atomicrmw volatile xchg ptr %ptr, i8 0 syncscope("agent") acq_rel, align 8
229+
%j = cmpxchg ptr %ptr, i8 1, i8 2 seq_cst acquire, align 1
230+
%k = cmpxchg weak ptr %ptr, i8 1, i8 2 seq_cst acquire, align 8
231+
%l = cmpxchg volatile ptr %ptr, i8 1, i8 2 monotonic monotonic, align 16
232+
%m = cmpxchg volatile ptr %ptr, i8 1, i8 2 syncscope("singlethread") monotonic monotonic, align 16
233+
%n = cmpxchg volatile ptr %ptr, i8 1, i8 2 syncscope("agent") monotonic monotonic, align 16
234+
fence syncscope("singlethread") acquire
235+
fence syncscope("agent") acquire
228236
ret void
229237
}
230238

llvm/tools/llvm-c-test/attributes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
int llvm_test_function_attributes(void) {
2121
LLVMEnablePrettyStackTrace();
2222

23-
LLVMModuleRef M = llvm_load_module(false, true);
23+
LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), false, true);
2424

2525
LLVMValueRef F = LLVMGetFirstFunction(M);
2626
while (F) {
@@ -49,7 +49,7 @@ int llvm_test_function_attributes(void) {
4949
int llvm_test_callsite_attributes(void) {
5050
LLVMEnablePrettyStackTrace();
5151

52-
LLVMModuleRef M = llvm_load_module(false, true);
52+
LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), false, true);
5353

5454
LLVMValueRef F = LLVMGetFirstFunction(M);
5555
while (F) {

llvm/tools/llvm-c-test/echo.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ struct FunCloner {
520520
check_value_kind(Src, LLVMInstructionValueKind);
521521
if (!LLVMIsAInstruction(Src))
522522
report_fatal_error("Expected an instruction");
523+
LLVMContextRef Ctx = LLVMGetTypeContext(LLVMTypeOf(Src));
523524

524525
size_t NameLen;
525526
const char *Name = LLVMGetValueName2(Src, &NameLen);
@@ -754,7 +755,8 @@ struct FunCloner {
754755
LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
755756
LLVMSetOrdering(Dst, LLVMGetOrdering(Src));
756757
LLVMSetVolatile(Dst, LLVMGetVolatile(Src));
757-
LLVMSetAtomicSingleThread(Dst, LLVMIsAtomicSingleThread(Src));
758+
if (LLVMIsAtomic(Src))
759+
LLVMSetAtomicSyncScopeID(Dst, LLVMGetAtomicSyncScopeID(Src));
758760
break;
759761
}
760762
case LLVMStore: {
@@ -764,7 +766,8 @@ struct FunCloner {
764766
LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
765767
LLVMSetOrdering(Dst, LLVMGetOrdering(Src));
766768
LLVMSetVolatile(Dst, LLVMGetVolatile(Src));
767-
LLVMSetAtomicSingleThread(Dst, LLVMIsAtomicSingleThread(Src));
769+
if (LLVMIsAtomic(Src))
770+
LLVMSetAtomicSyncScopeID(Dst, LLVMGetAtomicSyncScopeID(Src));
768771
break;
769772
}
770773
case LLVMGetElementPtr: {
@@ -785,8 +788,8 @@ struct FunCloner {
785788
LLVMValueRef Val = CloneValue(LLVMGetOperand(Src, 1));
786789
LLVMAtomicRMWBinOp BinOp = LLVMGetAtomicRMWBinOp(Src);
787790
LLVMAtomicOrdering Ord = LLVMGetOrdering(Src);
788-
LLVMBool SingleThread = LLVMIsAtomicSingleThread(Src);
789-
Dst = LLVMBuildAtomicRMW(Builder, BinOp, Ptr, Val, Ord, SingleThread);
791+
Dst = LLVMBuildAtomicRMWSyncScope(Builder, BinOp, Ptr, Val, Ord,
792+
LLVMGetAtomicSyncScopeID(Src));
790793
LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
791794
LLVMSetVolatile(Dst, LLVMGetVolatile(Src));
792795
LLVMSetValueName2(Dst, Name, NameLen);
@@ -798,10 +801,8 @@ struct FunCloner {
798801
LLVMValueRef New = CloneValue(LLVMGetOperand(Src, 2));
799802
LLVMAtomicOrdering Succ = LLVMGetCmpXchgSuccessOrdering(Src);
800803
LLVMAtomicOrdering Fail = LLVMGetCmpXchgFailureOrdering(Src);
801-
LLVMBool SingleThread = LLVMIsAtomicSingleThread(Src);
802-
803-
Dst = LLVMBuildAtomicCmpXchg(Builder, Ptr, Cmp, New, Succ, Fail,
804-
SingleThread);
804+
Dst = LLVMBuildAtomicCmpXchgSyncScope(
805+
Builder, Ptr, Cmp, New, Succ, Fail, LLVMGetAtomicSyncScopeID(Src));
805806
LLVMSetAlignment(Dst, LLVMGetAlignment(Src));
806807
LLVMSetVolatile(Dst, LLVMGetVolatile(Src));
807808
LLVMSetWeak(Dst, LLVMGetWeak(Src));
@@ -992,8 +993,8 @@ struct FunCloner {
992993
}
993994
case LLVMFence: {
994995
LLVMAtomicOrdering Ordering = LLVMGetOrdering(Src);
995-
LLVMBool IsSingleThreaded = LLVMIsAtomicSingleThread(Src);
996-
Dst = LLVMBuildFence(Builder, Ordering, IsSingleThreaded, Name);
996+
Dst = LLVMBuildFenceSyncScope(Builder, Ordering,
997+
LLVMGetAtomicSyncScopeID(Src), Name);
997998
break;
998999
}
9991000
case LLVMZExt: {
@@ -1059,7 +1060,6 @@ struct FunCloner {
10591060
if (LLVMCanValueUseFastMathFlags(Src))
10601061
LLVMSetFastMathFlags(Dst, LLVMGetFastMathFlags(Src));
10611062

1062-
auto Ctx = LLVMGetModuleContext(M);
10631063
size_t NumMetadataEntries;
10641064
auto *AllMetadata =
10651065
LLVMInstructionGetAllMetadataOtherThanDebugLoc(Src,
@@ -1609,12 +1609,12 @@ static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
16091609
int llvm_echo(void) {
16101610
LLVMEnablePrettyStackTrace();
16111611

1612-
LLVMModuleRef Src = llvm_load_module(false, true);
1612+
LLVMContextRef Ctx = LLVMContextCreate();
1613+
LLVMModuleRef Src = llvm_load_module(Ctx, false, true);
16131614
size_t SourceFileLen;
16141615
const char *SourceFileName = LLVMGetSourceFileName(Src, &SourceFileLen);
16151616
size_t ModuleIdentLen;
16161617
const char *ModuleName = LLVMGetModuleIdentifier(Src, &ModuleIdentLen);
1617-
LLVMContextRef Ctx = LLVMContextCreate();
16181618
LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleName, Ctx);
16191619

16201620
LLVMSetSourceFileName(M, SourceFileName, SourceFileLen);

llvm/tools/llvm-c-test/llvm-c-test.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extern "C" {
2424
void llvm_tokenize_stdin(void (*cb)(char **tokens, int ntokens));
2525

2626
// module.c
27-
LLVMModuleRef llvm_load_module(bool Lazy, bool New);
27+
LLVMModuleRef llvm_load_module(LLVMContextRef C, bool Lazy, bool New);
2828
int llvm_module_dump(bool Lazy, bool New);
2929
int llvm_module_list_functions(void);
3030
int llvm_module_list_globals(void);

0 commit comments

Comments
 (0)