1/**
2 * Copyright (c) Glow Contributors. See CONTRIBUTORS file.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// This file contains the print functionality the JIT code can use. The backend
18// can call function to emit a global var that points to the host side struct
19// containing fopen/fprintf/fclose pointers, JIT code can call instead of it's
20// own fopen/fprintf/fclose.
21
22#include "glow/LLVMIRCodeGen/JITFilePrinter.h"
23#include "glow/LLVMIRCodeGen/LLVMIRGen.h"
24
25#include "llvm/Support/DynamicLibrary.h"
26
27using namespace glow;
28
29#if defined _MSC_VER
30#define EXTERN __declspec(dllexport)
31#else
32#define EXTERN
33#endif
34
35static JITFileWriter jitfileWriter;
36
37int JITFileWriter::JITfprintf(FILE *f, const char *format, ...) {
38 va_list argptr;
39 va_start(argptr, format);
40 return vfprintf(f, format, argptr);
41}
42
43FILE *JITFileWriter::JITfopen(const char *path, const char *mode) {
44 // File access is locked using per file name lock. This lock is a simple
45 // bool variable with it's access guarded by mutex.
46 std::unique_lock<std::mutex> lck(jitfileWriter.mtx_);
47 jitfileWriter.readyCV.wait(
48 lck, [&path] { return !jitfileWriter.fileLock_[std::string(path)]; });
49 jitfileWriter.fileLock_[std::string(path)] = true;
50 FILE *f = fopen(path, mode);
51 jitfileWriter.fileMap_[f] = std::string(path);
52 return f;
53}
54
55int JITFileWriter::JITfclose(FILE *f) {
56 std::lock_guard<std::mutex> lck(jitfileWriter.mtx_);
57 if (!jitfileWriter.fileMap_.count(f)) {
58 return -1;
59 }
60 std::string &file = jitfileWriter.fileMap_[f];
61 int ret = fclose(f);
62 jitfileWriter.fileMap_.erase(f);
63 jitfileWriter.fileLock_[file] = false;
64 jitfileWriter.readyCV.notify_all();
65 return ret;
66}
67
68/// Expose host side file printer for JIT code to use.
69/// The function simply exposes the writer object as a global symbol
70/// that will be avaiable for JIT to use.
71void LLVMIRGen::generateJITFileWriter() {
72 llvm::sys::DynamicLibrary::AddSymbol("_jitFileWriter", &jitfileWriter);
73}
74