Move everything under kotlin-native folder
I was forced to manually do update the following files, because otherwise they would be ignored according .gitignore settings. Probably they should be deleted from repo. Interop/.idea/compiler.xml Interop/.idea/gradle.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_3.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_3.xml Interop/.idea/modules.xml Interop/.idea/modules/Indexer/Indexer.iml Interop/.idea/modules/Runtime/Runtime.iml Interop/.idea/modules/StubGenerator/StubGenerator.iml backend.native/backend.native.iml backend.native/bc.frontend/bc.frontend.iml backend.native/cli.bc/cli.bc.iml backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt backend.native/tests/link/lib/foo.kt backend.native/tests/link/lib/foo2.kt backend.native/tests/teamcity-test.property
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "CoverageMappingC.h"
|
||||
|
||||
#include <llvm/ProfileData/Coverage/CoverageMapping.h>
|
||||
#include <llvm/ProfileData/Coverage/CoverageMappingWriter.h>
|
||||
#include <llvm/IR/GlobalVariable.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
#include <llvm/ADT/Triple.h>
|
||||
#include <llvm/IR/LLVMContext.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/IR/Type.h>
|
||||
#include <llvm/IR/DerivedTypes.h>
|
||||
#include <llvm/IR/Constants.h>
|
||||
#include <llvm/IR/Intrinsics.h>
|
||||
#include <llvm/IR/LegacyPassManager.h>
|
||||
#include <llvm/Analysis/TargetLibraryInfo.h>
|
||||
#include <llvm/Transforms/Instrumentation.h>
|
||||
#include <llvm/Support/FileSystem.h>
|
||||
#include <llvm/Support/Path.h>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::coverage;
|
||||
|
||||
namespace llvm {
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetLibraryInfoImpl, LLVMTargetLibraryInfoRef)
|
||||
}
|
||||
|
||||
struct LLVMFunctionCoverage {
|
||||
explicit LLVMFunctionCoverage(std::string coverageData) : coverageData(std::move(coverageData)) {}
|
||||
|
||||
std::string coverageData;
|
||||
};
|
||||
|
||||
static coverage::CounterMappingRegion::RegionKind determineRegionKind(const struct LLVMCoverageRegion& region) {
|
||||
switch (region.kind) {
|
||||
case LLVMCoverageRegionKind::CODE:
|
||||
return coverage::CounterMappingRegion::RegionKind::CodeRegion;
|
||||
case LLVMCoverageRegionKind::GAP:
|
||||
return coverage::CounterMappingRegion::RegionKind::GapRegion;
|
||||
case LLVMCoverageRegionKind::EXPANSION:
|
||||
return coverage::CounterMappingRegion::RegionKind::ExpansionRegion;
|
||||
}
|
||||
}
|
||||
|
||||
static coverage::CounterMappingRegion createCounterMappingRegion(struct LLVMCoverageRegion& region) {
|
||||
auto regionKind = determineRegionKind(region);
|
||||
int expandedFileId = 0;
|
||||
if (regionKind == coverage::CounterMappingRegion::RegionKind::ExpansionRegion) {
|
||||
expandedFileId = region.expandedFileId;
|
||||
}
|
||||
const Counter &counter = coverage::Counter::getCounter(region.counterId);
|
||||
return coverage::CounterMappingRegion(counter, region.fileId, expandedFileId, region.lineStart,
|
||||
region.columnStart, region.lineEnd, region.columnEnd, regionKind);
|
||||
}
|
||||
|
||||
LLVMFunctionCoverage* LLVMWriteCoverageRegionMapping(unsigned int *fileIdMapping, size_t fileIdMappingSize,
|
||||
struct LLVMCoverageRegion **mappingRegions, size_t mappingRegionsSize) {
|
||||
std::vector<coverage::CounterMappingRegion> counterMappingRegions;
|
||||
for (size_t i = 0; i < mappingRegionsSize; ++i) {
|
||||
struct LLVMCoverageRegion region = *mappingRegions[i];
|
||||
counterMappingRegions.emplace_back(createCounterMappingRegion(region));
|
||||
}
|
||||
CoverageMappingWriter writer(ArrayRef<unsigned int>(fileIdMapping, fileIdMappingSize), None, counterMappingRegions);
|
||||
std::string CoverageMapping;
|
||||
raw_string_ostream OS(CoverageMapping);
|
||||
writer.write(OS);
|
||||
OS.flush();
|
||||
// Should be disposed with `LLVMFunctionCoverageDispose`.
|
||||
return new LLVMFunctionCoverage(CoverageMapping);
|
||||
}
|
||||
|
||||
void LLVMFunctionCoverageDispose(struct LLVMFunctionCoverage* functionCoverage) {
|
||||
delete functionCoverage;
|
||||
}
|
||||
|
||||
static StructType *getFunctionRecordTy(LLVMContext &Ctx) {
|
||||
#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
|
||||
Type *FunctionRecordTypes[] = {
|
||||
#include "llvm/ProfileData/InstrProfData.inc"
|
||||
};
|
||||
StructType *FunctionRecordTy = StructType::get(Ctx, makeArrayRef(FunctionRecordTypes), true);
|
||||
return FunctionRecordTy;
|
||||
}
|
||||
|
||||
static llvm::Constant *addFunctionMappingRecord(llvm::LLVMContext &Ctx, StringRef NameValue, uint64_t FuncHash,
|
||||
const std::string &CoverageMapping) {
|
||||
llvm::StructType *FunctionRecordTy = getFunctionRecordTy(Ctx);
|
||||
|
||||
#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
|
||||
llvm::Constant *FunctionRecordVals[] = {
|
||||
#include "llvm/ProfileData/InstrProfData.inc"
|
||||
};
|
||||
return llvm::ConstantStruct::get(FunctionRecordTy, makeArrayRef(FunctionRecordVals));
|
||||
}
|
||||
|
||||
// See https://github.com/llvm/llvm-project/blob/fa8fa044ec46b94e64971efa8852df0d58114062/clang/lib/CodeGen/CoverageMappingGen.cpp#L1284.
|
||||
LLVMValueRef LLVMAddFunctionMappingRecord(LLVMContextRef context, const char *name, uint64_t hash,
|
||||
struct LLVMFunctionCoverage *coverageMapping) {
|
||||
return llvm::wrap(addFunctionMappingRecord(*llvm::unwrap(context), name, hash, coverageMapping->coverageData));
|
||||
}
|
||||
|
||||
// See https://github.com/llvm/llvm-project/blob/fa8fa044ec46b94e64971efa8852df0d58114062/clang/lib/CodeGen/CoverageMappingGen.cpp#L1335.
|
||||
// Please note that llvm/ProfileData/InstrProfData.inc refers to variable names of the function that includes it. So be careful with renaming.
|
||||
static llvm::GlobalVariable* emitCoverageGlobal(
|
||||
llvm::LLVMContext &Ctx,
|
||||
llvm::Module &module,
|
||||
std::vector<llvm::Constant *> &FunctionRecords,
|
||||
const llvm::SmallVector<StringRef, 16> &FilenameRefs,
|
||||
const std::string &RawCoverageMappings) {
|
||||
|
||||
auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
|
||||
|
||||
std::string FilenamesAndCoverageMappings;
|
||||
llvm::raw_string_ostream outputStream(FilenamesAndCoverageMappings);
|
||||
CoverageFilenamesSectionWriter(FilenameRefs).write(outputStream);
|
||||
outputStream << RawCoverageMappings;
|
||||
size_t CoverageMappingSize = RawCoverageMappings.size();
|
||||
size_t FilenamesSize = outputStream.str().size() - CoverageMappingSize;
|
||||
|
||||
// See https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation
|
||||
//
|
||||
// > Coverage mapping data which is an array of bytes. Zero paddings are added at the end to force 8 byte alignment.
|
||||
//
|
||||
if (size_t rem = outputStream.str().size() % 8) {
|
||||
CoverageMappingSize += 8 - rem;
|
||||
for (size_t i = 0; i < 8 - rem; ++i) {
|
||||
outputStream << '\0';
|
||||
}
|
||||
}
|
||||
|
||||
StructType *functionRecordTy = getFunctionRecordTy(Ctx);
|
||||
// Create the deferred function records array
|
||||
auto functionRecordsTy = llvm::ArrayType::get(functionRecordTy, FunctionRecords.size());
|
||||
auto functionRecordsVal = llvm::ConstantArray::get(functionRecordsTy, FunctionRecords);
|
||||
|
||||
llvm::Type *CovDataHeaderTypes[] = {
|
||||
#define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
|
||||
|
||||
#include "llvm/ProfileData/InstrProfData.inc"
|
||||
};
|
||||
auto CovDataHeaderTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataHeaderTypes));
|
||||
llvm::Constant *CovDataHeaderVals[] = {
|
||||
#define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
|
||||
|
||||
#include "llvm/ProfileData/InstrProfData.inc"
|
||||
};
|
||||
auto covDataHeaderVal = llvm::ConstantStruct::get(CovDataHeaderTy, makeArrayRef(CovDataHeaderVals));
|
||||
|
||||
auto *filenamesAndMappingsVal = llvm::ConstantDataArray::getString(Ctx, outputStream.str(), false);
|
||||
// Create the coverage data record
|
||||
llvm::Type *covDataTypes[] = {CovDataHeaderTy, functionRecordsTy, filenamesAndMappingsVal->getType()};
|
||||
auto covDataTy = llvm::StructType::get(Ctx, makeArrayRef(covDataTypes));
|
||||
|
||||
llvm::Constant *TUDataVals[] = {covDataHeaderVal, functionRecordsVal, filenamesAndMappingsVal};
|
||||
auto covDataVal = llvm::ConstantStruct::get(covDataTy, makeArrayRef(TUDataVals));
|
||||
// Will be deleted when module is disposed.
|
||||
return new llvm::GlobalVariable(module, covDataTy, true, llvm::GlobalValue::InternalLinkage,
|
||||
covDataVal, llvm::getCoverageMappingVarName());
|
||||
}
|
||||
|
||||
static std::string createRawCoverageMapping(struct LLVMFunctionCoverage **functionCoverages, size_t functionCoveragesSize) {
|
||||
std::vector<std::string> coverageMappings;
|
||||
for (size_t i = 0; i < functionCoveragesSize; ++i) {
|
||||
coverageMappings.emplace_back(functionCoverages[i]->coverageData);
|
||||
}
|
||||
return llvm::join(coverageMappings.begin(), coverageMappings.end(), "");
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMCoverageEmit(LLVMModuleRef moduleRef,
|
||||
LLVMValueRef *records, size_t recordsSize,
|
||||
const char **filenames, int *filenamesIndices, size_t filenamesSize,
|
||||
struct LLVMFunctionCoverage **functionCoverages, size_t functionCoveragesSize) {
|
||||
LLVMContext &ctx = *unwrap(LLVMGetModuleContext(moduleRef));
|
||||
Module &module = *unwrap(moduleRef);
|
||||
|
||||
std::vector<Constant *> functionRecords;
|
||||
for (size_t i = 0; i < recordsSize; ++i) {
|
||||
functionRecords.push_back(dyn_cast<Constant>(unwrap(records[i])));
|
||||
}
|
||||
llvm::SmallVector<StringRef, 16> filenameRefs;
|
||||
filenameRefs.resize(filenamesSize);
|
||||
for (size_t i = 0; i < filenamesSize; ++i) {
|
||||
if (sys::path::is_absolute(filenames[i])) {
|
||||
filenameRefs[filenamesIndices[i]] = filenames[i];
|
||||
} else {
|
||||
SmallString<256> path(filenames[i]);
|
||||
sys::fs::make_absolute(path);
|
||||
sys::path::remove_dots(path, true);
|
||||
filenameRefs[filenamesIndices[i]] = path;
|
||||
}
|
||||
}
|
||||
const std::string &rawCoverageMappings = createRawCoverageMapping(functionCoverages, functionCoveragesSize);
|
||||
GlobalVariable *coverageGlobal = emitCoverageGlobal(ctx, module, functionRecords, filenameRefs, rawCoverageMappings);
|
||||
|
||||
const std::string §ion = getInstrProfSectionName(IPSK_covmap, Triple(module.getTargetTriple()).getObjectFormat());
|
||||
coverageGlobal->setSection(section);
|
||||
coverageGlobal->setAlignment(8);
|
||||
return wrap(coverageGlobal);
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMInstrProfIncrement(LLVMModuleRef moduleRef) {
|
||||
Module &module = *unwrap(moduleRef);
|
||||
return wrap(Intrinsic::getDeclaration(&module, Intrinsic::instrprof_increment, None));
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMCreatePGOFunctionNameVar(LLVMValueRef llvmFunction, const char *pgoFunctionName) {
|
||||
auto *fnPtr = cast<llvm::Function>(unwrap(llvmFunction));
|
||||
return wrap(createPGOFuncNameVar(*fnPtr, pgoFunctionName));
|
||||
}
|
||||
|
||||
void LLVMAddInstrProfPass(LLVMPassManagerRef passManagerRef, const char* outputFileName) {
|
||||
legacy::PassManagerBase *passManager = unwrap(passManagerRef);
|
||||
InstrProfOptions options;
|
||||
options.InstrProfileOutput = outputFileName;
|
||||
passManager->add(createInstrProfilingLegacyPass(options));
|
||||
}
|
||||
|
||||
void LLVMKotlinAddTargetLibraryInfoWrapperPass(LLVMPassManagerRef passManagerRef, const char* targetTriple) {
|
||||
legacy::PassManagerBase *passManager = unwrap(passManagerRef);
|
||||
passManager->add(new TargetLibraryInfoWrapperPass(Triple(targetTriple)));
|
||||
}
|
||||
|
||||
void LLVMKotlinInitializeTargets() {
|
||||
#define INIT_LLVM_TARGET(TargetName) \
|
||||
LLVMInitialize##TargetName##TargetInfo();\
|
||||
LLVMInitialize##TargetName##Target();\
|
||||
LLVMInitialize##TargetName##TargetMC();
|
||||
#if KONAN_MACOS
|
||||
INIT_LLVM_TARGET(AArch64)
|
||||
INIT_LLVM_TARGET(ARM)
|
||||
INIT_LLVM_TARGET(Mips)
|
||||
INIT_LLVM_TARGET(X86)
|
||||
INIT_LLVM_TARGET(WebAssembly)
|
||||
#elif KONAN_LINUX
|
||||
INIT_LLVM_TARGET(AArch64)
|
||||
INIT_LLVM_TARGET(ARM)
|
||||
INIT_LLVM_TARGET(Mips)
|
||||
INIT_LLVM_TARGET(X86)
|
||||
INIT_LLVM_TARGET(WebAssembly)
|
||||
#elif KONAN_WINDOWS
|
||||
INIT_LLVM_TARGET(AArch64)
|
||||
INIT_LLVM_TARGET(ARM)
|
||||
INIT_LLVM_TARGET(X86)
|
||||
INIT_LLVM_TARGET(WebAssembly)
|
||||
#endif
|
||||
|
||||
#undef INIT_LLVM_TARGET
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef __COVERAGE_MAPPING_C_H__
|
||||
# define __COVERAGE_MAPPING_C_H__
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Target.h>
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
/**
|
||||
* See org.jetbrains.kotlin.backend.konan.llvm.coverage.RegionKind.
|
||||
*/
|
||||
enum LLVMCoverageRegionKind {
|
||||
CODE,
|
||||
GAP,
|
||||
EXPANSION
|
||||
};
|
||||
|
||||
/**
|
||||
* See org.jetbrains.kotlin.backend.konan.llvm.coverage.Region.
|
||||
*/
|
||||
struct LLVMCoverageRegion {
|
||||
int fileId;
|
||||
int lineStart;
|
||||
int columnStart;
|
||||
int lineEnd;
|
||||
int columnEnd;
|
||||
int counterId;
|
||||
int expandedFileId;
|
||||
enum LLVMCoverageRegionKind kind;
|
||||
};
|
||||
|
||||
struct LLVMFunctionCoverage;
|
||||
|
||||
/**
|
||||
* Add record in the following format: https://llvm.org/docs/CoverageMappingFormat.html#function-record.
|
||||
*/
|
||||
LLVMValueRef
|
||||
LLVMAddFunctionMappingRecord(LLVMContextRef context, const char *name, uint64_t hash, struct LLVMFunctionCoverage* coverageMapping);
|
||||
|
||||
/**
|
||||
* Wraps creation of coverage::CoverageMappingWriter and call to coverage::CoverageMappingWriter::write.
|
||||
*/
|
||||
struct LLVMFunctionCoverage* LLVMWriteCoverageRegionMapping(unsigned int *fileIdMapping, size_t fileIdMappingSize,
|
||||
struct LLVMCoverageRegion **mappingRegions, size_t mappingRegionsSize);
|
||||
|
||||
void LLVMFunctionCoverageDispose(struct LLVMFunctionCoverage* functionCoverage);
|
||||
|
||||
/**
|
||||
* Create __llvm_coverage_mapping global.
|
||||
*/
|
||||
LLVMValueRef LLVMCoverageEmit(LLVMModuleRef moduleRef, LLVMValueRef *records, size_t recordsSize,
|
||||
const char **filenames, int *filenamesIndices, size_t filenamesSize,
|
||||
struct LLVMFunctionCoverage** functionCoverages, size_t functionCoveragesSize);
|
||||
|
||||
/**
|
||||
* Wrapper for `llvm.instrprof.increment` declaration.
|
||||
*/
|
||||
LLVMValueRef LLVMInstrProfIncrement(LLVMModuleRef moduleRef);
|
||||
|
||||
/**
|
||||
* Wrapper for llvm::createPGOFuncNameVar.
|
||||
*/
|
||||
LLVMValueRef LLVMCreatePGOFunctionNameVar(LLVMValueRef llvmFunction, const char *pgoFunctionName);
|
||||
|
||||
void LLVMAddInstrProfPass(LLVMPassManagerRef passManagerRef, const char* outputFileName);
|
||||
|
||||
void LLVMKotlinAddTargetLibraryInfoWrapperPass(LLVMPassManagerRef passManagerRef, const char* targetTriple);
|
||||
|
||||
void LLVMKotlinInitializeTargets();
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user