Skip to content

Commit adece8c

Browse files
author
Viktor Yastrebov
committed
reimplement external intrinsic idea to make it embeded into final transpiled source code
1 parent 96b0912 commit adece8c

File tree

20 files changed

+103
-207
lines changed

20 files changed

+103
-207
lines changed

lib/core/intrinsics/external_intrinsics.cpp

Lines changed: 34 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <clang/Frontend/CompilerInstance.h>
44
#include "core/transpiler_session/session_stage.h"
55
#include "core/transpiler_session/transpiler_session.h"
6+
#include "oklt/util/io_helper.h"
67
#include "util/string_utils.hpp"
78

89
#include <algorithm>
@@ -73,10 +74,9 @@ std::optional<fs::path> getExternalInstrincisInclude(TranspilerSession& session,
7374
return std::nullopt;
7475
}
7576

76-
tl::expected<std::unique_ptr<llvm::MemoryBuffer>, std::string> getExternalIntrinsicSource(
77-
TargetBackend backend,
78-
const fs::path& intrinsicPath,
79-
clang::SourceManager& sm) {
77+
tl::expected<std::string, std::string> getExternalIntrinsicSource(TargetBackend backend,
78+
const fs::path& intrinsicPath,
79+
clang::SourceManager& sm) {
8080
auto implPathResult = getIntrincisImplSourcePath(backend, intrinsicPath);
8181
if (!implPathResult) {
8282
return tl::make_unexpected(implPathResult.error());
@@ -93,119 +93,85 @@ tl::expected<std::unique_ptr<llvm::MemoryBuffer>, std::string> getExternalIntrin
9393
}
9494

9595
auto it = std::find_if(files.cbegin(), files.cend(), [](const fs::path& p) -> bool {
96-
return p.extension().string() == std::string(".h");
96+
return p.extension().string() == std::string(".cpp");
9797
});
9898

9999
if (it == files.cend()) {
100100
std::string error = "Can't' find implementation file with path: " + sourceFolder.string();
101101
return tl::make_unexpected(error);
102102
}
103103

104-
auto& fm = sm.getFileManager();
105-
auto backendFilePath = it->string();
106-
auto maybeReplacedFile = fm.getFile(backendFilePath);
107-
if (!maybeReplacedFile) {
108-
std::string error = "Can't open file: " + backendFilePath;
104+
auto contentResult = util::readFileAsStr(*it);
105+
if (!contentResult) {
106+
std::string error = "Can't get memory buffer for: " + it->string();
109107
return tl::make_unexpected(error);
110108
}
111-
auto maybeBuffer = fm.getBufferForFile(maybeReplacedFile.get());
112-
if (!maybeBuffer) {
113-
std::string error = "Can't get memory buffer for: " + backendFilePath;
114-
return tl::make_unexpected(error);
115-
}
116-
return std::move(maybeBuffer.get());
109+
return contentResult.value();
117110
}
118111

119-
bool overrideExternalIntrinsic(TranspilerSession& session,
112+
bool overrideExternalIntrinsic(SessionStage& stage,
113+
HeaderDepsInfo& deps,
120114
const std::string& includedFileName,
121-
clang::OptionalFileEntryRef includedFile,
122-
clang::SourceManager& sourceManager) {
115+
clang::OptionalFileEntryRef includedFile) {
116+
auto& session = stage.getSession();
117+
auto& sourceManager = stage.getCompiler().getSourceManager();
123118
const auto& userIntrinsics = session.getInput().userIntrinsics;
124119
if (!userIntrinsics.empty()) {
125120
auto maybeIntrinsicPath = getExternalInstrincisInclude(session, includedFileName);
126121
if (!maybeIntrinsicPath) {
127122
return false;
128123
}
129124
auto intrinsicPath = maybeIntrinsicPath.value();
130-
auto infoResult =
131-
getExternalIntrinsicSource(session.getInput().backend, intrinsicPath, sourceManager);
132-
if (!infoResult) {
133-
session.pushError(std::error_code(), infoResult.error());
125+
auto intrinsicResult =
126+
getExternalIntrinsicSource(stage.getBackend(), intrinsicPath, sourceManager);
127+
if (!intrinsicResult) {
128+
session.pushError(std::error_code(), intrinsicResult.error());
134129
return false;
135130
}
136-
auto buffer = std::move(infoResult.value());
137-
auto& fm = sourceManager.getFileManager();
131+
deps.externalIntrinsicsSources[includedFileName] = std::move(intrinsicResult.value());
132+
133+
auto emptyExternalIntrinsic = MemoryBuffer::getMemBuffer("");
138134
if (includedFile) {
139135
auto fileRef = includedFile;
140136
const auto& fileEntry = fileRef->getFileEntry();
141-
sourceManager.overrideFileContents(&fileEntry, std::move(buffer));
137+
sourceManager.overrideFileContents(&fileEntry, std::move(emptyExternalIntrinsic));
142138
} else {
143139
// INFO: case when the file can be found by relative path
144140
// it happens when the include path is relative to WORKING DIR path
141+
auto& fm = sourceManager.getFileManager();
145142
auto maybeFileRef = fm.getFileRef(includedFileName);
146143
if (maybeFileRef) {
147144
auto foundFileRef = maybeFileRef.get();
148-
sourceManager.overrideFileContents(foundFileRef, std::move(buffer));
145+
sourceManager.overrideFileContents(foundFileRef, std::move(emptyExternalIntrinsic));
149146
}
150147
}
151148
return true;
152149
}
153150
return false;
154151
}
155152

156-
void nullyLauncherExternalIntrinsics(TransformedFiles& inputs, SessionStage& stage) {
157-
if (stage.getBackend() != TargetBackend::_LAUNCHER) {
158-
return;
159-
}
160-
161-
auto& session = stage.getSession();
162-
const auto& intrinsics = session.getInput().userIntrinsics;
163-
if (intrinsics.empty()) {
153+
void updateExternalIntrinsicMap(SessionStage& stage, HeaderDepsInfo& deps) {
154+
if (deps.externalIntrinsicsSources.empty()) {
164155
return;
165156
}
166157

167-
for (auto& mappedFile : inputs.fileMap) {
168-
auto fileName = normalizedFileName(mappedFile.first);
169-
for (const auto& includePath : intrinsics) {
170-
auto folderPrefix = includePath.filename().string();
171-
if (util::startsWith(fileName, folderPrefix)) {
172-
mappedFile.second.clear();
173-
}
174-
}
175-
}
176-
}
177-
178-
void embedLauncherExternalIntrinsics(std::string& input,
179-
const HeaderDepsInfo& info,
180-
SessionStage& stage) {
181158
auto backend = stage.getBackend();
182-
if (backend != TargetBackend::_LAUNCHER) {
183-
return;
184-
}
185-
186-
const auto& usedIntrinsics = info.externalIntrinsics;
187-
if (usedIntrinsics.empty()) {
188-
return;
189-
}
190-
191-
auto session = stage.getSession();
159+
auto& session = stage.getSession();
192160
auto& sm = stage.getCompiler().getSourceManager();
193-
for (const auto& includeIntrinsic : usedIntrinsics) {
194-
auto maybeIntrinsicPath = getExternalInstrincisInclude(session, includeIntrinsic);
161+
for (auto& mappedIntrinsic : deps.externalIntrinsicsSources) {
162+
auto maybeIntrinsicPath = getExternalInstrincisInclude(session, mappedIntrinsic.first);
195163
if (!maybeIntrinsicPath) {
196-
std::string error = "Count not find implementation for " + includeIntrinsic;
164+
std::string error = "Count not find implementation for " + mappedIntrinsic.first;
197165
session.pushError(std::error_code(), error);
198166
return;
199167
}
200168
auto intrinsicPath = maybeIntrinsicPath.value();
201-
auto infoResult = getExternalIntrinsicSource(backend, intrinsicPath, sm);
202-
if (!infoResult) {
203-
session.pushError(std::error_code(), infoResult.error());
169+
auto intrinsicResult = getExternalIntrinsicSource(backend, intrinsicPath, sm);
170+
if (!intrinsicResult) {
171+
session.pushError(std::error_code(), intrinsicResult.error());
204172
return;
205173
}
206-
auto buffer = std::move(infoResult.value());
207-
// INFO: make temporary buffer because pointer could be not null terminated
208-
input.insert(0, buffer->getBuffer().str());
174+
mappedIntrinsic.second = std::move(intrinsicResult.value());
209175
}
210176
}
211177
} // namespace oklt

lib/core/intrinsics/external_intrinsics.h

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,15 @@
22
#include <clang/Basic/FileEntry.h>
33
#include <string>
44

5-
namespace clang {
6-
class CompilerInstance;
7-
class SourceManager;
8-
} // namespace clang
9-
105
namespace oklt {
116

12-
class TranspilerSession;
13-
class TransformedFiles;
147
class SessionStage;
158
class HeaderDepsInfo;
169

17-
bool overrideExternalIntrinsic(TranspilerSession& session,
10+
bool overrideExternalIntrinsic(SessionStage& stage,
11+
HeaderDepsInfo& deps,
1812
const std::string& includedFileName,
19-
clang::OptionalFileEntryRef includedFile,
20-
clang::SourceManager& sourceManager);
21-
22-
void nullyLauncherExternalIntrinsics(TransformedFiles& inputs, SessionStage& stage);
23-
24-
void embedLauncherExternalIntrinsics(std::string& input,
25-
const HeaderDepsInfo& info,
26-
SessionStage& stage);
13+
clang::OptionalFileEntryRef includedFile);
2714

15+
void updateExternalIntrinsicMap(SessionStage& stage, HeaderDepsInfo& deps);
2816
} // namespace oklt

lib/core/transpiler_session/code_generator.cpp

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
#include "core/transpiler_session/transpiler_session.h"
88

99
#include "core/intrinsics/builtin_intrinsics.h"
10-
#include "core/intrinsics/external_intrinsics.h"
10+
// #include "core/intrinsics/external_intrinsics.h"
1111

1212
#include "core/handler_manager/handler_manager.h"
1313

14-
#include "core/utils/attributes.h"
14+
// #include "core/utils/attributes.h"
1515
#include "core/vfs/overlay_fs.h"
1616

1717
#include <clang/AST/Attr.h>
@@ -86,10 +86,8 @@ void removeSystemHeaders(SessionStage& stage, const HeaderDepsInfo& deps) {
8686
rewriter.RemoveText({dep.hashLoc, dep.filenameRange.getEnd()});
8787
}
8888

89-
for (const auto& intrinsicDep : deps.externalIntrinsicDeps) {
90-
SPDLOG_TRACE(
91-
"remove system include {} {}", intrinsicDep.relativePath, intrinsicDep.fileName);
92-
rewriter.RemoveText({intrinsicDep.hashLoc, intrinsicDep.filenameRange.getEnd()});
89+
for (const auto& intrinsic : deps.externalIntrinsicHeaders) {
90+
rewriter.RemoveText({intrinsic.hashLoc, intrinsic.filenameRange.getEnd()});
9391
}
9492
}
9593

@@ -169,18 +167,14 @@ std::string restoreSystemAndBackendHeaders(SessionStage& stage,
169167
}
170168
}
171169

172-
embedLauncherExternalIntrinsics(input, deps, stage);
170+
for (const auto& externalIntrinsicSource : deps.externalIntrinsicsSources) {
171+
input.insert(0, externalIntrinsicSource.second);
172+
}
173173

174174
for (auto it = deps.backendHeaders.rbegin(); it < deps.backendHeaders.rend(); ++it) {
175175
input.insert(0, *it);
176176
}
177177

178-
if (backend != TargetBackend::_LAUNCHER) {
179-
for (const auto& intrinsicDep : deps.externalIntrinsicDeps) {
180-
input.insert(0, "#include <" + intrinsicDep.fileName + ">\n");
181-
}
182-
}
183-
184178
// restore system headers
185179
for (const auto& dep : deps.topLevelDeps) {
186180
if (!clang::SrcMgr::isSystem(dep.fileType)) {
@@ -197,8 +191,6 @@ tl::expected<std::string, Error> fuseIncludeDeps(SessionStage& stage, const Head
197191

198192
auto inputs = gatherTransformedFiles(stage);
199193

200-
nullyLauncherExternalIntrinsics(inputs, stage);
201-
202194
auto preprocessedResult = preprocesseInputs(stage, inputs);
203195
if (!preprocessedResult) {
204196
return preprocessedResult;
Lines changed: 20 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
#include "core/transpiler_session/header_info.h"
22
#include "core/intrinsics/builtin_intrinsics.h"
33
#include "core/intrinsics/external_intrinsics.h"
4-
#include "core/transpiler_session/transpiler_session.h"
4+
#include "core/transpiler_session/session_stage.h"
55

66
namespace {}
77
namespace oklt {
88

99
using namespace llvm;
1010

11-
InclusionDirectiveCallback::InclusionDirectiveCallback(TranspilerSession& session,
11+
InclusionDirectiveCallback::InclusionDirectiveCallback(SessionStage& stage,
1212
HeaderDepsInfo& deps_,
1313
clang::SourceManager& sm_)
1414
: deps(deps_),
1515
sm(sm_),
16-
_session(session),
17-
_isInExternalIntrinsic(false) {}
16+
_stage(stage) {}
1817

1918
void InclusionDirectiveCallback::InclusionDirective(clang::SourceLocation hashLoc,
2019
const clang::Token& includeTok,
@@ -36,67 +35,25 @@ void InclusionDirectiveCallback::InclusionDirective(clang::SourceLocation hashLo
3635
}
3736

3837
auto fileNameStr = fileName.str();
39-
auto isIntrinsic = overrideExternalIntrinsic(_session, fileNameStr, file, sm);
40-
if (isIntrinsic) {
41-
deps.externalIntrinsics.push_back(fileNameStr);
42-
_extIntrinsicFID = sm.getFileID(hashLoc);
43-
}
38+
bool isIntrinsic = overrideExternalIntrinsic(_stage, deps, fileNameStr, file);
39+
40+
auto dep = HeaderDep{
41+
.hashLoc = hashLoc,
42+
.includeTok = includeTok,
43+
.fileName = fileNameStr,
44+
.isAngled = isAngled,
45+
.filenameRange = filenameRange,
46+
.file = file,
47+
.searchPath = searchPath.str(),
48+
.relativePath = relativePath.str(),
49+
.imported = imported,
50+
.fileType = fileType,
51+
};
4452

45-
// INFO: force instrinsic includes to be system includes
46-
// they will be removed & attached to final transpiled source
47-
if (_isInExternalIntrinsic) {
48-
fileType = clang::SrcMgr::CharacteristicKind::C_System;
49-
deps.externalIntrinsicDeps.push_back(HeaderDep{
50-
.hashLoc = hashLoc,
51-
.includeTok = includeTok,
52-
.fileName = fileNameStr,
53-
.isAngled = isAngled,
54-
.filenameRange = filenameRange,
55-
.file = file,
56-
.searchPath = searchPath.str(),
57-
.relativePath = relativePath.str(),
58-
.imported = imported,
59-
.fileType = fileType,
60-
});
53+
if (isIntrinsic) {
54+
deps.externalIntrinsicHeaders.push_back(std::move(dep));
6155
} else {
62-
deps.topLevelDeps.push_back(HeaderDep{
63-
.hashLoc = hashLoc,
64-
.includeTok = includeTok,
65-
.fileName = fileNameStr,
66-
.isAngled = isAngled,
67-
.filenameRange = filenameRange,
68-
.file = file,
69-
.searchPath = searchPath.str(),
70-
.relativePath = relativePath.str(),
71-
.imported = imported,
72-
.fileType = fileType,
73-
});
56+
deps.topLevelDeps.push_back(std::move(dep));
7457
}
7558
}
76-
77-
void InclusionDirectiveCallback::FileChanged(clang::SourceLocation Loc,
78-
FileChangeReason Reason,
79-
clang::SrcMgr::CharacteristicKind FileType,
80-
clang::FileID PrevFID) {
81-
if (Reason == FileChangeReason::EnterFile) {
82-
if (_extIntrinsicFID.isValid()) {
83-
_isInExternalIntrinsic = PrevFID == _extIntrinsicFID;
84-
return;
85-
}
86-
}
87-
88-
if (Reason == FileChangeReason::ExitFile) {
89-
auto thisFID = sm.getFileID(Loc);
90-
if (_extIntrinsicFID.isValid() && thisFID == _extIntrinsicFID) {
91-
_extIntrinsicFID = clang::FileID();
92-
_isInExternalIntrinsic = false;
93-
return;
94-
}
95-
}
96-
}
97-
98-
bool InclusionDirectiveCallback::FileNotFound(clang::StringRef FileName) {
99-
return _isInExternalIntrinsic;
100-
}
101-
10259
} // namespace oklt

0 commit comments

Comments
 (0)