mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
The devirtualizer performs two optimizations: - If a value is known to have an exact class type, ie it is the result of an alloc_ref, we can devirtualize calls of *non-final* methods, because we know we’re calling that specific method and not an override. - If a method is known to be “effectively final” (it is not open, and there are no overrides inside the module) we can devirtualize it. However the second optimization needs to be disabled if a function is inlinable (F->getResilienceExpansion() == ResilienceExpansion::Minimal).
89 lines
3.6 KiB
C++
89 lines
3.6 KiB
C++
//===--- Devirtualize.h - Helper for devirtualizing apply -------*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 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
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This contains helper functions that perform the work of devirtualizing a
|
|
// given apply when possible.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_SIL_DEVIRTUALIZE_H
|
|
#define SWIFT_SIL_DEVIRTUALIZE_H
|
|
|
|
#include "swift/AST/Decl.h"
|
|
#include "swift/AST/Types.h"
|
|
#include "swift/SIL/SILDeclRef.h"
|
|
#include "swift/SIL/SILFunction.h"
|
|
#include "swift/SIL/SILInstruction.h"
|
|
#include "swift/SIL/SILModule.h"
|
|
#include "swift/SIL/SILType.h"
|
|
#include "swift/SIL/SILValue.h"
|
|
#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h"
|
|
#include "swift/SILOptimizer/Utils/Local.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
|
|
namespace swift {
|
|
namespace OptRemark {
|
|
class Emitter;
|
|
}
|
|
|
|
/// A pair representing results of devirtualization.
|
|
/// - The first element is the value representing the result of the
|
|
/// devirtualized call.
|
|
/// - The second element is the new apply/try_apply instruction.
|
|
/// If no devirtualization was possible, the pair:
|
|
/// <nullptr, FullApplySite()> is returned.
|
|
///
|
|
/// Two elements are required, because a result of the new devirtualized
|
|
/// apply/try_apply instruction (second element) eventually needs to be
|
|
/// casted to produce a properly typed value (first element).
|
|
///
|
|
/// *NOTE* The reason why we use a ValueBase here instead of a SILInstruction is
|
|
/// that a devirtualization result may be a BB arg if there was a cast in
|
|
/// between optional types.
|
|
typedef std::pair<ValueBase *, ApplySite> DevirtualizationResult;
|
|
|
|
/// Compute all subclasses of a given class.
|
|
///
|
|
/// \p CHA class hierarchy analysis
|
|
/// \p CD class declaration
|
|
/// \p ClassType type of the instance
|
|
/// \p M SILModule
|
|
/// \p Subs a container to be used for storing the set of subclasses
|
|
void getAllSubclasses(ClassHierarchyAnalysis *CHA,
|
|
ClassDecl *CD,
|
|
SILType ClassType,
|
|
SILModule &M,
|
|
ClassHierarchyAnalysis::ClassList &Subs);
|
|
|
|
DevirtualizationResult tryDevirtualizeApply(ApplySite AI,
|
|
ClassHierarchyAnalysis *CHA,
|
|
OptRemark::Emitter *ORE = nullptr);
|
|
bool canDevirtualizeApply(FullApplySite AI, ClassHierarchyAnalysis *CHA);
|
|
bool isNominalTypeWithUnboundGenericParameters(SILType Ty, SILModule &M);
|
|
bool canDevirtualizeClassMethod(FullApplySite AI, SILType ClassInstanceType,
|
|
OptRemark::Emitter *ORE = nullptr,
|
|
bool isEffectivelyFinalMethod = false);
|
|
SILFunction *getTargetClassMethod(SILModule &M, SILType ClassOrMetatypeType,
|
|
MethodInst *MI);
|
|
DevirtualizationResult devirtualizeClassMethod(FullApplySite AI,
|
|
SILValue ClassInstance,
|
|
OptRemark::Emitter *ORE);
|
|
DevirtualizationResult
|
|
tryDevirtualizeClassMethod(FullApplySite AI, SILValue ClassInstance,
|
|
OptRemark::Emitter *ORE,
|
|
bool isEffectivelyFinalMethod = false);
|
|
DevirtualizationResult
|
|
tryDevirtualizeWitnessMethod(ApplySite AI, OptRemark::Emitter *ORE);
|
|
}
|
|
|
|
#endif
|