Skip to content

Commit 5766124

Browse files
committed
[irgen] Add support for alloc_stack [non_nested].
1 parent ac81c4d commit 5766124

File tree

9 files changed

+101
-31
lines changed

9 files changed

+101
-31
lines changed

lib/IRGen/FixedTypeInfo.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,12 @@ class FixedTypeInfo : public TypeInfo {
8282
}
8383

8484
StackAddress allocateStack(IRGenFunction &IGF, SILType T,
85-
const llvm::Twine &name) const override;
86-
void deallocateStack(IRGenFunction &IGF, StackAddress addr, SILType T) const override;
85+
const llvm::Twine &name,
86+
StackAllocationIsNested_t isNested =
87+
StackAllocationIsNested) const override;
88+
void deallocateStack(IRGenFunction &IGF, StackAddress addr, SILType T,
89+
StackAllocationIsNested_t isNested =
90+
StackAllocationIsNested) const override;
8791
void destroyStack(IRGenFunction &IGF, StackAddress addr, SILType T,
8892
bool isOutlined) const override;
8993

lib/IRGen/GenArray.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -638,24 +638,26 @@ class NonFixedArrayTypeInfo final
638638
return nullptr;
639639
}
640640

641-
StackAddress allocateStack(IRGenFunction &IGF, SILType T,
642-
const llvm::Twine &name) const override {
641+
StackAddress
642+
allocateStack(IRGenFunction &IGF, SILType T, const llvm::Twine &name,
643+
StackAllocationIsNested_t isNested) const override {
643644
// Allocate memory on the stack.
644-
auto alloca = IGF.emitDynamicAlloca(T, name);
645+
auto alloca = IGF.emitDynamicStackAllocation(T, isNested, name);
645646
IGF.Builder.CreateLifetimeStart(alloca.getAddressPointer());
646647
return alloca.withAddress(getAddressForPointer(alloca.getAddressPointer()));
647648
}
648649

649-
void deallocateStack(IRGenFunction &IGF, StackAddress stackAddress,
650-
SILType T) const override {
650+
void deallocateStack(IRGenFunction &IGF, StackAddress stackAddress, SILType T,
651+
StackAllocationIsNested_t isNested) const override {
651652
IGF.Builder.CreateLifetimeEnd(stackAddress.getAddress().getAddress());
652-
IGF.emitDeallocateDynamicAlloca(stackAddress);
653+
IGF.emitDynamicStackDeallocation(stackAddress, isNested);
653654
}
654655

655656
void destroyStack(IRGenFunction &IGF, StackAddress stackAddress, SILType T,
656657
bool isOutlined) const override {
657658
emitDestroyCall(IGF, T, stackAddress.getAddress());
658-
deallocateStack(IGF, stackAddress, T);
659+
// For now, just always do nested.
660+
deallocateStack(IGF, stackAddress, T, StackAllocationIsNested);
659661
}
660662

661663
TypeLayoutEntry *

lib/IRGen/GenInit.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ void IRGenModule::emitSILGlobalVariable(SILGlobalVariable *var) {
5959
var->isDefinition() ? ForDefinition : NotForDefinition);
6060
}
6161

62-
StackAddress FixedTypeInfo::allocateStack(IRGenFunction &IGF, SILType T,
63-
const Twine &name) const {
62+
StackAddress
63+
FixedTypeInfo::allocateStack(IRGenFunction &IGF, SILType T, const Twine &name,
64+
StackAllocationIsNested_t isNested) const {
6465
// If the type is known to be empty, don't actually allocate anything.
6566
if (isKnownEmpty(ResilienceExpansion::Maximal)) {
6667
auto addr = getUndefAddress();
@@ -81,7 +82,8 @@ void FixedTypeInfo::destroyStack(IRGenFunction &IGF, StackAddress addr,
8182
}
8283

8384
void FixedTypeInfo::deallocateStack(IRGenFunction &IGF, StackAddress addr,
84-
SILType T) const {
85+
SILType T,
86+
StackAllocationIsNested_t isNested) const {
8587
if (isKnownEmpty(ResilienceExpansion::Maximal))
8688
return;
8789
IGF.Builder.CreateLifetimeEnd(addr.getAddress(), getFixedSize());

lib/IRGen/GenOpaque.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,38 @@ irgen::emitInitializeBufferWithCopyOfBufferCall(IRGenFunction &IGF,
553553
return call;
554554
}
555555

556+
StackAddress IRGenFunction::emitDynamicStackAllocation(
557+
SILType T, StackAllocationIsNested_t isNested, const llvm::Twine &name) {
558+
if (isNested) {
559+
return emitDynamicAlloca(T, name);
560+
}
561+
562+
// First malloc the memory.
563+
auto mallocFn = IGM.getMallocFunctionPointer();
564+
auto *size = emitLoadOfSize(*this, T);
565+
auto *call = Builder.CreateCall(mallocFn, {size});
566+
call->setDoesNotThrow();
567+
call->setCallingConv(IGM.C_CC);
568+
569+
// Then create the dynamic alloca to store the malloc pointer into.
570+
571+
// TODO: Alignment should be platform specific.
572+
auto address = Address(call, IGM.Int8Ty, Alignment(16));
573+
return StackAddress{address};
574+
}
575+
576+
void IRGenFunction::emitDynamicStackDeallocation(
577+
StackAddress address, StackAllocationIsNested_t isNested) {
578+
if (isNested) {
579+
return emitDeallocateDynamicAlloca(address);
580+
}
581+
582+
auto *call = Builder.CreateCall(IGM.getFreeFunctionPointer(),
583+
{address.getAddressPointer()});
584+
call->setDoesNotThrow();
585+
call->setCallingConv(IGM.C_CC);
586+
}
587+
556588
/// Emit a dynamic alloca call to allocate enough memory to hold an object of
557589
/// type 'T' and an optional llvm.stackrestore point if 'isInEntryBlock' is
558590
/// false.

lib/IRGen/GenType.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,12 +1373,13 @@ namespace {
13731373
llvm::Constant *getStaticStride(IRGenModule &IGM) const override {
13741374
return nullptr;
13751375
}
1376-
StackAddress allocateStack(IRGenFunction &IGF, SILType T,
1377-
const llvm::Twine &name) const override {
1376+
StackAddress
1377+
allocateStack(IRGenFunction &IGF, SILType T, const llvm::Twine &name,
1378+
StackAllocationIsNested_t isNested) const override {
13781379
llvm_unreachable("should not call on an immovable opaque type");
13791380
}
1380-
void deallocateStack(IRGenFunction &IGF, StackAddress addr,
1381-
SILType T) const override {
1381+
void deallocateStack(IRGenFunction &IGF, StackAddress addr, SILType T,
1382+
StackAllocationIsNested_t isNested) const override {
13821383
llvm_unreachable("should not call on an immovable opaque type");
13831384
}
13841385
void destroyStack(IRGenFunction &IGF, StackAddress addr, SILType T,

lib/IRGen/IRGenFunction.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/AST/ReferenceCounting.h"
2626
#include "swift/AST/Type.h"
2727
#include "swift/Basic/LLVM.h"
28+
#include "swift/SIL/SILInstruction.h"
2829
#include "swift/SIL/SILLocation.h"
2930
#include "swift/SIL/SILType.h"
3031
#include "llvm/ADT/DenseMap.h"
@@ -317,6 +318,12 @@ class IRGenFunction {
317318
bool useTaskDeallocThrough = false,
318319
bool forCalleeCoroutineFrame = false);
319320

321+
StackAddress emitDynamicStackAllocation(SILType type,
322+
StackAllocationIsNested_t isNested,
323+
const llvm::Twine &name = "");
324+
void emitDynamicStackDeallocation(StackAddress address,
325+
StackAllocationIsNested_t isNested);
326+
320327
llvm::BasicBlock *createBasicBlock(const llvm::Twine &Name);
321328
const TypeInfo &getTypeInfoForUnlowered(Type subst);
322329
const TypeInfo &getTypeInfoForUnlowered(AbstractionPattern orig, Type subst);

lib/IRGen/IRGenSIL.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@
110110

111111
#define DEBUG_TYPE "irgensil"
112112

113+
#pragma clang optimize off
114+
113115
using namespace swift;
114116
using namespace irgen;
115117

@@ -882,6 +884,14 @@ class IRGenSILFunction :
882884
return isTaskAlloc;
883885
}
884886

887+
static bool isCallToMalloc(llvm::Value *val) {
888+
auto *call = dyn_cast<llvm::CallInst>(val);
889+
if (!call)
890+
return false;
891+
auto *callee = call->getCalledFunction();
892+
return callee && callee->getName() == "malloc";
893+
}
894+
885895
static bool isTaskAlloc(llvm::Value *Storage) {
886896
while (Storage) {
887897
if (auto *LdInst = dyn_cast<llvm::LoadInst>(Storage))
@@ -6518,7 +6528,8 @@ void IRGenSILFunction::emitDebugInfoAfterAllocStack(AllocStackInst *i,
65186528

65196529
// At this point addr must be an alloca or an undef.
65206530
assert(isa<llvm::AllocaInst>(addr) || isa<llvm::UndefValue>(addr) ||
6521-
isa<llvm::IntrinsicInst>(addr) || isCallToSwiftTaskAlloc(addr));
6531+
isa<llvm::IntrinsicInst>(addr) || isCallToSwiftTaskAlloc(addr) ||
6532+
isCallToMalloc(addr));
65226533

65236534
auto Indirection = DirectValue;
65246535
if (InCoroContext(*CurSILFn, *i))
@@ -6575,7 +6586,8 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
65756586
DebugTypeInfo DbgTy;
65766587
emitDebugInfoBeforeAllocStack(i, type, DbgTy);
65776588

6578-
auto stackAddr = type.allocateStack(*this, i->getElementType(), dbgname);
6589+
auto stackAddr = type.allocateStack(*this, i->getElementType(), dbgname,
6590+
i->isStackAllocationNested());
65796591
setLoweredStackAddress(i, stackAddr);
65806592
Address addr = stackAddr.getAddress();
65816593

@@ -6668,23 +6680,27 @@ void IRGenSILFunction::visitDeallocStackInst(swift::DeallocStackInst *i) {
66686680
if (auto *closure = dyn_cast<PartialApplyInst>(i->getOperand())) {
66696681
assert(closure->isOnStack());
66706682
auto stackAddr = LoweredPartialApplyAllocations[i->getOperand()];
6671-
emitDeallocateDynamicAlloca(stackAddr);
6683+
emitDeallocateDynamicAlloca(stackAddr, closure->isStackAllocationNested());
66726684
return;
66736685
}
66746686
if (isaResultOf<BeginApplyInst>(i->getOperand())) {
66756687
auto *mvi = getAsResultOf<BeginApplyInst>(i->getOperand());
66766688
auto *bai = cast<BeginApplyInst>(mvi->getParent());
6689+
// FIXME: [non_nested]
66776690
const auto &coroutine = getLoweredCoroutine(bai->getTokenResult());
66786691
emitDeallocYieldOnce2CoroutineFrame(*this,
66796692
coroutine.getCalleeAllocatedFrame());
66806693
return;
66816694
}
66826695

6683-
auto allocatedType = i->getOperand()->getType();
6696+
auto *asi = cast<AllocStackInst>(i->getOperand());
6697+
6698+
auto allocatedType = asi->getType();
66846699
const TypeInfo &allocatedTI = getTypeInfo(allocatedType);
6685-
StackAddress stackAddr = getLoweredStackAddress(i->getOperand());
6700+
StackAddress stackAddr = getLoweredStackAddress(asi);
6701+
auto isNested = asi->isStackAllocationNested();
66866702

6687-
allocatedTI.deallocateStack(*this, stackAddr, allocatedType);
6703+
allocatedTI.deallocateStack(*this, stackAddr, allocatedType, isNested);
66886704
}
66896705

66906706
void IRGenSILFunction::visitDeallocStackRefInst(DeallocStackRefInst *i) {

lib/IRGen/NonFixedTypeInfo.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,21 @@ class WitnessSizedTypeInfo : public IndirectTypeInfo<Impl, TypeInfo> {
6363
static bool isFixed() { return false; }
6464

6565
StackAddress allocateStack(IRGenFunction &IGF, SILType T,
66-
const llvm::Twine &name) const override {
66+
const llvm::Twine &name,
67+
StackAllocationIsNested_t isNested =
68+
StackAllocationIsNested) const override {
6769
// Allocate memory on the stack.
68-
auto alloca = IGF.emitDynamicAlloca(T, name);
70+
auto alloca = IGF.emitDynamicStackAllocation(T, isNested, name);
6971
IGF.Builder.CreateLifetimeStart(alloca.getAddressPointer());
7072
return alloca.withAddress(
7173
getAsBitCastAddress(IGF, alloca.getAddressPointer()));
7274
}
7375

74-
void deallocateStack(IRGenFunction &IGF, StackAddress stackAddress,
75-
SILType T) const override {
76+
void deallocateStack(IRGenFunction &IGF, StackAddress stackAddress, SILType T,
77+
StackAllocationIsNested_t isNested =
78+
StackAllocationIsNested) const override {
7679
IGF.Builder.CreateLifetimeEnd(stackAddress.getAddress().getAddress());
77-
IGF.emitDeallocateDynamicAlloca(stackAddress);
80+
IGF.emitDynamicStackDeallocation(stackAddress, isNested);
7881
}
7982

8083
void destroyStack(IRGenFunction &IGF, StackAddress stackAddress, SILType T,

lib/IRGen/TypeInfo.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "IRGen.h"
2929
#include "Outlining.h"
3030
#include "swift/AST/ReferenceCounting.h"
31+
#include "swift/SIL/SILInstruction.h"
3132
#include "llvm/ADT/MapVector.h"
3233

3334
namespace llvm {
@@ -354,12 +355,14 @@ class TypeInfo {
354355
bool useStructLayouts) const = 0;
355356

356357
/// Allocate a variable of this type on the stack.
357-
virtual StackAddress allocateStack(IRGenFunction &IGF, SILType T,
358-
const llvm::Twine &name) const = 0;
358+
virtual StackAddress allocateStack(
359+
IRGenFunction &IGF, SILType T, const llvm::Twine &name,
360+
StackAllocationIsNested_t isNested = StackAllocationIsNested) const = 0;
359361

360362
/// Deallocate a variable of this type.
361-
virtual void deallocateStack(IRGenFunction &IGF, StackAddress addr,
362-
SILType T) const = 0;
363+
virtual void deallocateStack(
364+
IRGenFunction &IGF, StackAddress addr, SILType T,
365+
StackAllocationIsNested_t isNested = StackAllocationIsNested) const = 0;
363366

364367
/// Destroy the value of a variable of this type, then deallocate its
365368
/// memory.

0 commit comments

Comments
 (0)