@@ -49,6 +49,7 @@ struct FinalLowerGC: private JuliaPassContext {
49
49
Function *queueBindingFunc;
50
50
Function *poolAllocFunc;
51
51
Function *bigAllocFunc;
52
+ Function *allocTypedFunc;
52
53
Instruction *pgcstack;
53
54
54
55
// Lowers a `julia.new_gc_frame` intrinsic.
@@ -205,23 +206,35 @@ Value *FinalLowerGC::lowerGCAllocBytes(CallInst *target, Function &F)
205
206
{
206
207
++GCAllocBytesCount;
207
208
assert (target->arg_size () == 2 );
208
- auto sz = (size_t )cast<ConstantInt>(target->getArgOperand (1 ))->getZExtValue ();
209
- // This is strongly architecture and OS dependent
210
- int osize;
211
- int offset = jl_gc_classify_pools (sz, &osize);
209
+ CallInst *newI;
210
+
212
211
IRBuilder<> builder (target);
213
212
builder.SetCurrentDebugLocation (target->getDebugLoc ());
214
213
auto ptls = target->getArgOperand (0 );
215
- CallInst *newI;
216
- if (offset < 0 ) {
217
- newI = builder.CreateCall (
218
- bigAllocFunc,
219
- { ptls, ConstantInt::get (getSizeTy (F.getContext ()), sz + sizeof (void *)) });
220
- }
221
- else {
222
- auto pool_offs = ConstantInt::get (Type::getInt32Ty (F.getContext ()), offset);
223
- auto pool_osize = ConstantInt::get (Type::getInt32Ty (F.getContext ()), osize);
224
- newI = builder.CreateCall (poolAllocFunc, { ptls, pool_offs, pool_osize });
214
+ Attribute derefAttr;
215
+
216
+ if (auto CI = dyn_cast<ConstantInt>(target->getArgOperand (1 ))) {
217
+ size_t sz = (size_t )CI->getZExtValue ();
218
+ // This is strongly architecture and OS dependent
219
+ int osize;
220
+ int offset = jl_gc_classify_pools (sz, &osize);
221
+ if (offset < 0 ) {
222
+ newI = builder.CreateCall (
223
+ bigAllocFunc,
224
+ { ptls, ConstantInt::get (getSizeTy (F.getContext ()), sz + sizeof (void *)) });
225
+ derefAttr = Attribute::getWithDereferenceableBytes (F.getContext (), sz + sizeof (void *));
226
+ }
227
+ else {
228
+ auto pool_offs = ConstantInt::get (Type::getInt32Ty (F.getContext ()), offset);
229
+ auto pool_osize = ConstantInt::get (Type::getInt32Ty (F.getContext ()), osize);
230
+ newI = builder.CreateCall (poolAllocFunc, { ptls, pool_offs, pool_osize });
231
+ derefAttr = Attribute::getWithDereferenceableBytes (F.getContext (), osize);
232
+ }
233
+ } else {
234
+ auto size = builder.CreateZExtOrTrunc (target->getArgOperand (1 ), getSizeTy (F.getContext ()));
235
+ size = builder.CreateAdd (size, ConstantInt::get (getSizeTy (F.getContext ()), sizeof (void *)));
236
+ newI = builder.CreateCall (allocTypedFunc, { ptls, size, ConstantPointerNull::get (Type::getInt8PtrTy (F.getContext ())) });
237
+ derefAttr = Attribute::getWithDereferenceableBytes (F.getContext (), sizeof (void *));
225
238
}
226
239
newI->setAttributes (newI->getCalledFunction ()->getAttributes ());
227
240
newI->takeName (target);
@@ -237,8 +250,9 @@ bool FinalLowerGC::doInitialization(Module &M) {
237
250
queueBindingFunc = getOrDeclare (jl_well_known::GCQueueBinding);
238
251
poolAllocFunc = getOrDeclare (jl_well_known::GCPoolAlloc);
239
252
bigAllocFunc = getOrDeclare (jl_well_known::GCBigAlloc);
253
+ allocTypedFunc = getOrDeclare (jl_well_known::GCAllocTyped);
240
254
241
- GlobalValue *functionList[] = {queueRootFunc, queueBindingFunc, poolAllocFunc, bigAllocFunc};
255
+ GlobalValue *functionList[] = {queueRootFunc, queueBindingFunc, poolAllocFunc, bigAllocFunc, allocTypedFunc };
242
256
unsigned j = 0 ;
243
257
for (unsigned i = 0 ; i < sizeof (functionList) / sizeof (void *); i++) {
244
258
if (!functionList[i])
@@ -254,8 +268,8 @@ bool FinalLowerGC::doInitialization(Module &M) {
254
268
255
269
bool FinalLowerGC::doFinalization (Module &M)
256
270
{
257
- GlobalValue *functionList[] = {queueRootFunc, queueBindingFunc, poolAllocFunc, bigAllocFunc};
258
- queueRootFunc = queueBindingFunc = poolAllocFunc = bigAllocFunc = nullptr ;
271
+ GlobalValue *functionList[] = {queueRootFunc, queueBindingFunc, poolAllocFunc, bigAllocFunc, allocTypedFunc };
272
+ queueRootFunc = queueBindingFunc = poolAllocFunc = bigAllocFunc = allocTypedFunc = nullptr ;
259
273
auto used = M.getGlobalVariable (" llvm.compiler.used" );
260
274
if (!used)
261
275
return false ;
0 commit comments