Skip to content

Commit 283d2f2

Browse files
committed
[NO MERGE] implement realloc_ref SIL instruction [INCOMPLETE]
1 parent 456952e commit 283d2f2

20 files changed

+190
-1
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,19 @@ class SILBuilder {
385385
C.OpenedArchetypes));
386386
}
387387

388+
ReallocRefInst *createReallocRef(SILLocation Loc, SILType ObjectType,
389+
SILValue Val, ArrayRef<SILType> ElementTypes,
390+
ArrayRef<SILValue> ElementCountOperands) {
391+
// ReallocRefInst expand to function calls and can therefore not be
392+
// counted towards the function prologue.
393+
assert(!Loc.isInPrologue() &&
394+
"ReallocRefInst can not count towards function prologue since it "
395+
"expands into function calls");
396+
return insert(ReallocRefInst::create(
397+
getSILDebugLocation(Loc), getFunction(), ObjectType, Val, ElementTypes,
398+
ElementCountOperands, C.OpenedArchetypes));
399+
}
400+
388401
AllocRefDynamicInst *createAllocRefDynamic(SILLocation Loc, SILValue operand,
389402
SILType type, bool objc,
390403
ArrayRef<SILType> ElementTypes,

include/swift/SIL/SILCloner.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,11 @@ SILCloner<ImplClass>::visitAllocRefInst(AllocRefInst *Inst) {
500500
doPostProcess(Inst, NewInst);
501501
}
502502

503+
template <typename ImplClass>
504+
void SILCloner<ImplClass>::visitReallocRefInst(ReallocRefInst *Inst) {
505+
llvm_unreachable("unimplemented: incomplete realloc_ref implementation");
506+
}
507+
503508
template<typename ImplClass>
504509
void
505510
SILCloner<ImplClass>::visitAllocRefDynamicInst(AllocRefDynamicInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,55 @@ class AllocRefInst final
14461446
}
14471447
};
14481448

1449+
/// ReallocRefInst - This represents the reallocation primitive of a reference
1450+
/// type. If the reallocation was successfully the reference is returned with
1451+
/// the altered size. If the reallocation failed the reference is returned at
1452+
/// a new address in an allocation with the altered size and the contents are
1453+
/// bit-wise copied.
1454+
/// This is only useful for tail-allocated arrays and the new size must always
1455+
/// be larger than the original size.
1456+
class ReallocRefInst final
1457+
: public InstructionBaseWithTrailingOperands<
1458+
SILInstructionKind::ReallocRefInst,
1459+
ReallocRefInst,
1460+
AllocRefInstBase, SILType> {
1461+
friend AllocRefInstBase;
1462+
friend SILBuilder;
1463+
1464+
ReallocRefInst(SILDebugLocation DebugLoc, SILFunction &F, SILType ObjectType,
1465+
SILValue ExistingRef, ArrayRef<SILType> ElementTypes,
1466+
ArrayRef<SILValue> AllOperands)
1467+
: InstructionBaseWithTrailingOperands(AllOperands, DebugLoc, ObjectType,
1468+
false, false, ElementTypes) {
1469+
assert(AllOperands.size() >= ElementTypes.size());
1470+
std::uninitialized_copy(ElementTypes.begin(), ElementTypes.end(),
1471+
getTrailingObjects<SILType>());
1472+
}
1473+
1474+
static ReallocRefInst *create(SILDebugLocation DebugLoc, SILFunction &F,
1475+
SILType ObjectType, SILValue ExistingRef,
1476+
ArrayRef<SILType> ElementTypes,
1477+
ArrayRef<SILValue> ElementCountOperands,
1478+
SILOpenedArchetypesState &OpenedArchetypes);
1479+
1480+
public:
1481+
ArrayRef<Operand> getTypeDependentOperands() const {
1482+
return getAllOperands().slice(getNumTailTypes());
1483+
}
1484+
1485+
MutableArrayRef<Operand> getTypeDependentOperands() {
1486+
return getAllOperands().slice(getNumTailTypes());
1487+
}
1488+
1489+
SILValue getReallocPointer() {
1490+
llvm_unreachable("Unimplemented! realloc_ref implementation incomplete");
1491+
}
1492+
1493+
SILValue getReallocSize() {
1494+
llvm_unreachable("Unimplemented! realloc_ref implementation incomplete");
1495+
}
1496+
};
1497+
14491498
/// AllocRefDynamicInst - This represents the primitive allocation of
14501499
/// an instance of a reference type whose runtime type is provided by
14511500
/// the given metatype value. Aside from the reference count, the

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
231231
AllocationInst, None, DoesNotRelease)
232232
SINGLE_VALUE_INST(AllocRefInst, alloc_ref,
233233
AllocationInst, None, DoesNotRelease)
234+
SINGLE_VALUE_INST(ReallocRefInst, realloc_ref,
235+
AllocationInst, None, DoesNotRelease)
234236
SINGLE_VALUE_INST(AllocRefDynamicInst, alloc_ref_dynamic,
235237
AllocationInst, None, DoesNotRelease)
236238
SINGLE_VALUE_INST(AllocValueBufferInst, alloc_value_buffer,

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
5757
/// Don't worry about adhering to the 80-column limit for this line.
58-
const uint16_t VERSION_MINOR = 426; // SIL key path external components with local attempts
58+
const uint16_t VERSION_MINOR = 427; // Last change: add realloc_ref
5959

6060
using DeclIDField = BCFixed<31>;
6161

lib/IRGen/IRGenSIL.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ class IRGenSILFunction :
919919
llvm::Value *addr);
920920
void visitAllocStackInst(AllocStackInst *i);
921921
void visitAllocRefInst(AllocRefInst *i);
922+
void visitReallocRefInst(ReallocRefInst *i);
922923
void visitAllocRefDynamicInst(AllocRefDynamicInst *i);
923924
void visitAllocBoxInst(AllocBoxInst *i);
924925

@@ -4095,6 +4096,10 @@ void IRGenSILFunction::visitAllocRefInst(swift::AllocRefInst *i) {
40954096
setLoweredExplosion(i, e);
40964097
}
40974098

4099+
void IRGenSILFunction::visitReallocRefInst(swift::ReallocRefInst *i) {
4100+
llvm_unreachable("unimplemented: incomplete realloc_ref implementation");
4101+
}
4102+
40984103
void IRGenSILFunction::visitAllocRefDynamicInst(swift::AllocRefDynamicInst *i) {
40994104
SmallVector<std::pair<SILType, llvm::Value *>, 4> TailArrays;
41004105
buildTailArrays(*this, TailArrays, i);

lib/ParseSIL/ParseSIL.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3602,6 +3602,47 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
36023602
}
36033603
break;
36043604
}
3605+
case SILInstructionKind::ReallocRefInst: {
3606+
SmallVector<SILType, 2> ElementTypes;
3607+
SmallVector<SILValue, 2> ElementCounts;
3608+
while (P.consumeIf(tok::l_square)) {
3609+
Identifier Id;
3610+
parseSILIdentifier(Id, diag::expected_in_attribute_list);
3611+
StringRef Optional = Id.str();
3612+
if (Optional == "tail_elems") {
3613+
SILType ElemTy;
3614+
if (parseSILType(ElemTy) || !P.Tok.isAnyOperator() ||
3615+
P.Tok.getText() != "*")
3616+
return true;
3617+
P.consumeToken();
3618+
3619+
SILValue ElemCount;
3620+
if (parseTypedValueRef(ElemCount, B))
3621+
return true;
3622+
3623+
ElementTypes.push_back(ElemTy);
3624+
ElementCounts.push_back(ElemCount);
3625+
} else {
3626+
return true;
3627+
}
3628+
P.parseToken(tok::r_square, diag::expected_in_attribute_list);
3629+
}
3630+
SILValue Metadata;
3631+
if (parseTypedValueRef(Val, B) ||
3632+
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ","))
3633+
return true;
3634+
3635+
SILType ObjectType;
3636+
if (parseSILType(ObjectType))
3637+
return true;
3638+
3639+
if (parseSILDebugLocation(InstLoc, B))
3640+
return true;
3641+
3642+
ResultVal = B.createReallocRef(InstLoc, ObjectType, Val, ElementTypes,
3643+
ElementCounts);
3644+
break;
3645+
}
36053646
case SILInstructionKind::AllocRefInst:
36063647
case SILInstructionKind::AllocRefDynamicInst: {
36073648
bool IsObjC = false;

lib/SIL/Linker.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,18 @@ void SILLinkerVisitor::visitAllocRefInst(AllocRefInst *ARI) {
353353
linkInVTable(D);
354354
}
355355

356+
void SILLinkerVisitor::visitReallocRefInst(ReallocRefInst *RRI) {
357+
if (!isLinkAll())
358+
return;
359+
360+
// Grab the class decl from the alloc ref inst.
361+
ClassDecl *D = RRI->getType().getClassOrBoundGenericClass();
362+
if (!D)
363+
return;
364+
365+
linkInVTable(D);
366+
}
367+
356368
void SILLinkerVisitor::visitMetatypeInst(MetatypeInst *MI) {
357369
if (!isLinkAll())
358370
return;

lib/SIL/Linker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class SILLinkerVisitor : public SILInstructionVisitor<SILLinkerVisitor, void> {
7575
void visitInitExistentialAddrInst(InitExistentialAddrInst *IEI);
7676
void visitInitExistentialRefInst(InitExistentialRefInst *IERI);
7777
void visitAllocRefInst(AllocRefInst *ARI);
78+
void visitReallocRefInst(ReallocRefInst *RRI);
7879
void visitMetatypeInst(MetatypeInst *MI);
7980

8081
private:

lib/SIL/SILInstruction.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ namespace {
367367
return true;
368368
}
369369

370+
bool visitReallocRefInst(const ReallocRefInst *RHS) { return true; }
371+
370372
bool visitAllocRefDynamicInst(const AllocRefDynamicInst *RHS) {
371373
return true;
372374
}

lib/SIL/SILInstructions.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,27 @@ AllocRefInst *AllocRefInst::create(SILDebugLocation Loc, SILFunction &F,
232232
ElementTypes, AllOperands);
233233
}
234234

235+
ReallocRefInst *
236+
ReallocRefInst::create(SILDebugLocation Loc, SILFunction &F, SILType ObjectType,
237+
SILValue ExistingRef, ArrayRef<SILType> ElementTypes,
238+
ArrayRef<SILValue> ElementCountOperands,
239+
SILOpenedArchetypesState &OpenedArchetypes) {
240+
assert(ElementTypes.size() == ElementCountOperands.size());
241+
SmallVector<SILValue, 8> AllOperands(ElementCountOperands.begin(),
242+
ElementCountOperands.end());
243+
for (SILType ElemType : ElementTypes) {
244+
collectTypeDependentOperands(AllOperands, OpenedArchetypes, F,
245+
ElemType.getASTType());
246+
}
247+
collectTypeDependentOperands(AllOperands, OpenedArchetypes, F,
248+
ObjectType.getASTType());
249+
auto Size = totalSizeToAlloc<swift::Operand, SILType>(AllOperands.size(),
250+
ElementTypes.size());
251+
auto Buffer = F.getModule().allocateInst(Size, alignof(ReallocRefInst));
252+
return ::new (Buffer) ReallocRefInst(Loc, F, ObjectType, ExistingRef,
253+
ElementTypes, AllOperands);
254+
}
255+
235256
AllocRefDynamicInst *
236257
AllocRefDynamicInst::create(SILDebugLocation DebugLoc, SILFunction &F,
237258
SILValue metatypeOperand, SILType ty, bool objc,

lib/SIL/SILOwnershipVerifier.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,17 @@ OwnershipCompatibilityUseChecker::visitAllocRefInst(AllocRefInst *I) {
645645
UseLifetimeConstraint::MustBeLive};
646646
}
647647

648+
OwnershipUseCheckerResult
649+
OwnershipCompatibilityUseChecker::visitReallocRefInst(ReallocRefInst *I) {
650+
if (getValue() == I->getReallocPointer()) {
651+
return {compatibleWithOwnership(ValueOwnershipKind::Owned),
652+
UseLifetimeConstraint::MustBeInvalidated};
653+
}
654+
assert(getValue() == I->getReallocSize());
655+
return {compatibleWithOwnership(ValueOwnershipKind::Trivial),
656+
UseLifetimeConstraint::MustBeLive};
657+
}
658+
648659
OwnershipUseCheckerResult
649660
OwnershipCompatibilityUseChecker::visitAllocRefDynamicInst(
650661
AllocRefDynamicInst *I) {

lib/SIL/SILPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,11 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
10501050
*this << ARI->getType();
10511051
}
10521052

1053+
void visitReallocRefInst(ReallocRefInst *RRI) {
1054+
printAllocRefInstBase(RRI);
1055+
*this << RRI->getType();
1056+
}
1057+
10531058
void visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
10541059
printAllocRefInstBase(ARDI);
10551060
*this << getIDAndType(ARDI->getMetatypeOperand());

lib/SIL/ValueOwnershipKindClassifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ CONSTANT_OWNERSHIP_INST(Guaranteed, LoadBorrow)
4949
CONSTANT_OWNERSHIP_INST(Owned, AllocBox)
5050
CONSTANT_OWNERSHIP_INST(Owned, AllocExistentialBox)
5151
CONSTANT_OWNERSHIP_INST(Owned, AllocRef)
52+
CONSTANT_OWNERSHIP_INST(Owned, ReallocRef)
5253
CONSTANT_OWNERSHIP_INST(Owned, AllocRefDynamic)
5354
CONSTANT_OWNERSHIP_INST(Trivial, AllocValueBuffer)
5455
CONSTANT_OWNERSHIP_INST(Owned, CopyBlock)

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ class SILCombiner :
210210
SILInstruction *visitIndexAddrInst(IndexAddrInst *IA);
211211
SILInstruction *visitAllocStackInst(AllocStackInst *AS);
212212
SILInstruction *visitAllocRefInst(AllocRefInst *AR);
213+
SILInstruction *visitReallocRefInst(ReallocRefInst *AR);
213214
SILInstruction *visitSwitchEnumAddrInst(SwitchEnumAddrInst *SEAI);
214215
SILInstruction *visitInjectEnumAddrInst(InjectEnumAddrInst *IEAI);
215216
SILInstruction *visitPointerToAddressInst(PointerToAddressInst *PTAI);

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,10 @@ SILInstruction *SILCombiner::visitAllocRefInst(AllocRefInst *AR) {
465465
return nullptr;
466466
}
467467

468+
SILInstruction *SILCombiner::visitReallocRefInst(ReallocRefInst *RRI) {
469+
return nullptr;
470+
}
471+
468472
/// Returns the base address if \p val is an index_addr with constant index.
469473
static SILValue isConstIndexAddr(SILValue val, unsigned &index) {
470474
auto *IA = dyn_cast<IndexAddrInst>(val);

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
579579
case SILInstructionKind::AllocBoxInst:
580580
case SILInstructionKind::AllocExistentialBoxInst:
581581
case SILInstructionKind::AllocRefInst:
582+
case SILInstructionKind::ReallocRefInst:
582583
case SILInstructionKind::AllocRefDynamicInst:
583584
case SILInstructionKind::AllocStackInst:
584585
case SILInstructionKind::AllocValueBufferInst:

lib/Serialization/DeserializeSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
12571257
}
12581258
break;
12591259
}
1260+
case SILInstructionKind::ReallocRefInst:
12601261
case SILInstructionKind::AllocRefInst:
12611262
case SILInstructionKind::AllocRefDynamicInst: {
12621263
assert(RecordKind == SIL_ONE_TYPE_VALUES &&

lib/Serialization/SerializeSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
827827
break;
828828
}
829829
case SILInstructionKind::AllocRefInst:
830+
case SILInstructionKind::ReallocRefInst:
830831
case SILInstructionKind::AllocRefDynamicInst: {
831832
const AllocRefInstBase *ARI = cast<AllocRefInstBase>(&SI);
832833
unsigned abbrCode = SILAbbrCodes[SILOneTypeValuesLayout::Code];

test/SIL/Parser/basic.sil

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,19 @@ bb0(%0 : $Builtin.Word, %1 : $Builtin.Word):
754754
return %3 : $()
755755
}
756756

757+
// CHECK-LABEL: sil @test_realloc_tail_elems
758+
sil @test_realloc_tail_elems : $@convention(thin) (Builtin.Word, Builtin.Word) -> () {
759+
bb0(%0 : $Builtin.Word, %1 : $Builtin.Word):
760+
// CHECK: alloc_ref [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] $Class1
761+
%2 = alloc_ref [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] $Class1
762+
// CHECK: %3 = realloc_ref [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * % %1 : $Builtin.Word] %2, $Class1
763+
%3 = realloc_ref [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * % %1 : $Builtin.Word] %2, $Class1
764+
// CHECK: dealloc_ref %3 : $Class1
765+
dealloc_ref %3 : $Class1
766+
%4 = tuple ()
767+
return %4 : $()
768+
}
769+
757770
// CHECK-LABEL: sil @test_tail_elems_dynamic
758771
sil @test_tail_elems_dynamic : $@convention(thin) (Builtin.Word, Builtin.Word, @thick Class1.Type) -> () {
759772
bb0(%0 : $Builtin.Word, %1 : $Builtin.Word, %2 : $@thick Class1.Type):

0 commit comments

Comments
 (0)