1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
//===--- Link.cpp - Link in transparent SILFunctions from module ----------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "swift/SIL/SILModule.h"
#include "swift/Serialization/SerializedSILLoader.h"
using namespace swift;
static llvm::cl::opt<bool> LinkEmbeddedRuntime("link-embedded-runtime",
llvm::cl::init(true));
//===----------------------------------------------------------------------===//
// Top Level Driver
//===----------------------------------------------------------------------===//
namespace {
/// Copies code from the standard library into the user program to enable
/// optimizations.
class SILLinker : public SILModuleTransform {
SILModule::LinkingMode LinkMode;
public:
explicit SILLinker(SILModule::LinkingMode LinkMode) : LinkMode(LinkMode) {}
void run() override {
SILModule &M = *getModule();
for (auto &Fn : M)
if (M.linkFunction(&Fn, LinkMode))
invalidateAnalysis(&Fn, SILAnalysis::InvalidationKind::Everything);
// In embedded Swift, the stdlib contains all the runtime functions needed
// (swift_retain, etc.). Link them in so they can be referenced in IRGen.
if (M.getOptions().EmbeddedSwift && LinkEmbeddedRuntime) {
linkEmbeddedRuntimeFromStdlib();
}
}
void linkEmbeddedRuntimeFromStdlib() {
using namespace RuntimeConstants;
#define FUNCTION(ID, NAME, CC, AVAILABILITY, RETURNS, ARGS, ATTRS, EFFECT, \
MEMORY_EFFECTS) \
linkEmbeddedRuntimeFunctionByName(#NAME, EFFECT);
#define RETURNS(...)
#define ARGS(...)
#define NO_ARGS
#define ATTRS(...)
#define NO_ATTRS
#define EFFECT(...) { __VA_ARGS__ }
#define MEMORY_EFFECTS(...)
#define UNKNOWN_MEMEFFECTS
#include "swift/Runtime/RuntimeFunctions.def"
}
void linkEmbeddedRuntimeFunctionByName(StringRef name,
ArrayRef<RuntimeEffect> effects) {
SILModule &M = *getModule();
bool allocating = false;
for (RuntimeEffect rt : effects)
if (rt == RuntimeEffect::Allocating || rt == RuntimeEffect::Deallocating)
allocating = true;
// Don't link allocating runtime functions in -no-allocations mode.
if (M.getOptions().NoAllocations && allocating) return;
// Bail if runtime function is already loaded.
if (M.lookUpFunction(name)) return;
SILFunction *Fn =
M.getSILLoader()->lookupSILFunction(name, SILLinkage::PublicExternal);
if (!Fn) return;
if (M.linkFunction(Fn, LinkMode))
invalidateAnalysis(Fn, SILAnalysis::InvalidationKind::Everything);
// Make sure that dead-function-elimination doesn't remove runtime functions.
// TODO: lazily emit runtime functions in IRGen so that we don't have to
// rely on dead-stripping in the linker to remove unused runtime
// functions.
if (Fn->isDefinition())
Fn->setLinkage(SILLinkage::Public);
}
};
} // end anonymous namespace
SILTransform *swift::createMandatorySILLinker() {
return new SILLinker(SILModule::LinkingMode::LinkNormal);
}
SILTransform *swift::createPerformanceSILLinker() {
return new SILLinker(SILModule::LinkingMode::LinkAll);
}
|