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
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2020-2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#pragma once
#include "Compiler/MetaDataApi/MetaDataApi.h"
#include "common/LLVMWarningsPush.hpp"
#include <llvm/ADT/StringRef.h>
#include "common/LLVMWarningsPop.hpp"
namespace IGC {
//===----------------------------------------------------------------------===//
/// This is the class to track values that needs to be known at compile-time.
/// This class can be used in three different scenarios, to track: images, samplers or constants.
/// The algorithm is simply divided into two main steps:
/// 1. trackValue function goes up through the tree to find an alloca which holds the value
/// passed as an parameter to call instruction.
/// 2. alloca instruction found in point 1. is passed to findAllocaValue function to find
/// the source of value stored in that alloca. It can be either image, sampler or constant
/// value.
class ValueTracker {
private:
ValueTracker(llvm::Function *F, const IGC::IGCMD::MetaDataUtils *pMdUtils, const IGC::ModuleMetaData *pModMD,
llvm::function_ref<bool(llvm::Value *)> predicate)
: m_pMDUtils(pMdUtils), m_pModMD(pModMD), m_Function(F), m_predicate(predicate) {};
// The first step of the algorithm
llvm::Value *trackValue(llvm::Value *I);
llvm::Value *handleGenIntrinsic(llvm::GenIntrinsicInst *I);
llvm::Value *handleExtractElement(llvm::ExtractElementInst *E);
llvm::Value *handleGlobalVariable(llvm::GlobalVariable *G);
llvm::Value *handleConstExpr(llvm::ConstantExpr *CE);
// The second step of the algorithm
llvm::Value *findAllocaValue(llvm::Value *V, const uint depth);
const IGC::IGCMD::MetaDataUtils *m_pMDUtils;
const IGC::ModuleMetaData *m_pModMD;
llvm::Function *m_Function;
// Used for evaluating if currently processed value is the final value.
// Value tracker will return the value if predicate is true.
llvm::function_ref<bool(llvm::Value *)> m_predicate;
std::vector<llvm::ConstantInt *> gepIndices;
std::vector<llvm::CallInst *> callInsts;
llvm::SmallPtrSet<llvm::Value *, 10> visitedValues;
std::vector<llvm::Value *> workList;
std::map<llvm::Value *, llvm::Value *> phiVisited;
public:
static llvm::Value *track(llvm::CallInst *CI, const uint index, const IGC::IGCMD::MetaDataUtils *pMdUtils = nullptr,
const IGC::ModuleMetaData *pModMD = nullptr,
llvm::function_ref<bool(llvm::Value *)> predicate = nullptr);
static llvm::Value *track(llvm::Value *value, llvm::Function *function, const IGC::IGCMD::MetaDataUtils *pMdUtils,
const IGC::ModuleMetaData *pModMD,
llvm::function_ref<bool(llvm::Value *)> predicate = nullptr);
};
} // namespace IGC
|