mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
We used to represent these just as normal LLVM functions, e.x.: declare objc_object* @objc_retain(objc_object*) declare void @objc_release(objc_object*) Recently, special objc intrinsics were added to LLVM. This pass updates these small (old) passes to use the new intrinsics. This turned out to not be too difficult since we never create these instructions. We only analyze them, move them, and delete them. rdar://47852297
80 lines
2.7 KiB
C++
80 lines
2.7 KiB
C++
//===--- LLVMARCOpts.h - LLVM level ARC Opts Util. Declarations -*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef SWIFT_LLVMPASSES_LLVMARCOPTS_H
|
|
#define SWIFT_LLVMPASSES_LLVMARCOPTS_H
|
|
|
|
#include "swift/Basic/LLVM.h"
|
|
#include "swift/Runtime/Config.h"
|
|
#include "llvm/ADT/StringSwitch.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/IR/Intrinsics.h"
|
|
|
|
namespace swift {
|
|
|
|
enum RT_Kind {
|
|
#define KIND(Name, MemBehavior) RT_ ## Name,
|
|
#include "LLVMSwift.def"
|
|
};
|
|
|
|
/// Take a look at the specified instruction and classify it into what kind of
|
|
/// runtime entrypoint it is, if any.
|
|
inline RT_Kind classifyInstruction(const llvm::Instruction &I) {
|
|
if (!I.mayReadOrWriteMemory())
|
|
return RT_NoMemoryAccessed;
|
|
|
|
// Non-calls or calls to indirect functions are unknown.
|
|
auto *CI = dyn_cast<llvm::CallInst>(&I);
|
|
if (CI == 0) return RT_Unknown;
|
|
|
|
// First check if we have an objc intrinsic.
|
|
auto intrinsic = CI->getIntrinsicID();
|
|
switch (intrinsic) {
|
|
// This is an intrinsic that we do not understand. It can not be one of our
|
|
// "special" runtime functions as well... so return RT_Unknown early.
|
|
default:
|
|
return RT_Unknown;
|
|
case llvm::Intrinsic::not_intrinsic:
|
|
// If we do not have an intrinsic, break and move onto runtime functions
|
|
// that we identify by name.
|
|
break;
|
|
#define OBJC_FUNC(Name, MemBehavior, TextualName) \
|
|
case llvm::Intrinsic::objc_##TextualName: \
|
|
return RT_##Name;
|
|
#include "LLVMSwift.def"
|
|
}
|
|
|
|
llvm::Function *F = CI->getCalledFunction();
|
|
if (F == nullptr)
|
|
return RT_Unknown;
|
|
|
|
return llvm::StringSwitch<RT_Kind>(F->getName())
|
|
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
|
|
.Case("swift_" #TextualName, RT_ ## Name)
|
|
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
|
|
.Case("__swift_" #TextualName, RT_ ## Name)
|
|
#include "LLVMSwift.def"
|
|
|
|
// Support non-atomic versions of reference counting entry points.
|
|
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
|
|
.Case("swift_nonatomic_" #TextualName, RT_ ## Name)
|
|
#define OBJC_FUNC(Name, MemBehavior, TextualName) \
|
|
.Case("objc_nonatomic_" #TextualName, RT_ ## Name)
|
|
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName)
|
|
#include "LLVMSwift.def"
|
|
|
|
.Default(RT_Unknown);
|
|
}
|
|
|
|
} // end namespace swift
|
|
#endif
|