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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2022 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#pragma once
#include "common/LLVMWarningsPush.hpp"
#include <llvm/Pass.h>
#include <llvm/IR/InstVisitor.h>
#include <llvm/Analysis/CallGraph.h>
#include "common/LLVMWarningsPop.hpp"
#include "Compiler/CodeGenContextWrapper.hpp"
#include <utility>
namespace IGC
{
enum {
HasPrivateToGenericCast = 1 << 0,
HasLocalToGenericCast = 1 << 1,
};
class GASInfo {
public:
bool canGenericPointToPrivate(llvm::Function& F) const {
auto E = FunctionMap.find(&F);
if (E == FunctionMap.end())
return true;
return E->second & HasPrivateToGenericCast;
}
bool isPrivateAllocatedInGlobalMemory() const {
return allocatePrivateAsGlobalBuffer;
}
bool canGenericPointToLocal(llvm::Function& F) const {
auto E = FunctionMap.find(&F);
if (E == FunctionMap.end())
return true;
return E->second & HasLocalToGenericCast;
}
bool isNoLocalToGenericOptionEnabled() const {
return noLocalToGenericOptionEnabled;
}
private:
using FunctionMapTy = llvm::DenseMap<const llvm::Function*, unsigned>;
FunctionMapTy FunctionMap;
// True when -cl-intel-no-local-to-generic is enabled
bool noLocalToGenericOptionEnabled = false;
bool allocatePrivateAsGlobalBuffer = false;
friend class CastToGASAnalysis;
};
class CastToGASAnalysis : public llvm::ModulePass {
public:
static char ID;
CastToGASAnalysis() : llvm::ModulePass(ID) {}
~CastToGASAnalysis() = default;
virtual llvm::StringRef getPassName() const override
{
return "Cast To GAS Analysis";
}
bool runOnModule(llvm::Module & M) override;
void getAnalysisUsage(llvm::AnalysisUsage & AU) const override {
AU.setPreservesAll();
AU.addRequired<llvm::CallGraphWrapperPass>();
AU.addRequired<CodeGenContextWrapper>();
}
GASInfo& getGASInfo() { return GI; }
private:
CodeGenContext* m_ctx = nullptr;
GASInfo GI;
llvm::DenseMap<const llvm::Function*, unsigned> castInfoCache;
void setInfoForGroup(
llvm::SmallPtrSetImpl<const llvm::Function*>& functionsGroup,
unsigned castInfo);
unsigned hasCastsToGeneric(const llvm::Function* F);
void getAllFuncsAccessibleFromKernel(
const llvm::Function* F,
llvm::CallGraph& CG,
llvm::SmallPtrSetImpl<const llvm::Function*>& funcs,
bool& disruptAnalysis) const;
};
// EmitPass's analysis passes are either function passes or immutable
// passes for performance reason. To pass the CastToGASAnalysis's
// info to EmitPass, the following immutable pass is used for holding
// info and CastToGASInfoWrapper is used to create this immutable pass.
// Note that no more CastToGASAnalysis after CastToGASInfoWrapper, as
// CastToGASInfoWrapper invalides CastToGASAnalysis by taking its 'GI'.
// Any pass after CastToGASInfoWrapper should use CastToGASInfo immutable
// pass to access the info.
class CastToGASInfo : public llvm::ImmutablePass {
public:
static char ID;
GASInfo GI;
public:
CastToGASInfo();
virtual llvm::StringRef getPassName() const override
{
return "Cast To GAS info for EmitPass";
}
const GASInfo& getGASInfo() const { return GI; }
void setGASInfo(GASInfo& aGI) {
GI.~GASInfo();
GI = std::move(aGI);
}
};
class CastToGASInfoWrapper : public llvm::ModulePass {
public:
static char ID;
CastToGASInfoWrapper();
bool runOnModule(llvm::Module& M) override;
virtual llvm::StringRef getPassName() const override
{
return "Cast To GAS Info Generation for EmitPass";
}
void getAnalysisUsage(llvm::AnalysisUsage& AU) const override {
AU.setPreservesAll();
AU.addRequired<CastToGASAnalysis>();
AU.addRequired<CastToGASInfo>();
}
};
}
|