Skip to content

Commit d0a7948

Browse files
authored
Merge pull request #32544 from eeckstein/fold-kp-offset
SILCombine: Constant-fold MemoryLayout<T>.offset(of: \.literalKeyPath)
2 parents 3e59cc4 + d7d829c commit d0a7948

File tree

20 files changed

+448
-21
lines changed

20 files changed

+448
-21
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))

0 commit comments

Comments
 (0)