1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#include "vc/GenXOpts/GenXOpts.h"
#include "vc/Support/BackendConfig.h"
#include "vc/Utils/GenX/KernelInfo.h"
#include "Probe/Assertion.h"
#include <llvm/GenXIntrinsics/GenXIntrinsics.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/Pass.h>
#include <llvm/Support/Debug.h>
#define DEBUG_TYPE "vc-linkage-corruptor"
using namespace llvm;
namespace {
struct GenXLinkageCorruptor final : public ModulePass {
static char ID;
GenXLinkageCorruptor() : ModulePass(ID) {}
StringRef getPassName() const override { return "GenX linkage corruptor"; }
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnModule(Module &M) override;
};
} // namespace
char GenXLinkageCorruptor::ID = 0;
INITIALIZE_PASS_BEGIN(GenXLinkageCorruptor, "GenXLinkageCorruptor",
"GenXLinkageCorruptor", false, false)
INITIALIZE_PASS_DEPENDENCY(GenXBackendConfig)
INITIALIZE_PASS_END(GenXLinkageCorruptor, "GenXLinkageCorruptor",
"GenXLinkageCorruptor", false, false)
ModulePass *llvm::createGenXLinkageCorruptorPass() {
initializeGenXLinkageCorruptorPass(*PassRegistry::getPassRegistry());
return new GenXLinkageCorruptor;
}
void GenXLinkageCorruptor::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<GenXBackendConfig>();
}
bool GenXLinkageCorruptor::runOnModule(Module &M) {
auto &&BCfg = getAnalysis<GenXBackendConfig>();
FunctionControl FCtrl = BCfg.getFCtrl();
bool SaveStackCallLinkage = BCfg.saveStackCallLinkage();
bool Changed = false;
for (auto &F : M.getFunctionList()) {
if (F.isDeclaration() || F.hasDLLExportStorageClass())
continue;
if (GenXIntrinsic::getAnyIntrinsicID(&F) !=
GenXIntrinsic::not_any_intrinsic)
continue;
// __cm_intrinsic_impl_* could be used for emulation mul/div etc
if (F.getName().contains("__cm_intrinsic_impl_"))
continue;
// Indirect functions are always stack calls.
if (F.hasAddressTaken()) {
F.addFnAttr(genx::FunctionMD::CMStackCall);
Changed = true;
IGC_ASSERT(vc::isIndirect(F));
}
// Convert non-kernel to stack call if applicable
if (FCtrl == FunctionControl::StackCall && !vc::requiresStackCall(&F)) {
LLVM_DEBUG(dbgs() << "Adding stack call to: " << F.getName() << "\n");
F.addFnAttr(genx::FunctionMD::CMStackCall);
Changed = true;
}
// Do not change stack calls linkage as we may have both types of stack
// calls.
if (vc::requiresStackCall(&F) && SaveStackCallLinkage)
continue;
F.setLinkage(GlobalValue::InternalLinkage);
Changed = true;
}
return Changed;
}
|