Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -669,10 +669,11 @@ class SILBuilder {
BeginAccessInst *createBeginAccess(SILLocation loc, SILValue address,
SILAccessKind accessKind,
SILAccessEnforcement enforcement,
bool noNestedConflict) {
bool noNestedConflict,
bool fromBuiltin) {
return insert(new (getModule()) BeginAccessInst(
getSILDebugLocation(loc), address, accessKind, enforcement,
noNestedConflict));
noNestedConflict, fromBuiltin));
}

EndAccessInst *createEndAccess(SILLocation loc, SILValue address,
Expand All @@ -685,18 +686,19 @@ class SILBuilder {
createBeginUnpairedAccess(SILLocation loc, SILValue address, SILValue buffer,
SILAccessKind accessKind,
SILAccessEnforcement enforcement,
bool noNestedConflict) {
bool noNestedConflict,
bool fromBuiltin) {
return insert(new (getModule()) BeginUnpairedAccessInst(
getSILDebugLocation(loc), address, buffer, accessKind, enforcement,
noNestedConflict));
noNestedConflict, fromBuiltin));
}

EndUnpairedAccessInst *createEndUnpairedAccess(SILLocation loc,
SILValue buffer,
SILAccessEnforcement enforcement,
bool aborted) {
EndUnpairedAccessInst *
createEndUnpairedAccess(SILLocation loc, SILValue buffer,
SILAccessEnforcement enforcement, bool aborted,
bool fromBuiltin) {
return insert(new (getModule()) EndUnpairedAccessInst(
getSILDebugLocation(loc), buffer, enforcement, aborted));
getSILDebugLocation(loc), buffer, enforcement, aborted, fromBuiltin));
}

AssignInst *createAssign(SILLocation Loc, SILValue Src, SILValue DestAddr) {
Expand Down
16 changes: 9 additions & 7 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,8 @@ void SILCloner<ImplClass>::visitBeginAccessInst(BeginAccessInst *Inst) {
getOpValue(Inst->getOperand()),
Inst->getAccessKind(),
Inst->getEnforcement(),
Inst->hasNoNestedConflict()));
Inst->hasNoNestedConflict(),
Inst->isFromBuiltin()));
}

template <typename ImplClass>
Expand All @@ -831,18 +832,19 @@ void SILCloner<ImplClass>::visitBeginUnpairedAccessInst(
getOpValue(Inst->getBuffer()),
Inst->getAccessKind(),
Inst->getEnforcement(),
Inst->hasNoNestedConflict()));
Inst->hasNoNestedConflict(),
Inst->isFromBuiltin()));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitEndUnpairedAccessInst(
EndUnpairedAccessInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(
Inst, getBuilder().createEndUnpairedAccess(getOpLocation(Inst->getLoc()),
getOpValue(Inst->getOperand()),
Inst->getEnforcement(),
Inst->isAborting()));
doPostProcess(Inst,
getBuilder().createEndUnpairedAccess(
getOpLocation(Inst->getLoc()),
getOpValue(Inst->getOperand()), Inst->getEnforcement(),
Inst->isAborting(), Inst->isFromBuiltin()));
}

template <typename ImplClass>
Expand Down
34 changes: 31 additions & 3 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3229,12 +3229,14 @@ class BeginAccessInst

BeginAccessInst(SILDebugLocation loc, SILValue lvalue,
SILAccessKind accessKind, SILAccessEnforcement enforcement,
bool noNestedConflict)
bool noNestedConflict, bool fromBuiltin)
: UnaryInstructionBase(loc, lvalue, lvalue->getType()) {
SILInstruction::Bits.BeginAccessInst.AccessKind = unsigned(accessKind);
SILInstruction::Bits.BeginAccessInst.Enforcement = unsigned(enforcement);
SILInstruction::Bits.BeginAccessInst.NoNestedConflict =
unsigned(noNestedConflict);
SILInstruction::Bits.BeginAccessInst.FromBuiltin =
unsigned(fromBuiltin);

static_assert(unsigned(SILAccessKind::Last) < (1 << 2),
"reserve sufficient bits for serialized SIL");
Expand Down Expand Up @@ -3278,6 +3280,13 @@ class BeginAccessInst
SILInstruction::Bits.BeginAccessInst.NoNestedConflict = noNestedConflict;
}

/// Return true if this access marker was emitted for a user-controlled
/// Builtin. Return false if this access marker was auto-generated by the
/// compiler to enforce formal access that derives from the language.
bool isFromBuiltin() const {
return SILInstruction::Bits.BeginAccessInst.FromBuiltin;
}

SILValue getSource() const {
return getOperand();
}
Expand Down Expand Up @@ -3358,14 +3367,17 @@ class BeginUnpairedAccessInst
BeginUnpairedAccessInst(SILDebugLocation loc, SILValue addr, SILValue buffer,
SILAccessKind accessKind,
SILAccessEnforcement enforcement,
bool noNestedConflict)
bool noNestedConflict,
bool fromBuiltin)
: InstructionBase(loc), Operands(this, addr, buffer) {
SILInstruction::Bits.BeginUnpairedAccessInst.AccessKind =
unsigned(accessKind);
SILInstruction::Bits.BeginUnpairedAccessInst.Enforcement =
unsigned(enforcement);
SILInstruction::Bits.BeginUnpairedAccessInst.NoNestedConflict =
unsigned(noNestedConflict);
SILInstruction::Bits.BeginUnpairedAccessInst.FromBuiltin =
unsigned(fromBuiltin);
}

public:
Expand Down Expand Up @@ -3400,6 +3412,13 @@ class BeginUnpairedAccessInst
noNestedConflict;
}

/// Return true if this access marker was emitted for a user-controlled
/// Builtin. Return false if this access marker was auto-generated by the
/// compiler to enforce formal access that derives from the language.
bool isFromBuiltin() const {
return SILInstruction::Bits.BeginUnpairedAccessInst.FromBuiltin;
}

SILValue getSource() const {
return Operands[0].get();
}
Expand Down Expand Up @@ -3428,11 +3447,13 @@ class EndUnpairedAccessInst

private:
EndUnpairedAccessInst(SILDebugLocation loc, SILValue buffer,
SILAccessEnforcement enforcement, bool aborting = false)
SILAccessEnforcement enforcement, bool aborting,
bool fromBuiltin)
: UnaryInstructionBase(loc, buffer) {
SILInstruction::Bits.EndUnpairedAccessInst.Enforcement
= unsigned(enforcement);
SILInstruction::Bits.EndUnpairedAccessInst.Aborting = aborting;
SILInstruction::Bits.EndUnpairedAccessInst.FromBuiltin = fromBuiltin;
}

public:
Expand All @@ -3458,6 +3479,13 @@ class EndUnpairedAccessInst
unsigned(enforcement);
}

/// Return true if this access marker was emitted for a user-controlled
/// Builtin. Return false if this access marker was auto-generated by the
/// compiler to enforce formal access that derives from the language.
bool isFromBuiltin() const {
return SILInstruction::Bits.EndUnpairedAccessInst.FromBuiltin;
}

SILValue getBuffer() const {
return getOperand();
}
Expand Down
16 changes: 10 additions & 6 deletions include/swift/SIL/SILNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,24 +258,28 @@ class alignas(8) SILNode {

SWIFT_INLINE_BITFIELD(BeginAccessInst, SingleValueInstruction,
NumSILAccessKindBits+NumSILAccessEnforcementBits
+ 1,
+ 1 + 1,
AccessKind : NumSILAccessKindBits,
Enforcement : NumSILAccessEnforcementBits,
NoNestedConflict : 1
NoNestedConflict : 1,
FromBuiltin : 1
);
SWIFT_INLINE_BITFIELD(BeginUnpairedAccessInst, NonValueInstruction,
NumSILAccessKindBits + NumSILAccessEnforcementBits + 1,
NumSILAccessKindBits + NumSILAccessEnforcementBits
+ 1 + 1,
AccessKind : NumSILAccessKindBits,
Enforcement : NumSILAccessEnforcementBits,
NoNestedConflict : 1);
NoNestedConflict : 1,
FromBuiltin : 1);

SWIFT_INLINE_BITFIELD(EndAccessInst, NonValueInstruction, 1,
Aborting : 1
);
SWIFT_INLINE_BITFIELD(EndUnpairedAccessInst, NonValueInstruction,
NumSILAccessEnforcementBits + 1,
NumSILAccessEnforcementBits + 1 + 1,
Enforcement : NumSILAccessEnforcementBits,
Aborting : 1);
Aborting : 1,
FromBuiltin : 1);

SWIFT_INLINE_BITFIELD(StoreInst, NonValueInstruction,
NumStoreOwnershipQualifierBits,
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t VERSION_MINOR = 417; // Last change: revert @usableFromInline imports
const uint16_t VERSION_MINOR = 418; // Last change: add begin_access [builtin].

using DeclIDField = BCFixed<31>;

Expand Down
7 changes: 0 additions & 7 deletions include/swift/Strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
#ifndef SWIFT_STRINGS_H
#define SWIFT_STRINGS_H

#include "swift/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"

namespace swift {

/// The extension for serialized modules.
Expand Down Expand Up @@ -92,10 +89,6 @@ constexpr static const char BUILTIN_TYPE_NAME_VEC[] = "Builtin.Vec";
constexpr static const char BUILTIN_TYPE_NAME_SILTOKEN[] = "Builtin.SILToken";
/// The name of the Builtin type for Word
constexpr static const char BUILTIN_TYPE_NAME_WORD[] = "Builtin.Word";

constexpr static StringLiteral OPTIMIZE_SIL_PRESERVE_EXCLUSIVITY =
"optimize.sil.preserve_exclusivity";

} // end namespace swift

#endif // SWIFT_STRINGS_H
7 changes: 4 additions & 3 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4228,11 +4228,12 @@ static ExclusivityFlags getExclusivityAction(SILAccessKind kind) {

static ExclusivityFlags getExclusivityFlags(SILModule &M,
SILAccessKind kind,
bool noNestedConflict) {
bool noNestedConflict,
bool fromBuiltin) {
auto flags = getExclusivityAction(kind);

// In old Swift compatibility modes, downgrade this to a warning.
if (M.getASTContext().LangOpts.isSwiftVersion3())
if (!fromBuiltin && M.getASTContext().LangOpts.isSwiftVersion3())
flags |= ExclusivityFlags::WarningOnly;

if (!noNestedConflict)
Expand Down Expand Up @@ -4264,7 +4265,7 @@ static SILAccessEnforcement getEffectiveEnforcement(IRGenFunction &IGF,
template <class BeginAccessInst>
static ExclusivityFlags getExclusivityFlags(BeginAccessInst *i) {
return getExclusivityFlags(i->getModule(), i->getAccessKind(),
i->hasNoNestedConflict());
i->hasNoNestedConflict(), i->isFromBuiltin());
}

void IRGenSILFunction::visitBeginAccessInst(BeginAccessInst *access) {
Expand Down
3 changes: 2 additions & 1 deletion lib/IRGen/LoadableByAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2086,7 +2086,8 @@ static void rewriteFunction(StructLoweringState &pass,
auto *convInstr = cast<BeginAccessInst>(instr);
newInstr = resultTyBuilder.createBeginAccess(
Loc, convInstr->getOperand(), convInstr->getAccessKind(),
convInstr->getEnforcement(), convInstr->hasNoNestedConflict());
convInstr->getEnforcement(), convInstr->hasNoNestedConflict(),
convInstr->isFromBuiltin());
break;
}
case SILInstructionKind::EnumInst: {
Expand Down
18 changes: 14 additions & 4 deletions lib/ParseSIL/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3447,6 +3447,7 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
ParsedEnum<SILAccessEnforcement> enforcement;
ParsedEnum<bool> aborting;
ParsedEnum<bool> noNestedConflict;
ParsedEnum<bool> fromBuiltin;

bool isBeginAccess = (Opcode == SILInstructionKind::BeginAccessInst ||
Opcode == SILInstructionKind::BeginUnpairedAccessInst);
Expand Down Expand Up @@ -3478,6 +3479,10 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
auto setNoNestedConflict = [&](bool value) {
maybeSetEnum(isBeginAccess, noNestedConflict, value, attr, identLoc);
};
auto setFromBuiltin = [&](bool value) {
maybeSetEnum(Opcode != SILInstructionKind::EndAccessInst, fromBuiltin,
value, attr, identLoc);
};

if (attr == "unknown") {
setEnforcement(SILAccessEnforcement::Unknown);
Expand All @@ -3499,6 +3504,8 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
setAborting(true);
} else if (attr == "no_nested_conflict") {
setNoNestedConflict(true);
} else if (attr == "builtin") {
setFromBuiltin(true);
} else {
P.diagnose(identLoc, diag::unknown_attribute, attr);
}
Expand All @@ -3523,6 +3530,9 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
if (isBeginAccess && !noNestedConflict.isSet())
noNestedConflict.Value = false;

if (!fromBuiltin.isSet())
fromBuiltin.Value = false;

SILValue addrVal;
SourceLoc addrLoc;
if (parseTypedValueRef(addrVal, addrLoc, B))
Expand All @@ -3547,16 +3557,16 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
if (Opcode == SILInstructionKind::BeginAccessInst) {
ResultVal =
B.createBeginAccess(InstLoc, addrVal, *kind, *enforcement,
*noNestedConflict);
*noNestedConflict, *fromBuiltin);
} else if (Opcode == SILInstructionKind::EndAccessInst) {
ResultVal = B.createEndAccess(InstLoc, addrVal, *aborting);
} else if (Opcode == SILInstructionKind::BeginUnpairedAccessInst) {
ResultVal = B.createBeginUnpairedAccess(InstLoc, addrVal, bufferVal,
*kind, *enforcement,
*noNestedConflict);
*noNestedConflict, *fromBuiltin);
} else {
ResultVal = B.createEndUnpairedAccess(InstLoc, addrVal,
*enforcement, *aborting);
ResultVal = B.createEndUnpairedAccess(InstLoc, addrVal, *enforcement,
*aborting, *fromBuiltin);
}
break;
}
Expand Down
9 changes: 6 additions & 3 deletions lib/SIL/SILInstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,8 @@ namespace {
auto left = cast<BeginAccessInst>(LHS);
return left->getAccessKind() == right->getAccessKind()
&& left->getEnforcement() == right->getEnforcement()
&& left->hasNoNestedConflict() == right->hasNoNestedConflict();
&& left->hasNoNestedConflict() == right->hasNoNestedConflict()
&& left->isFromBuiltin() == right->isFromBuiltin();
}

bool visitEndAccessInst(const EndAccessInst *right) {
Expand All @@ -400,13 +401,15 @@ namespace {
auto left = cast<BeginUnpairedAccessInst>(LHS);
return left->getAccessKind() == right->getAccessKind()
&& left->getEnforcement() == right->getEnforcement()
&& left->hasNoNestedConflict() == right->hasNoNestedConflict();
&& left->hasNoNestedConflict() == right->hasNoNestedConflict()
&& left->isFromBuiltin() == right->isFromBuiltin();
}

bool visitEndUnpairedAccessInst(const EndUnpairedAccessInst *right) {
auto left = cast<EndUnpairedAccessInst>(LHS);
return left->getEnforcement() == right->getEnforcement()
&& left->isAborting() == right->isAborting();
&& left->isAborting() == right->isAborting()
&& left->isFromBuiltin() == right->isFromBuiltin();
}

bool visitStrongReleaseInst(const StrongReleaseInst *RHS) {
Expand Down
7 changes: 5 additions & 2 deletions lib/SIL/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1846,6 +1846,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
*this << '[' << getSILAccessKindName(BAI->getAccessKind()) << "] ["
<< getSILAccessEnforcementName(BAI->getEnforcement()) << "] "
<< (BAI->hasNoNestedConflict() ? "[no_nested_conflict] " : "")
<< (BAI->isFromBuiltin() ? "[builtin] " : "")
<< getIDAndType(BAI->getOperand());
}
void visitEndAccessInst(EndAccessInst *EAI) {
Expand All @@ -1856,12 +1857,14 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
*this << '[' << getSILAccessKindName(BAI->getAccessKind()) << "] ["
<< getSILAccessEnforcementName(BAI->getEnforcement()) << "] "
<< (BAI->hasNoNestedConflict() ? "[no_nested_conflict] " : "")
<< (BAI->isFromBuiltin() ? "[builtin] " : "")
<< getIDAndType(BAI->getSource()) << ", "
<< getIDAndType(BAI->getBuffer());
}
void visitEndUnpairedAccessInst(EndUnpairedAccessInst *EAI) {
*this << (EAI->isAborting() ? "[abort] " : "")
<< '[' << getSILAccessEnforcementName(EAI->getEnforcement()) << "] "
*this << (EAI->isAborting() ? "[abort] " : "") << '['
<< getSILAccessEnforcementName(EAI->getEnforcement()) << "] "
<< (EAI->isFromBuiltin() ? "[builtin] " : "")
<< getIDAndType(EAI->getOperand());
}

Expand Down
Loading