Skip to content

Commit f2995a1

Browse files
authored
Merge pull request #60979 from hamishknight/fixed-value
2 parents 7bf6803 + b12015c commit f2995a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+427
-226
lines changed

docs/SIL.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3898,6 +3898,22 @@ It is worth noting that a SIL DIExpression is similar to
38983898
info metadata. While LLVM represents ``!DIExpression`` are a list of 64-bit integers,
38993899
SIL DIExpression can have elements with various types, like AST nodes or strings.
39003900

3901+
Profiling
3902+
~~~~~~~~~
3903+
3904+
increment_profiler_counter
3905+
``````````````````````````
3906+
::
3907+
3908+
sil-instruction ::= 'increment_profiler_counter' int-literal ',' string-literal ',' 'num_counters' int-literal ',' 'hash' int-literal
3909+
3910+
increment_profiler_counter 1, "$foo", num_counters 3, hash 0
3911+
3912+
Increments a given profiler counter for a given PGO function name. This is
3913+
lowered to the ``llvm.instrprof.increment`` LLVM intrinsic. This instruction
3914+
is emitted when profiling is enabled, and enables features such as code coverage
3915+
and profile-guided optimization.
3916+
39013917
Accessing Memory
39023918
~~~~~~~~~~~~~~~~
39033919

include/swift/AST/Builtins.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -738,9 +738,6 @@ BUILTIN_MISC_OPERATION(PoundAssert, "poundAssert", "", Special)
738738
// TypePtrAuthDiscriminator has type <T> (T.Type) -> Int64
739739
BUILTIN_MISC_OPERATION(TypePtrAuthDiscriminator, "typePtrAuthDiscriminator", "n", Special)
740740

741-
// int_instrprof_increment has type (Builtin.RawPointer, Builtin.Int64, Builtin.Int32, Builtin.Int32) -> ().
742-
BUILTIN_MISC_OPERATION(IntInstrprofIncrement, "int_instrprof_increment", "", Special)
743-
744741
/// Initialize the default-actor instance in a default actor object.
745742
BUILTIN_MISC_OPERATION(InitializeDefaultActor, "initializeDefaultActor", "", Special)
746743

include/swift/AST/DiagnosticsParse.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,14 @@ ERROR(sil_invalid_attribute_for_instruction,none,
531531
ERROR(sil_invalid_attribute_for_expected,none,
532532
"Invalid attribute '%0' (expected '%1').",
533533
(StringRef, StringRef))
534+
ERROR(expected_sil_profiler_counter_idx,none,
535+
"expected profiler counter index", ())
536+
ERROR(expected_sil_profiler_counter_pgo_func_name,none,
537+
"expected profiler counter PGO function name", ())
538+
ERROR(expected_sil_profiler_counter_total,none,
539+
"expected profiler counter total", ())
540+
ERROR(expected_sil_profiler_counter_hash,none,
541+
"expected profiler counter hash", ())
534542

535543
// SIL Values
536544
ERROR(sil_value_redefinition,none,

include/swift/SIL/SILBuilder.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,19 @@ class SILBuilder {
21312131
return createCondFail(loc, one, message);
21322132
}
21332133

2134+
//===--------------------------------------------------------------------===//
2135+
// Profiler
2136+
//===--------------------------------------------------------------------===//
2137+
2138+
IncrementProfilerCounterInst *
2139+
createIncrementProfilerCounter(SILLocation Loc, unsigned CounterIdx,
2140+
StringRef PGOFuncName, unsigned NumCounters,
2141+
uint64_t PGOFuncHash) {
2142+
return insert(IncrementProfilerCounterInst::create(
2143+
getSILDebugLocation(Loc), CounterIdx, PGOFuncName, NumCounters,
2144+
PGOFuncHash, getModule()));
2145+
}
2146+
21342147
//===--------------------------------------------------------------------===//
21352148
// Array indexing instructions
21362149
//===--------------------------------------------------------------------===//

include/swift/SIL/SILCloner.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,6 +2620,17 @@ SILCloner<ImplClass>::visitCondFailInst(CondFailInst *Inst) {
26202620
Inst->getMessage()));
26212621
}
26222622

2623+
template <typename ImplClass>
2624+
void SILCloner<ImplClass>::visitIncrementProfilerCounterInst(
2625+
IncrementProfilerCounterInst *Inst) {
2626+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2627+
recordClonedInstruction(Inst,
2628+
getBuilder().createIncrementProfilerCounter(
2629+
getOpLocation(Inst->getLoc()),
2630+
Inst->getCounterIndex(), Inst->getPGOFuncName(),
2631+
Inst->getNumCounters(), Inst->getPGOFuncHash()));
2632+
}
2633+
26232634
template<typename ImplClass>
26242635
void
26252636
SILCloner<ImplClass>::visitIndexAddrInst(IndexAddrInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3858,7 +3858,53 @@ class BuiltinInst final
38583858
return OperandValueArrayRef(getAllOperands());
38593859
}
38603860
};
3861-
3861+
3862+
/// Increments a given profiler counter for a given PGO function name. This is
3863+
/// lowered to the \c llvm.instrprof.increment LLVM intrinsic.
3864+
class IncrementProfilerCounterInst final
3865+
: public InstructionBase<SILInstructionKind::IncrementProfilerCounterInst,
3866+
NonValueInstruction>,
3867+
private llvm::TrailingObjects<IncrementProfilerCounterInst, char> {
3868+
friend TrailingObjects;
3869+
friend SILBuilder;
3870+
3871+
unsigned CounterIdx;
3872+
unsigned PGOFuncNameLength;
3873+
unsigned NumCounters;
3874+
uint64_t PGOFuncHash;
3875+
3876+
IncrementProfilerCounterInst(SILDebugLocation Loc, unsigned CounterIdx,
3877+
unsigned PGOFuncNameLength, unsigned NumCounters,
3878+
uint64_t PGOFuncHash)
3879+
: InstructionBase(Loc), CounterIdx(CounterIdx),
3880+
PGOFuncNameLength(PGOFuncNameLength), NumCounters(NumCounters),
3881+
PGOFuncHash(PGOFuncHash) {}
3882+
3883+
static IncrementProfilerCounterInst *
3884+
create(SILDebugLocation Loc, unsigned CounterIdx, StringRef PGOFuncName,
3885+
unsigned NumCounters, uint64_t PGOFuncHash, SILModule &M);
3886+
3887+
public:
3888+
/// The index of the counter to be incremented.
3889+
unsigned getCounterIndex() const { return CounterIdx; }
3890+
3891+
/// The PGO function name for the function in which the counter resides.
3892+
StringRef getPGOFuncName() const {
3893+
return StringRef(getTrailingObjects<char>(), PGOFuncNameLength);
3894+
}
3895+
3896+
/// The total number of counters within the function.
3897+
unsigned getNumCounters() const { return NumCounters; }
3898+
3899+
/// A hash value for the function used to determine whether the profile is
3900+
/// outdated.
3901+
/// FIXME: This is currently always 0.
3902+
uint64_t getPGOFuncHash() const { return PGOFuncHash; }
3903+
3904+
ArrayRef<Operand> getAllOperands() const { return {}; }
3905+
MutableArrayRef<Operand> getAllOperands() { return {}; }
3906+
};
3907+
38623908
/// Initializes a SIL global variable. Only valid once, before any
38633909
/// usages of the global via GlobalAddrInst.
38643910
class AllocGlobalInst

include/swift/SIL/SILNodes.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,10 @@ NON_VALUE_INST(AbortApplyInst, abort_apply,
810810
BRIDGED_NON_VALUE_INST(CondFailInst, cond_fail,
811811
SILInstruction, MayHaveSideEffects, DoesNotRelease)
812812

813-
NODE_RANGE(NonValueInstruction, UnreachableInst, CondFailInst)
813+
NON_VALUE_INST(IncrementProfilerCounterInst, increment_profiler_counter,
814+
SILInstruction, MayReadWrite, DoesNotRelease)
815+
816+
NODE_RANGE(NonValueInstruction, UnreachableInst, IncrementProfilerCounterInst)
814817

815818
ABSTRACT_INST(MultipleValueInstruction, SILInstruction)
816819
MULTIPLE_VALUE_INST(BeginApplyInst, begin_apply,

lib/AST/Builtins.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,15 +1190,6 @@ static ValueDecl *getCOWBufferForReading(ASTContext &C, Identifier Id) {
11901190
return builder.build(Id);
11911191
}
11921192

1193-
static ValueDecl *getIntInstrprofIncrement(ASTContext &C, Identifier Id) {
1194-
// (Builtin.RawPointer, Builtin.Int64, Builtin.Int32, Builtin.Int32) -> ()
1195-
Type Int64Ty = BuiltinIntegerType::get(64, C);
1196-
Type Int32Ty = BuiltinIntegerType::get(32, C);
1197-
return getBuiltinFunction(Id,
1198-
{C.TheRawPointerType, Int64Ty, Int32Ty, Int32Ty},
1199-
TupleType::getEmpty(C));
1200-
}
1201-
12021193
static ValueDecl *getTypePtrAuthDiscriminator(ASTContext &C, Identifier Id) {
12031194
// <T : AnyObject> (T.Type) -> Int64
12041195
BuiltinFunctionBuilder builder(C);
@@ -2844,9 +2835,6 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
28442835
{},
28452836
TupleType::getEmpty(Context));
28462837

2847-
case BuiltinValueKind::IntInstrprofIncrement:
2848-
return getIntInstrprofIncrement(Context, Id);
2849-
28502838
case BuiltinValueKind::TypePtrAuthDiscriminator:
28512839
return getTypePtrAuthDiscriminator(Context, Id);
28522840

lib/IRGen/GenBuiltin.cpp

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -400,56 +400,6 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
400400
return;
401401
}
402402

403-
// Calls to the int_instrprof_increment intrinsic are emitted during SILGen.
404-
// At that stage, the function name GV used by the profiling pass is hidden.
405-
// Fix the intrinsic call here by pointing it to the correct GV.
406-
if (IID == llvm::Intrinsic::instrprof_increment) {
407-
// If we import profiling intrinsics from a swift module but profiling is
408-
// not enabled, ignore the increment.
409-
SILModule &SILMod = IGF.getSILModule();
410-
const auto &Opts = SILMod.getOptions();
411-
if (!Opts.GenerateProfile) {
412-
(void)args.claimAll();
413-
return;
414-
}
415-
416-
// Extract the PGO function name.
417-
auto *NameGEP = cast<llvm::User>(args.claimNext());
418-
auto *NameGV = dyn_cast<llvm::GlobalVariable>(NameGEP->stripPointerCasts());
419-
420-
// TODO: The SIL optimizer may rewrite the name argument in a way that
421-
// makes it impossible to lower. Until that issue is fixed, defensively
422-
// refuse to lower ill-formed intrinsics (rdar://39146527).
423-
if (!NameGV) {
424-
(void)args.claimAll();
425-
return;
426-
}
427-
428-
auto *NameC = NameGV->getInitializer();
429-
StringRef Name = cast<llvm::ConstantDataArray>(NameC)->getRawDataValues();
430-
StringRef PGOFuncName = Name.rtrim(StringRef("\0", 1));
431-
432-
// Point the increment call to the right function name variable.
433-
std::string PGOFuncNameVar = llvm::getPGOFuncNameVarName(
434-
PGOFuncName, llvm::GlobalValue::LinkOnceAnyLinkage);
435-
auto *FuncNamePtr = IGF.IGM.Module.getNamedGlobal(PGOFuncNameVar);
436-
if (!FuncNamePtr)
437-
FuncNamePtr = llvm::createPGOFuncNameVar(
438-
*IGF.IGM.getModule(), llvm::GlobalValue::LinkOnceAnyLinkage,
439-
PGOFuncName);
440-
441-
llvm::SmallVector<llvm::Value *, 2> Indices(2, NameGEP->getOperand(1));
442-
NameGEP = llvm::ConstantExpr::getGetElementPtr(
443-
((llvm::PointerType *)FuncNamePtr->getType())->getPointerElementType(),
444-
FuncNamePtr, makeArrayRef(Indices));
445-
446-
// Replace the placeholder value with the new GEP.
447-
Explosion replacement;
448-
replacement.add(NameGEP);
449-
replacement.add(args.claimAll());
450-
args = std::move(replacement);
451-
}
452-
453403
// Implement the ptrauth builtins as no-ops when the Clang
454404
// intrinsics are disabled.
455405
if ((IID == llvm::Intrinsic::ptrauth_sign ||

lib/IRGen/IRGenSIL.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1315,7 +1315,9 @@ class IRGenSILFunction :
13151315
void visitRebindMemoryInst(RebindMemoryInst *i);
13161316

13171317
void visitCondFailInst(CondFailInst *i);
1318-
1318+
1319+
void visitIncrementProfilerCounterInst(IncrementProfilerCounterInst *I);
1320+
13191321
void visitConvertFunctionInst(ConvertFunctionInst *i);
13201322
void visitConvertEscapeToNoEscapeInst(ConvertEscapeToNoEscapeInst *i);
13211323
void visitUpcastInst(UpcastInst *i);
@@ -6956,6 +6958,39 @@ void IRGenSILFunction::visitCondFailInst(swift::CondFailInst *i) {
69566958
FailBBs.push_back(failBB);
69576959
}
69586960

6961+
void IRGenSILFunction::visitIncrementProfilerCounterInst(
6962+
IncrementProfilerCounterInst *i) {
6963+
// If we import profiling intrinsics from a swift module but profiling is
6964+
// not enabled, ignore the increment.
6965+
if (!getSILModule().getOptions().GenerateProfile)
6966+
return;
6967+
6968+
// Retrieve the global variable that stores the PGO function name, creating it
6969+
// if needed.
6970+
auto funcName = i->getPGOFuncName();
6971+
auto varLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
6972+
auto *nameVar = IGM.Module.getNamedGlobal(
6973+
llvm::getPGOFuncNameVarName(funcName, varLinkage));
6974+
if (!nameVar)
6975+
nameVar = llvm::createPGOFuncNameVar(IGM.Module, varLinkage, funcName);
6976+
6977+
// We need to GEP the function name global to point to the first character of
6978+
// the string.
6979+
llvm::SmallVector<llvm::Value *, 2> indices;
6980+
indices.append(2, llvm::ConstantInt::get(IGM.SizeTy, 0));
6981+
auto *nameGEP = llvm::ConstantExpr::getGetElementPtr(
6982+
nameVar->getValueType(), nameVar, makeArrayRef(indices));
6983+
6984+
// Emit the call to the 'llvm.instrprof.increment' LLVM intrinsic.
6985+
llvm::Value *args[] = {
6986+
nameGEP,
6987+
llvm::ConstantInt::get(IGM.Int64Ty, i->getPGOFuncHash()),
6988+
llvm::ConstantInt::get(IGM.Int32Ty, i->getNumCounters()),
6989+
llvm::ConstantInt::get(IGM.Int32Ty, i->getCounterIndex())
6990+
};
6991+
Builder.CreateIntrinsicCall(llvm::Intrinsic::instrprof_increment, args);
6992+
}
6993+
69596994
void IRGenSILFunction::visitSuperMethodInst(swift::SuperMethodInst *i) {
69606995
assert(!i->getMember().isForeign);
69616996

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ SHOULD_NEVER_VISIT_INST(ReleaseValue)
119119
SHOULD_NEVER_VISIT_INST(ReleaseValueAddr)
120120
SHOULD_NEVER_VISIT_INST(StrongRelease)
121121
SHOULD_NEVER_VISIT_INST(GetAsyncContinuation)
122+
SHOULD_NEVER_VISIT_INST(IncrementProfilerCounter)
122123

123124
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
124125
SHOULD_NEVER_VISIT_INST(StrongRetain##Name) \
@@ -794,7 +795,6 @@ BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, PoundAssert)
794795
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, GlobalStringTablePointer)
795796
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, TypePtrAuthDiscriminator)
796797
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, TargetOSVersionAtLeast)
797-
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, IntInstrprofIncrement)
798798
BUILTIN_OPERAND_OWNERSHIP(UnownedInstantaneousUse, Copy)
799799
BUILTIN_OPERAND_OWNERSHIP(DestroyingConsume, StartAsyncLet)
800800
BUILTIN_OPERAND_OWNERSHIP(DestroyingConsume, EndAsyncLet)

lib/SIL/IR/SILInstructions.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,22 @@ BuiltinInst::BuiltinInst(SILDebugLocation Loc, Identifier Name,
438438
Substitutions(Subs) {
439439
}
440440

441+
IncrementProfilerCounterInst *IncrementProfilerCounterInst::create(
442+
SILDebugLocation Loc, unsigned CounterIdx, StringRef PGOFuncName,
443+
unsigned NumCounters, uint64_t PGOFuncHash, SILModule &M) {
444+
445+
auto PGOFuncNameLength = PGOFuncName.size();
446+
auto Size = totalSizeToAlloc<char>(PGOFuncNameLength);
447+
auto Buffer = M.allocateInst(Size, alignof(IncrementProfilerCounterInst));
448+
449+
auto *Inst = ::new (Buffer) IncrementProfilerCounterInst(
450+
Loc, CounterIdx, PGOFuncNameLength, NumCounters, PGOFuncHash);
451+
452+
std::uninitialized_copy(PGOFuncName.begin(), PGOFuncName.end(),
453+
Inst->getTrailingObjects<char>());
454+
return Inst;
455+
}
456+
441457
InitBlockStorageHeaderInst *
442458
InitBlockStorageHeaderInst::create(SILFunction &F,
443459
SILDebugLocation DebugLoc, SILValue BlockStorage,

lib/SIL/IR/SILPrinter.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2359,7 +2359,14 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
23592359
*this << getIDAndType(FI->getOperand()) << ", "
23602360
<< QuotedString(FI->getMessage());
23612361
}
2362-
2362+
2363+
void visitIncrementProfilerCounterInst(IncrementProfilerCounterInst *IPCI) {
2364+
*this << IPCI->getCounterIndex() << ", "
2365+
<< QuotedString(IPCI->getPGOFuncName()) << ", "
2366+
<< "num_counters " << IPCI->getNumCounters() << ", "
2367+
<< "hash " << IPCI->getPGOFuncHash();
2368+
}
2369+
23632370
void visitIndexAddrInst(IndexAddrInst *IAI) {
23642371
*this << getIDAndType(IAI->getBase()) << ", "
23652372
<< getIDAndType(IAI->getIndex());

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,6 @@ CONSTANT_OWNERSHIP_BUILTIN(None, TSanInoutAccess)
532532
CONSTANT_OWNERSHIP_BUILTIN(None, Swift3ImplicitObjCEntrypoint)
533533
CONSTANT_OWNERSHIP_BUILTIN(None, PoundAssert)
534534
CONSTANT_OWNERSHIP_BUILTIN(None, TypePtrAuthDiscriminator)
535-
CONSTANT_OWNERSHIP_BUILTIN(None, IntInstrprofIncrement)
536535
CONSTANT_OWNERSHIP_BUILTIN(None, TargetOSVersionAtLeast)
537536
CONSTANT_OWNERSHIP_BUILTIN(None, GlobalStringTablePointer)
538537
CONSTANT_OWNERSHIP_BUILTIN(None, GetCurrentAsyncTask)

0 commit comments

Comments
 (0)