Files
swift-mirror/lib/IRGen/IRGenModule.cpp
John McCall 8499117b59 The value witnesses for size/alignment/stride can just be size_t's.
This requires us to potentially copy the value witness tables for
generic struct types as part of computing layout, but that's not
the end of the world (although it will rely on a future patch
to split value witnesses out from protocol witness tables).

Oh, and add a value witness for stride, changing Builtin.strideof
to use that.

Swift SVN r2829
2012-09-06 08:23:14 +00:00

221 lines
7.8 KiB
C++

//===--- IRGenModule.cpp - Swift Global LLVM IR Generation ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements IR generation for global declarations in Swift.
//
//===----------------------------------------------------------------------===//
#include "swift/AST/ASTContext.h"
#include "swift/AST/Module.h"
#include "swift/AST/Stmt.h"
#include "swift/AST/Diagnostics.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Intrinsics.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Target/TargetData.h"
#include "GenType.h"
#include "IRGenModule.h"
#include "Linking.h"
using namespace swift;
using namespace irgen;
IRGenModule::IRGenModule(ASTContext &Context,
Options &Opts, llvm::Module &Module,
const llvm::TargetData &TargetData)
: Context(Context), Opts(Opts),
Module(Module), LLVMContext(Module.getContext()),
TargetData(TargetData), Types(*new TypeConverter(*this)) {
VoidTy = llvm::Type::getVoidTy(getLLVMContext());
Int1Ty = llvm::Type::getInt1Ty(getLLVMContext());
Int8Ty = llvm::Type::getInt8Ty(getLLVMContext());
Int16Ty = llvm::Type::getInt16Ty(getLLVMContext());
Int32Ty = llvm::Type::getInt32Ty(getLLVMContext());
Int64Ty = llvm::Type::getInt64Ty(getLLVMContext());
Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
SizeTy = TargetData.getIntPtrType(getLLVMContext());
MemCpyFn = nullptr;
AllocObjectFn = nullptr;
RetainNoResultFn = nullptr;
ReleaseFn = nullptr;
DeallocObjectFn = nullptr;
ObjCRetainFn = nullptr;
ObjCReleaseFn = nullptr;
RawAllocFn = nullptr;
RawDeallocFn = nullptr;
SlowAllocFn = nullptr;
SlowRawDeallocFn = nullptr;
RefCountedStructTy =
llvm::StructType::create(getLLVMContext(), "swift.refcounted");
RefCountedPtrTy = RefCountedStructTy->getPointerTo(/*addrspace*/ 0);
RefCountedNull = llvm::ConstantPointerNull::get(RefCountedPtrTy);
DtorTy = llvm::FunctionType::get(SizeTy, RefCountedPtrTy, false);
llvm::Type *dtorPtrTy = DtorTy->getPointerTo();
llvm::Type *heapMetadataElts[] = { dtorPtrTy, dtorPtrTy };
HeapMetadataStructTy =
llvm::StructType::create(getLLVMContext(), heapMetadataElts,
"swift.heapmetadata");
HeapMetadataPtrTy = HeapMetadataStructTy->getPointerTo(/*addrspace*/ 0);
llvm::Type *refCountedElts[] = { HeapMetadataPtrTy, SizeTy };
RefCountedStructTy->setBody(refCountedElts);
PtrSize = Size(TargetData.getPointerSize());
llvm::Type *funcElts[] = { Int8PtrTy, RefCountedPtrTy };
FunctionPairTy = llvm::StructType::get(LLVMContext, funcElts,
/*packed*/ false);
OpaquePtrTy = llvm::StructType::create(LLVMContext, "swift.opaque")
->getPointerTo(0);
FixedBufferTy = nullptr;
for (unsigned i = 0; i != NumValueWitnessFunctions; ++i)
ValueWitnessTys[i] = nullptr;
ObjCPtrTy = llvm::StructType::create(getLLVMContext(), "objc_object")
->getPointerTo(0);
// TODO: use "tinycc" on platforms that support it
RuntimeCC = llvm::CallingConv::C;
}
IRGenModule::~IRGenModule() {
delete &Types;
}
static llvm::Constant *createRuntimeFunction(IRGenModule &IGM, StringRef name,
llvm::FunctionType *fnType) {
llvm::Constant *addr = IGM.Module.getOrInsertFunction(name, fnType);
if (auto fn = dyn_cast<llvm::Function>(addr))
fn->setCallingConv(IGM.RuntimeCC);
return addr;
}
llvm::Constant *IRGenModule::getAllocObjectFn() {
if (AllocObjectFn) return AllocObjectFn;
llvm::Type *types[] = { HeapMetadataPtrTy, SizeTy, SizeTy };
llvm::FunctionType *fnType =
llvm::FunctionType::get(RefCountedPtrTy, types, false);
AllocObjectFn = createRuntimeFunction(*this, "swift_allocObject", fnType);
return AllocObjectFn;
}
llvm::Constant *IRGenModule::getRawAllocFn() {
if (RawAllocFn) return RawAllocFn;
/// void *swift_rawAlloc(SwiftAllocIndex index);
llvm::FunctionType *fnType =
llvm::FunctionType::get(Int8PtrTy, SizeTy, false);
RawAllocFn = createRuntimeFunction(*this, "swift_rawAlloc", fnType);
return RawAllocFn;
}
llvm::Constant *IRGenModule::getRawDeallocFn() {
if (RawDeallocFn) return RawDeallocFn;
/// void swift_rawDealloc(void *ptr, SwiftAllocIndex index);
llvm::Type *types[] = { Int8PtrTy, SizeTy };
llvm::FunctionType *fnType =
llvm::FunctionType::get(VoidTy, types, false);
RawDeallocFn = createRuntimeFunction(*this, "swift_rawDealloc", fnType);
return RawDeallocFn;
}
llvm::Constant *IRGenModule::getSlowAllocFn() {
if (SlowAllocFn) return SlowAllocFn;
/// void *swift_slowAlloc(size_t size, size_t flags);
llvm::Type *argTypes[] = { SizeTy, SizeTy };
llvm::FunctionType *fnType =
llvm::FunctionType::get(Int8PtrTy, argTypes, false);
SlowAllocFn = createRuntimeFunction(*this, "swift_slowAlloc", fnType);
return SlowAllocFn;
}
llvm::Constant *IRGenModule::getSlowRawDeallocFn() {
if (SlowRawDeallocFn) return SlowRawDeallocFn;
/// void swift_slowRawDealloc(void *ptr, size_t size);
llvm::Type *types[] = { Int8PtrTy, SizeTy };
llvm::FunctionType *fnType =
llvm::FunctionType::get(VoidTy, types, false);
SlowRawDeallocFn = createRuntimeFunction(*this, "swift_slowRawDealloc", fnType);
return SlowRawDeallocFn;
}
llvm::Constant *IRGenModule::getRetainNoResultFn() {
if (RetainNoResultFn) return RetainNoResultFn;
// void swift_retainNoResult(void *ptr);
auto fnType = llvm::FunctionType::get(VoidTy, RefCountedPtrTy, false);
RetainNoResultFn = createRuntimeFunction(*this, "swift_retain_noresult", fnType);
if (auto fn = dyn_cast<llvm::Function>(RetainNoResultFn))
fn->setDoesNotCapture(1);
return RetainNoResultFn;
}
llvm::Constant *IRGenModule::getReleaseFn() {
if (ReleaseFn) return ReleaseFn;
// void swift_release(void *ptr);
auto fnType = llvm::FunctionType::get(VoidTy, RefCountedPtrTy, false);
ReleaseFn = createRuntimeFunction(*this, "swift_release", fnType);
if (auto fn = dyn_cast<llvm::Function>(ReleaseFn))
fn->setDoesNotCapture(1);
return ReleaseFn;
}
llvm::Constant *IRGenModule::getDeallocObjectFn() {
if (DeallocObjectFn) return DeallocObjectFn;
// void swift_deallocObject(void *ptr, size_t size);
llvm::Type *argTypes[] = { RefCountedPtrTy, SizeTy };
llvm::FunctionType *fnType =
llvm::FunctionType::get(VoidTy, argTypes, false);
DeallocObjectFn = createRuntimeFunction(*this, "swift_deallocObject", fnType);
return DeallocObjectFn;
}
llvm::Constant *IRGenModule::getGetGenericMetadataFn() {
if (GetGenericMetadataFn) return GetGenericMetadataFn;
// heap_metadata_t *swift_getGenericMetadata(heap_metadata_t *pattern,
// const void *arguments);
llvm::Type *argTypes[] = { HeapMetadataPtrTy, Int8PtrTy };
llvm::FunctionType *fnType =
llvm::FunctionType::get(HeapMetadataPtrTy, argTypes, false);
GetGenericMetadataFn =
createRuntimeFunction(*this, "swift_getGenericMetadata", fnType);
return GetGenericMetadataFn;
}
void IRGenModule::unimplemented(SourceLoc loc, StringRef message) {
Context.Diags.diagnose(loc, diag::irgen_unimplemented, message);
}
void IRGenModule::error(SourceLoc loc, const Twine &message) {
SmallVector<char, 128> buffer;
Context.Diags.diagnose(loc, diag::irgen_failure,
message.toStringRef(buffer));
}