Skip to content

[ESIMD] Fix compilation from static libraries. #5826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 18, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions llvm/tools/sycl-post-link/sycl-post-link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/GlobalStatus.h"

#include <algorithm>
#include <map>
Expand Down Expand Up @@ -833,6 +834,40 @@ class ModuleSplitter {
size_t totalSplits() { return GMap.size(); }
};

// Removes the global variable "llvm.used" and returns true on success.
// "llvm.used" is a global constant array containing references to kernels
// available in the module and callable from host code. The elements of
// the array are ConstantExpr bitcast to i8*.
// The variable must be removed as it is a) has done the job to the moment
// of this function call and b) the references to the kernels callable from
// host must not have users.
static bool removeSYCLKernelsConstRefArray(GlobalVariable *GV) {
assert(GV->getGlobalIdentifier() == "llvm.used" &&
"Unexpected global value is passed for removal, should be llvm.used");
assert(GV->user_empty() && "Unexpected llvm.used users");
Constant *Initializer = GV->getInitializer();
GV->setInitializer(nullptr);
GV->eraseFromParent();

// Destroy the initializer and all operands of it.
SmallVector<Constant *, 8> IOperands;
for (auto It = Initializer->op_begin(); It != Initializer->op_end(); It++)
IOperands.push_back(cast<Constant>(*It));
assert(llvm::isSafeToDestroyConstant(Initializer) &&
"Cannot remove initializer of llvm.used global");
Initializer->destroyConstant();
for (auto It = IOperands.begin(); It != IOperands.end(); It++) {
assert(llvm::isSafeToDestroyConstant(*It) &&
"Cannot remove an element of initializer of llvm.used global");
auto F = cast<Function>((*It)->getOperand(0));
(*It)->destroyConstant();
// Remove unused kernel declarations to avoid LLVM IR check fails.
if (F->isDeclaration())
F->eraseFromParent();
}
return true;
}

using TableFiles = std::map<StringRef, string_vector>;

TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
Expand All @@ -849,11 +884,8 @@ TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
// issue remove "llvm.used" from the input module before performing any other
// actions.
bool IsLLVMUsedRemoved = false;
if (GlobalVariable *GV = M->getGlobalVariable("llvm.used")) {
assert(GV->user_empty() && "unexpected llvm.used users");
GV->eraseFromParent();
IsLLVMUsedRemoved = true;
}
if (GlobalVariable *GV = M->getGlobalVariable("llvm.used"))
IsLLVMUsedRemoved = removeSYCLKernelsConstRefArray(GV);

if (IsEsimd && LowerEsimd)
lowerEsimdConstructs(*M);
Expand Down