Skip to content

Commit 6760555

Browse files
committed
SIL: a new instruction 'base_addr_for_offset' for field offset calculations.
The ``base_addr_for_offset`` instruction creates a base address for offset calculations. The result can be used by address projections, like ``struct_element_addr``, which themselves return the offset of the projected fields. IR generation simply creates a null pointer for ``base_addr_for_offset``.
1 parent 9e85a39 commit 6760555

File tree

16 files changed

+98
-1
lines changed

16 files changed

+98
-1
lines changed

docs/SIL.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3573,6 +3573,20 @@ the encoding is ``objc_selector``, the string literal produces a
35733573
reference to a UTF-8-encoded Objective-C selector in the Objective-C
35743574
method name segment.
35753575

3576+
base_addr_for_offset
3577+
````````````````````
3578+
::
3579+
3580+
sil-instruction ::= 'base_addr_for_offset' sil-type
3581+
3582+
%1 = base_addr_for_offset $*S
3583+
// %1 has type $*S
3584+
3585+
Creates a base address for offset calculations. The result can be used by
3586+
address projections, like ``struct_element_addr``, which themselves return the
3587+
offset of the projected fields.
3588+
IR generation simply creates a null pointer for ``base_addr_for_offset``.
3589+
35763590
Dynamic Dispatch
35773591
~~~~~~~~~~~~~~~~
35783592

include/swift/SIL/SILBuilder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,10 @@ class SILBuilder {
631631
return insert(new (getModule()) GlobalValueInst(getSILDebugLocation(Loc), g,
632632
getTypeExpansionContext()));
633633
}
634+
BaseAddrForOffsetInst *createBaseAddrForOffset(SILLocation Loc, SILType Ty) {
635+
return insert(new (F->getModule())
636+
BaseAddrForOffsetInst(getSILDebugLocation(Loc), Ty));
637+
}
634638
IntegerLiteralInst *createIntegerLiteral(IntegerLiteralExpr *E);
635639

636640
IntegerLiteralInst *createIntegerLiteral(SILLocation Loc, SILType Ty,

include/swift/SIL/SILCloner.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,15 @@ SILCloner<ImplClass>::visitGlobalValueInst(GlobalValueInst *Inst) {
10301030
Inst->getReferencedGlobal()));
10311031
}
10321032

1033+
template<typename ImplClass>
1034+
void
1035+
SILCloner<ImplClass>::visitBaseAddrForOffsetInst(BaseAddrForOffsetInst *Inst) {
1036+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1037+
recordClonedInstruction(
1038+
Inst, getBuilder().createBaseAddrForOffset(getOpLocation(Inst->getLoc()),
1039+
getOpType(Inst->getType())));
1040+
}
1041+
10331042
template<typename ImplClass>
10341043
void
10351044
SILCloner<ImplClass>::visitIntegerLiteralInst(IntegerLiteralInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3213,6 +3213,20 @@ class GlobalAddrInst
32133213
: InstructionBase(DebugLoc, Ty, nullptr) {}
32143214
};
32153215

3216+
/// Creates a base address for offset calculations.
3217+
class BaseAddrForOffsetInst
3218+
: public InstructionBase<SILInstructionKind::BaseAddrForOffsetInst,
3219+
LiteralInst> {
3220+
friend SILBuilder;
3221+
3222+
BaseAddrForOffsetInst(SILDebugLocation DebugLoc, SILType Ty)
3223+
: InstructionBase(DebugLoc, Ty) {}
3224+
3225+
public:
3226+
ArrayRef<Operand> getAllOperands() const { return {}; }
3227+
MutableArrayRef<Operand> getAllOperands() { return {}; }
3228+
};
3229+
32163230
/// Gives the value of a global variable.
32173231
///
32183232
/// The referenced global variable must be a statically initialized object.

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
458458
LiteralInst, None, DoesNotRelease)
459459
SINGLE_VALUE_INST(GlobalAddrInst, global_addr,
460460
LiteralInst, None, DoesNotRelease)
461+
SINGLE_VALUE_INST(BaseAddrForOffsetInst, base_addr_for_offset,
462+
LiteralInst, None, DoesNotRelease)
461463
SINGLE_VALUE_INST(GlobalValueInst, global_value,
462464
LiteralInst, None, DoesNotRelease)
463465
SINGLE_VALUE_INST(IntegerLiteralInst, integer_literal,

lib/IRGen/IRGenSIL.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,7 @@ class IRGenSILFunction :
868868
void visitAllocGlobalInst(AllocGlobalInst *i);
869869
void visitGlobalAddrInst(GlobalAddrInst *i);
870870
void visitGlobalValueInst(GlobalValueInst *i);
871+
void visitBaseAddrForOffsetInst(BaseAddrForOffsetInst *i);
871872

872873
void visitIntegerLiteralInst(IntegerLiteralInst *i);
873874
void visitFloatLiteralInst(FloatLiteralInst *i);
@@ -2074,6 +2075,12 @@ void IRGenSILFunction::visitGlobalValueInst(GlobalValueInst *i) {
20742075
setLoweredExplosion(i, e);
20752076
}
20762077

2078+
void IRGenSILFunction::visitBaseAddrForOffsetInst(BaseAddrForOffsetInst *i) {
2079+
auto storagePtrTy = IGM.getStoragePointerType(i->getType());
2080+
llvm::Value *addr = llvm::ConstantPointerNull::get(storagePtrTy);
2081+
setLoweredAddress(i, Address(addr, Alignment()));
2082+
}
2083+
20772084
void IRGenSILFunction::visitMetatypeInst(swift::MetatypeInst *i) {
20782085
auto metaTy = i->getType().castTo<MetatypeType>();
20792086
Explosion e;

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ SHOULD_NEVER_VISIT_INST(DynamicFunctionRef)
123123
SHOULD_NEVER_VISIT_INST(PreviousDynamicFunctionRef)
124124
SHOULD_NEVER_VISIT_INST(GlobalAddr)
125125
SHOULD_NEVER_VISIT_INST(GlobalValue)
126+
SHOULD_NEVER_VISIT_INST(BaseAddrForOffset)
126127
SHOULD_NEVER_VISIT_INST(IntegerLiteral)
127128
SHOULD_NEVER_VISIT_INST(Metatype)
128129
SHOULD_NEVER_VISIT_INST(ObjCProtocol)

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
13191319
*this << " : " << GVI->getType();
13201320
}
13211321

1322+
void visitBaseAddrForOffsetInst(BaseAddrForOffsetInst *BAI) {
1323+
*this << BAI->getType();
1324+
}
1325+
13221326
void visitIntegerLiteralInst(IntegerLiteralInst *ILI) {
13231327
const auto &lit = ILI->getValue();
13241328
*this << ILI->getType() << ", " << lit;

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ CONSTANT_OWNERSHIP_INST(None, FunctionRef)
103103
CONSTANT_OWNERSHIP_INST(None, DynamicFunctionRef)
104104
CONSTANT_OWNERSHIP_INST(None, PreviousDynamicFunctionRef)
105105
CONSTANT_OWNERSHIP_INST(None, GlobalAddr)
106+
CONSTANT_OWNERSHIP_INST(None, BaseAddrForOffset)
106107
CONSTANT_OWNERSHIP_INST(None, IndexAddr)
107108
CONSTANT_OWNERSHIP_INST(None, IndexRawPointer)
108109
CONSTANT_OWNERSHIP_INST(None, InitEnumDataAddr)

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4583,6 +4583,15 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
45834583
}
45844584
break;
45854585
}
4586+
case SILInstructionKind::BaseAddrForOffsetInst: {
4587+
SILType Ty;
4588+
if (parseSILType(Ty))
4589+
return true;
4590+
if (parseSILDebugLocation(InstLoc, B))
4591+
return true;
4592+
ResultVal = B.createBaseAddrForOffset(InstLoc, Ty);
4593+
break;
4594+
}
45864595
case SILInstructionKind::SelectEnumInst:
45874596
case SILInstructionKind::SelectEnumAddrInst: {
45884597
if (parseTypedValueRef(Val, B))

lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ static bool hasOpaqueArchetype(TypeExpansionContext context,
161161
case SILInstructionKind::PreviousDynamicFunctionRefInst:
162162
case SILInstructionKind::GlobalAddrInst:
163163
case SILInstructionKind::GlobalValueInst:
164+
case SILInstructionKind::BaseAddrForOffsetInst:
164165
case SILInstructionKind::IntegerLiteralInst:
165166
case SILInstructionKind::FloatLiteralInst:
166167
case SILInstructionKind::StringLiteralInst:

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
685685
case SILInstructionKind::FunctionRefInst:
686686
case SILInstructionKind::AllocGlobalInst:
687687
case SILInstructionKind::GlobalAddrInst:
688+
case SILInstructionKind::BaseAddrForOffsetInst:
688689
case SILInstructionKind::EndLifetimeInst:
689690
case SILInstructionKind::UncheckedOwnershipConversionInst:
690691
return InlineCost::Free;

lib/Serialization/DeserializeSIL.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,11 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
15921592
}
15931593
break;
15941594
}
1595+
case SILInstructionKind::BaseAddrForOffsetInst:
1596+
assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
1597+
ResultVal = Builder.createBaseAddrForOffset(Loc,
1598+
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
1599+
break;
15951600
case SILInstructionKind::DeallocStackInst: {
15961601
auto Ty = MF->getType(TyID);
15971602
ResultVal = Builder.createDeallocStack(

lib/Serialization/SerializeSIL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,12 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
10911091
S.addUniquedStringRef(G->getName()));
10921092
break;
10931093
}
1094+
case SILInstructionKind::BaseAddrForOffsetInst: {
1095+
const BaseAddrForOffsetInst *BAI = cast<BaseAddrForOffsetInst>(&SI);
1096+
writeOneTypeLayout(BAI->getKind(), /*attrs*/ 0, BAI->getType());
1097+
break;
1098+
}
1099+
10941100
case SILInstructionKind::BranchInst: {
10951101
// Format: destination basic block ID, a list of arguments. Use
10961102
// SILOneTypeValuesLayout.

test/SIL/Parser/basic.sil

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,15 @@ bb0:
572572
return %6 : $()
573573
}
574574

575+
// CHECK-LABEL: @base_addr : $@convention(thin) () -> ()
576+
sil private @base_addr : $() -> () {
577+
bb0:
578+
// CHECK: base_addr_for_offset $*Int
579+
%0 = base_addr_for_offset $*Int
580+
%1 = tuple ()
581+
return %1 : $()
582+
}
583+
575584
protocol SomeProtocol {
576585
}
577586
class SomeClass : SomeProtocol {

test/Serialization/Inputs/def_basic.sil

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,15 @@ bb0:
498498
return %6 : $()
499499
}
500500

501+
// CHECK-LABEL: @base_addr : $@convention(thin) () -> ()
502+
sil [transparent] [serialized] @base_addr : $@convention(thin) () -> () {
503+
bb0:
504+
// CHECK: base_addr_for_offset $*Int
505+
%0 = base_addr_for_offset $*Int
506+
%1 = tuple ()
507+
return %1 : $()
508+
}
509+
501510
class GlobalObject { }
502511

503512
sil_global @static_global_object : $GlobalObject = {
@@ -1491,7 +1500,8 @@ bb0:
14911500
%57 = function_ref @$s7literal8literalsyyF : $@convention(thin) () -> ()
14921501
%59 = function_ref @$s5index5gep641p1iBpBp_Bi64_tF : $@convention(thin) (Builtin.RawPointer, Builtin.Word) -> Builtin.RawPointer
14931502
%60 = function_ref @global_code : $@convention(thin) () -> ()
1494-
%61 = function_ref @global_object : $@convention(thin) () -> GlobalObject
1503+
%61 = function_ref @base_addr : $@convention(thin) () -> ()
1504+
%62 = function_ref @global_object : $@convention(thin) () -> GlobalObject
14951505
%63 = function_ref @test_class_metatype : $@convention(thin) (SomeClass, SomeSubclass) -> (@thick SomeClass.Type, @thick SomeClass.Type)
14961506
%67 = function_ref @test_existential_metatype : $@convention(thin) (@in SomeProtocol) -> @thick SomeProtocol.Type
14971507
%69 = function_ref @test_unreachable : $@convention(thin) () -> ()

0 commit comments

Comments
 (0)