Skip to content

[assembly-vision] Finish rebranding of opt remark gen to Assembly Vision Remark and add @_assemblyVision Attr #37895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 13, 2021
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
5 changes: 5 additions & 0 deletions include/swift/AST/Attr.def
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,11 @@ SIMPLE_DECL_ATTR(_distributedActorIndependent, DistributedActorIndependent,
APIBreakingToAdd | APIBreakingToRemove,
119)

SIMPLE_DECL_ATTR(_assemblyVision, EmitAssemblyVisionRemarks,
OnFunc | UserInaccessible | NotSerialized |
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
120)

#undef TYPE_ATTR
#undef DECL_ATTR_ALIAS
#undef CONTEXTUAL_DECL_ATTR_ALIAS
Expand Down
4 changes: 2 additions & 2 deletions include/swift/SILOptimizer/PassManager/Passes.def
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ PASS(OptimizedMandatoryCombine, "optimized-mandatory-combine",
"Perform -O level mandatory peephole combines")
PASS(BugReducerTester, "bug-reducer-tester",
"sil-bug-reducer Tool Testing by Asserting on a Sentinel Function")
PASS(OptRemarkGenerator, "sil-opt-remark-generator",
"Emit small peephole opt remarks that do not use large analyses")
PASS(AssemblyVisionRemarkGenerator, "assembly-vision-remark-generator",
"Emit assembly vision remarks that provide source level guidance of where runtime calls ended up")
PASS(PruneVTables, "prune-vtables",
"Mark class methods that do not require vtable dispatch")
PASS_RANGE(AllPasses, AADumper, PruneVTables)
Expand Down
10 changes: 10 additions & 0 deletions lib/SIL/IR/SILFunctionBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
//===----------------------------------------------------------------------===//

#include "swift/SIL/SILFunctionBuilder.h"
#include "swift/AST/AttrKind.h"
#include "swift/AST/Availability.h"
#include "swift/AST/Decl.h"
#include "swift/AST/SemanticAttrs.h"

using namespace swift;

SILFunction *SILFunctionBuilder::getOrCreateFunction(
Expand Down Expand Up @@ -45,6 +48,13 @@ void SILFunctionBuilder::addFunctionAttributes(
for (auto *A : Attrs.getAttributes<SemanticsAttr>())
F->addSemanticsAttr(cast<SemanticsAttr>(A)->Value);

// If we are asked to emit assembly vision remarks for this function, mark the
// function as force emitting all optremarks including assembly vision
// remarks. This allows us to emit the assembly vision remarks without needing
// to change any of the underlying optremark mechanisms.
if (auto *A = Attrs.getAttribute(DAK_EmitAssemblyVisionRemarks))
F->addSemanticsAttr(semantics::FORCE_EMIT_OPT_REMARK_PREFIX);

// Propagate @_specialize.
for (auto *A : Attrs.getAttributes<SpecializeAttr>()) {
auto *SA = cast<SpecializeAttr>(A);
Expand Down
4 changes: 2 additions & 2 deletions lib/SILOptimizer/PassManager/PassPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,8 +728,8 @@ static void addLastChanceOptPassPipeline(SILPassPipelinePlan &P) {
// Only has an effect if the -assume-single-thread option is specified.
P.addAssumeSingleThreaded();

// Only has an effect if opt-remark is enabled.
P.addOptRemarkGenerator();
// Emits remarks on all functions with @_assemblyVision attribute.
P.addAssemblyVisionRemarkGenerator();

// FIXME: rdar://72935649 (Miscompile on combining PruneVTables with WMO)
// P.addPruneVTables();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//===--- OptRemarkGenerator.cpp -------------------------------------------===//
//===--- AssemblyVisionRemarkGenerator.cpp --------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand All @@ -12,23 +12,23 @@
///
/// \file
///
/// In this pass, we define the opt-remark-generator, a simple SILVisitor that
/// attempts to infer opt-remarks for the user using heuristics.
/// In this pass, we define the assembly-vision-remark-generator, a simple
/// SILVisitor that attempts to infer remarks for the user using heuristics.
///
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "sil-opt-remark-gen"
#define DEBUG_TYPE "sil-assembly-vision-remark-gen"

#include "swift/AST/SemanticAttrs.h"
#include "swift/Basic/Defer.h"
#include "swift/SIL/DebugUtils.h"
#include "swift/SIL/DynamicCasts.h"
#include "swift/SIL/MemAccessUtils.h"
#include "swift/SIL/OptimizationRemark.h"
#include "swift/SIL/PatternMatch.h"
#include "swift/SIL/Projection.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/PatternMatch.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILVisitor.h"
#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
Expand All @@ -41,13 +41,14 @@ using namespace swift;
using namespace swift::PatternMatch;

static llvm::cl::opt<bool> ForceVisitImplicitAutogeneratedFunctions(
"optremarkgen-visit-implicit-autogen-funcs", llvm::cl::Hidden,
"assemblyvisionremarkgen-visit-implicit-autogen-funcs", llvm::cl::Hidden,
llvm::cl::desc(
"Emit opt remarks even on implicit and autogenerated functions"),
llvm::cl::init(false));

static llvm::cl::opt<bool> DecllessDebugValueUseSILDebugInfo(
"optremarkgen-declless-debugvalue-use-sildebugvar-info", llvm::cl::Hidden,
"assemblyvisionremarkgen-declless-debugvalue-use-sildebugvar-info",
llvm::cl::Hidden,
llvm::cl::desc(
"If a debug_value does not have a decl, infer a value with a name from "
"that info that has a loc set to the loc of the debug_value "
Expand Down Expand Up @@ -98,7 +99,8 @@ struct ValueToDeclInferrer {
///
/// sil @theFunction : $@convention(thin) () -> () {
/// bb0:
/// %0 = apply %getKlassPair() : $@convention(thin) () -> @owned KlassPair
/// %0 = apply %getKlassPair() : $@convention(thin) () -> @owned
/// KlassPair
/// // This debug_value's name can be combined...
/// debug_value %0 : $KlassPair, name "myPair"
/// // ... with the access path from the struct_extract here...
Expand All @@ -119,8 +121,9 @@ struct ValueToDeclInferrer {
/// //
/// // The reason why we must do this is due to the behavior of the late
/// // optimizer and how it forms these patterns in the code.
/// %0a = apply %getStateWithOwningPointer() : $@convention(thin) () -> @owned StateWithOwningPointer
/// %1 = struct_extract %0a : $StateWithOwningPointer, #StateWithOwningPointer.owningPtr
/// %0a = apply %getStateWithOwningPointer() : $@convention(thin) () ->
/// @owned StateWithOwningPointer %1 = struct_extract %0a :
/// $StateWithOwningPointer, #StateWithOwningPointer.owningPtr
/// strong_retain %1 : $Klass
/// %2 = struct $Array(%0 : $Builtin.NativeObject, ...)
/// debug_value %2 : $Array, ...
Expand All @@ -130,7 +133,8 @@ struct ValueToDeclInferrer {

/// Convenience overload that calls:
///
/// printNote(stream, decl->getBaseName().userFacingName(), shouldPrintAccessPath).
/// printNote(stream, decl->getBaseName().userFacingName(),
/// shouldPrintAccessPath).
void printNote(llvm::raw_string_ostream &stream, const ValueDecl *decl,
bool shouldPrintAccessPath = true) {
printNote(stream, decl->getBaseName().userFacingName(),
Expand Down Expand Up @@ -308,9 +312,7 @@ bool ValueToDeclInferrer::infer(
SmallVectorImpl<Argument> &resultingInferredDecls,
bool allowSingleRefEltAddrPeek) {
// Clear the stored access path at end of scope.
SWIFT_DEFER {
accessPath.clear();
};
SWIFT_DEFER { accessPath.clear(); };
ValueUseToDeclInferrer valueUseInferrer{
{}, *this, keyKind, resultingInferredDecls};
bool foundSingleRefElementAddr = false;
Expand Down Expand Up @@ -379,8 +381,9 @@ bool ValueToDeclInferrer::infer(
// A pattern that we see around empty array storage is:
//
// %0 = global_addr @_swiftEmptyArrayStorage : $*_SwiftEmptyArrayStorage
// %1 = address_to_pointer %0 : $*_SwiftEmptyArrayStorage to $Builtin.RawPointer
// %2 = raw_pointer_to_ref %1 : $Builtin.RawPointer to $__EmptyArrayStorage
// %1 = address_to_pointer %0 : $*_SwiftEmptyArrayStorage to
// $Builtin.RawPointer %2 = raw_pointer_to_ref %1 : $Builtin.RawPointer to
// $__EmptyArrayStorage
//
// Recognize this case.
{
Expand Down Expand Up @@ -490,17 +493,18 @@ bool ValueToDeclInferrer::infer(

namespace {

struct OptRemarkGeneratorInstructionVisitor
: public SILInstructionVisitor<OptRemarkGeneratorInstructionVisitor> {
struct AssemblyVisionRemarkGeneratorInstructionVisitor
: public SILInstructionVisitor<
AssemblyVisionRemarkGeneratorInstructionVisitor> {
SILModule &mod;
OptRemark::Emitter ORE;

/// A class that we use to infer the decl that is associated with a
/// miscellaneous SIL value. This is just a heuristic that is to taste.
ValueToDeclInferrer valueToDeclInferrer;

OptRemarkGeneratorInstructionVisitor(SILFunction &fn,
RCIdentityFunctionInfo &rcfi)
AssemblyVisionRemarkGeneratorInstructionVisitor(SILFunction &fn,
RCIdentityFunctionInfo &rcfi)
: mod(fn.getModule()), ORE(DEBUG_TYPE, fn), valueToDeclInferrer(rcfi) {}

void visitStrongRetainInst(StrongRetainInst *sri);
Expand All @@ -519,7 +523,7 @@ struct OptRemarkGeneratorInstructionVisitor

} // anonymous namespace

void OptRemarkGeneratorInstructionVisitor::
void AssemblyVisionRemarkGeneratorInstructionVisitor::
visitUnconditionalCheckedCastAddrInst(
UnconditionalCheckedCastAddrInst *uccai) {
ORE.emit([&]() {
Expand All @@ -542,8 +546,8 @@ void OptRemarkGeneratorInstructionVisitor::
});
}

void OptRemarkGeneratorInstructionVisitor::visitCheckedCastAddrBranchInst(
CheckedCastAddrBranchInst *ccabi) {
void AssemblyVisionRemarkGeneratorInstructionVisitor::
visitCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *ccabi) {
ORE.emit([&]() {
using namespace OptRemark;
SmallVector<Argument, 8> inferredArgs;
Expand All @@ -564,7 +568,7 @@ void OptRemarkGeneratorInstructionVisitor::visitCheckedCastAddrBranchInst(
});
}

void OptRemarkGeneratorInstructionVisitor::visitBeginAccessInst(
void AssemblyVisionRemarkGeneratorInstructionVisitor::visitBeginAccessInst(
BeginAccessInst *bai) {
ORE.emit([&]() {
using namespace OptRemark;
Expand All @@ -586,7 +590,7 @@ void OptRemarkGeneratorInstructionVisitor::visitBeginAccessInst(
});
}

void OptRemarkGeneratorInstructionVisitor::visitEndAccessInst(
void AssemblyVisionRemarkGeneratorInstructionVisitor::visitEndAccessInst(
EndAccessInst *eai) {
ORE.emit([&]() {
using namespace OptRemark;
Expand All @@ -611,7 +615,7 @@ void OptRemarkGeneratorInstructionVisitor::visitEndAccessInst(
});
}

void OptRemarkGeneratorInstructionVisitor::visitStrongRetainInst(
void AssemblyVisionRemarkGeneratorInstructionVisitor::visitStrongRetainInst(
StrongRetainInst *sri) {
ORE.emit([&]() {
using namespace OptRemark;
Expand All @@ -633,7 +637,7 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongRetainInst(
});
}

void OptRemarkGeneratorInstructionVisitor::visitStrongReleaseInst(
void AssemblyVisionRemarkGeneratorInstructionVisitor::visitStrongReleaseInst(
StrongReleaseInst *sri) {
ORE.emit([&]() {
using namespace OptRemark;
Expand All @@ -656,7 +660,7 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongReleaseInst(
});
}

void OptRemarkGeneratorInstructionVisitor::visitRetainValueInst(
void AssemblyVisionRemarkGeneratorInstructionVisitor::visitRetainValueInst(
RetainValueInst *rvi) {
ORE.emit([&]() {
using namespace OptRemark;
Expand All @@ -677,7 +681,7 @@ void OptRemarkGeneratorInstructionVisitor::visitRetainValueInst(
});
}

void OptRemarkGeneratorInstructionVisitor::visitReleaseValueInst(
void AssemblyVisionRemarkGeneratorInstructionVisitor::visitReleaseValueInst(
ReleaseValueInst *rvi) {
ORE.emit([&]() {
using namespace OptRemark;
Expand All @@ -699,7 +703,7 @@ void OptRemarkGeneratorInstructionVisitor::visitReleaseValueInst(
});
}

void OptRemarkGeneratorInstructionVisitor::visitAllocRefInst(
void AssemblyVisionRemarkGeneratorInstructionVisitor::visitAllocRefInst(
AllocRefInst *ari) {
if (ari->canAllocOnStack()) {
return ORE.emit([&]() {
Expand Down Expand Up @@ -735,7 +739,7 @@ void OptRemarkGeneratorInstructionVisitor::visitAllocRefInst(
});
}

void OptRemarkGeneratorInstructionVisitor::visitAllocBoxInst(
void AssemblyVisionRemarkGeneratorInstructionVisitor::visitAllocBoxInst(
AllocBoxInst *abi) {
return ORE.emit([&]() {
using namespace OptRemark;
Expand All @@ -760,8 +764,8 @@ void OptRemarkGeneratorInstructionVisitor::visitAllocBoxInst(

namespace {

class OptRemarkGenerator : public SILFunctionTransform {
~OptRemarkGenerator() override {}
class AssemblyVisionRemarkGenerator : public SILFunctionTransform {
~AssemblyVisionRemarkGenerator() override {}

bool isOptRemarksEnabled() {
auto *fn = getFunction();
Expand Down Expand Up @@ -798,7 +802,7 @@ class OptRemarkGenerator : public SILFunctionTransform {

LLVM_DEBUG(llvm::dbgs() << "Visiting: " << fn->getName() << "\n");
auto &rcfi = *getAnalysis<RCIdentityAnalysis>()->get(fn);
OptRemarkGeneratorInstructionVisitor visitor(*fn, rcfi);
AssemblyVisionRemarkGeneratorInstructionVisitor visitor(*fn, rcfi);
for (auto &block : *fn) {
for (auto &inst : block) {
visitor.visit(&inst);
Expand All @@ -809,6 +813,6 @@ class OptRemarkGenerator : public SILFunctionTransform {

} // end anonymous namespace

SILTransform *swift::createOptRemarkGenerator() {
return new OptRemarkGenerator();
SILTransform *swift::createAssemblyVisionRemarkGenerator() {
return new AssemblyVisionRemarkGenerator();
}
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ target_sources(swiftSILOptimizer PRIVATE
MergeCondFail.cpp
Outliner.cpp
ObjectOutliner.cpp
OptRemarkGenerator.cpp
AssemblyVisionRemarkGenerator.cpp
PerformanceInliner.cpp
PhiArgumentOptimizations.cpp
PruneVTables.cpp
Expand Down
1 change: 1 addition & 0 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
IGNORED_ATTR(RequiresStoredPropertyInits)
IGNORED_ATTR(RestatedObjCConformance)
IGNORED_ATTR(Semantics)
IGNORED_ATTR(EmitAssemblyVisionRemarks)
IGNORED_ATTR(ShowInInterface)
IGNORED_ATTR(SILGenName)
IGNORED_ATTR(StaticInitializeObjCMetadata)
Expand Down
1 change: 1 addition & 0 deletions lib/Sema/TypeCheckDeclOverride.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1480,6 +1480,7 @@ namespace {
UNINTERESTING_ATTR(Required)
UNINTERESTING_ATTR(Convenience)
UNINTERESTING_ATTR(Semantics)
UNINTERESTING_ATTR(EmitAssemblyVisionRemarks)
UNINTERESTING_ATTR(SetterAccess)
UNINTERESTING_ATTR(TypeEraser)
UNINTERESTING_ATTR(SPIAccessControl)
Expand Down
2 changes: 1 addition & 1 deletion lib/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_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 SWIFTMODULE_VERSION_MINOR = 615; // isolated parameters
const uint16_t SWIFTMODULE_VERSION_MINOR = 616; // @_assemblyVision

/// A standard hash seed used for all string hashes in a serialized module.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public func forceOptRemark() {
// expected-note @-2 {{of 'x'}}
}

@_semantics("optremark.sil-opt-remark-gen")
@_semantics("optremark.sil-assembly-vision-remark-gen")
@inline(never)
public func forceOptRemark2() {
let x = getGlobal()
Expand Down Expand Up @@ -55,7 +55,7 @@ public func allocateInlineCallee3() -> Klass {
}

@_semantics("optremark.sil-inliner")
@_semantics("optremark.sil-opt-remark-gen")
@_semantics("optremark.sil-assembly-vision-remark-gen")
public func mix1() -> (Klass, Klass) {
let x = getGlobal()
return (x, Klass()) // expected-remark {{Pure call. Always profitable to inline "main.Klass.__allocating_init()"}}
Expand All @@ -68,7 +68,7 @@ public func mix2() -> (Klass, Klass) {
return (x, Klass()) // expected-remark {{Pure call. Always profitable to inline "main.Klass.__allocating_init()"}}
}

@_semantics("optremark.sil-opt-remark-gen")
@_semantics("optremark.sil-assembly-vision-remark-gen")
public func mix3() -> (Klass, Klass) {
let x = getGlobal()
return (x, Klass()) // expected-remark {{heap allocated ref of type 'Klass'}}
Expand All @@ -85,3 +85,10 @@ public func mix5() -> (Klass, Klass) {
let x = getGlobal()
return (x, Klass())
}

@_assemblyVision
public func mix4a() -> (Klass, Klass) {
let x = getGlobal()
return (x, Klass()) // expected-remark {{Pure call. Always profitable to inline "main.Klass.__allocating_init()"}}
// expected-remark @-1 {{heap allocated ref of type 'Klass'}}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-sil-opt -sil-opt-remark-ignore-always-infer -optremarkgen-declless-debugvalue-use-sildebugvar-info -sil-opt-remark-generator -sil-remarks-missed=sil-opt-remark-gen -verify %s -o /dev/null
// RUN: %target-sil-opt -sil-opt-remark-ignore-always-infer -assemblyvisionremarkgen-declless-debugvalue-use-sildebugvar-info -assembly-vision-remark-generator -sil-remarks-missed=sil-assembly-vision-remark-gen -verify %s -o /dev/null

sil_stage canonical

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swiftc_driver -O -Rpass-missed=sil-opt-remark-gen -Xllvm -sil-disable-pass=FunctionSignatureOpts -Xfrontend -enable-copy-propagation -emit-sil %s -o /dev/null -Xfrontend -verify
// RUN: %target-swiftc_driver -O -Rpass-missed=sil-assembly-vision-remark-gen -Xllvm -sil-disable-pass=FunctionSignatureOpts -Xfrontend -enable-copy-propagation -emit-sil %s -o /dev/null -Xfrontend -verify
// REQUIRES: optimized_stdlib,swift_stdlib_no_asserts

public class Klass {
Expand Down
Loading