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
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2025 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#pragma once
#include "Compiler/CodeGenContextWrapper.hpp"
#include "Compiler/MetaDataUtilsWrapper.h"
#include <llvm/IR/DataLayout.h>
#include "Compiler/Optimizer/OCLBIUtils.h"
#include "common/LLVMWarningsPush.hpp"
#include <llvm/Pass.h>
#include <llvm/IR/InstVisitor.h>
#include "common/LLVMWarningsPop.hpp"
#include "IGC/common/Types.hpp"
namespace IGC {
/// @brief ManageableBarriersResolution pass used for resolving OpenCL named barriers functions.
class ManageableBarriersResolution : public llvm::ModulePass,
public llvm::InstVisitor<ManageableBarriersResolution, void> {
private:
enum class MBFuncType {
InitProdCons,
InitProd,
Release,
Arrive,
Wait,
ArriveWait,
ArriveDrop,
None
};
enum class MBMode { Mix = 0, DynamicOnly = 1, SimpleOnly = 2 };
enum class MBDynamicStructFields {
BarrierID = 0,
ProducerCount,
ConsumerCount,
ExpectedArrvial,
Max
};
llvm::ArrayType *getMBDynamicStructType();
struct DynamicBarrierStruct {
llvm::Value *ptrID;
llvm::Value *ptrProducerCount;
llvm::Value *ptrConsumerCount;
llvm::Value *ptrExpectedArrival;
};
struct SimpleBarrierStruct {
llvm::Value *ID;
llvm::Value *ProducerCount;
llvm::Value *ConsumerCount;
};
llvm::Module *mModule = nullptr;
MBMode mCurrentMode = {};
llvm::DenseMap<llvm::CallInst *, MBFuncType> mManageBarrierInstructions;
llvm::DenseMap<llvm::CallInst *, MBFuncType> mManageBarrierInstructionsInit;
llvm::DenseMap<llvm::CallInst *, SimpleBarrierStruct> mManageBarrierInstructionsInitSimple;
int mSimpleBarrierIDCount = 0;
llvm::DenseMap<llvm::Function *, llvm::Value *> mGlobalDataPoolPerFunc;
llvm::DenseMap<llvm::Function *, llvm::Value *> mGlobalIDPoolPPerFunc;
MBFuncType getFuncType(llvm::Function *pFunc);
void emit(llvm::CallInst *CI, MBFuncType FuncType);
void emitInit(llvm::CallInst *pInsertPoint);
void emitRelease(llvm::CallInst *pInsertPoint);
void emitArrive(llvm::CallInst *pInsertPoint);
void emitWait(llvm::CallInst *pInsertPoint);
void emitArriveWait(llvm::CallInst *pInsertPoint);
void emitArriveDrop(llvm::CallInst *pInsertPoint);
int getMaxNamedBarrierCount();
llvm::Value *allocBarriersDataPool(llvm::Function *pFunc);
llvm::Value *getManageableBarrierstructDataPtr(llvm::CallInst *pFuncInit, llvm::Value *barrierID,
llvm::Instruction *pInsertBefore);
llvm::Value *preparePointerToBarrierStruct(llvm::Value *ptrToBarrierSlot, MBDynamicStructFields FiledType,
llvm::Instruction *pInsertBefore);
llvm::Value *getManageableBarrierstructDataFieldPtr(llvm::Value *ptrToBarrierSlot, MBDynamicStructFields DataType,
llvm::Instruction *pInsertBefore);
void storeManageableBarrierstructData(llvm::Value *ptrToBarrierSlot, MBDynamicStructFields DataType,
llvm::Value *pData, llvm::Instruction *pInsertBefore);
llvm::Value *loadManageableBarrierstructData(llvm::Value *ptrToBarrierSlot, MBDynamicStructFields DataType,
llvm::Instruction *pInsertBefore, llvm::Value *prefetchedData = nullptr);
llvm::Value *loadManageBarrierAllStructData(llvm::Value *ptrToBarrierSlot, llvm::Instruction *pInsertBefore);
llvm::Value *prepareBarrierIDPoolPtr(llvm::Instruction *pInsertBefore);
llvm::Value *getBarriersDataPoolPtr(llvm::Instruction *pCallInst);
llvm::Value *getBarrierIDPoolPtr(llvm::Instruction *pCallInst);
void markID(llvm::Value *IDPool, llvm::Value *IDBarrier, llvm::Instruction *pInsertBefore);
void releaseID(llvm::Value *IDPool, llvm::Value *IDBarrier, llvm::Instruction *pInsertBefore);
llvm::Value *getFreeID(llvm::Value *IDPool, llvm::Instruction *pInsertBefore);
void clearData();
bool isConstantInit(llvm::CallInst *pFunc);
bool isCallOnceInit(llvm::CallInst *pFunc);
bool hasSimpleCallsOnly(llvm::CallInst *pFunc);
bool isSimpleBarrier(llvm::CallInst *pFunc);
bool usesSimpleBarrier(llvm::CallInst *pFunc);
SimpleBarrierStruct &getSimpleBarrierData(llvm::CallInst *pFunc);
SimpleBarrierStruct &getSimpleBarrierDataFromCall(llvm::CallInst *pFunc);
void lookForSimpleBarriers();
bool allBarrierSimple();
bool hasSimpleBarrier();
llvm::Value *getFreeID();
public:
// Pass identification, replacement for typeid
static char ID;
/// @brief Constructor
ManageableBarriersResolution();
/// @brief Destructor
~ManageableBarriersResolution();
/// @brief Provides name of pass
virtual llvm::StringRef getPassName() const override { return "ManageableBarriersResolution"; }
virtual bool runOnModule(llvm::Module &M) override;
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override { AU.addRequired<MetaDataUtilsWrapper>(); }
/// @brief Call instructions visitor.
/// Checks for OpenCL Named Barier init functions and resolves them into appropriate sequence of code
/// @param CI The call instruction.
void visitCallInst(llvm::CallInst &CI);
static bool HasHWSupport(GFXCORE_FAMILY GFX_CORE);
};
} // namespace IGC
|