1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 //===----------------------------------------------------------------------===//
10 //
11 // A helper class that returns a mapping from message generating
12 // intrinsic (e.g. sample, load, urb_write) arguments to their respective
13 // positions in the payload message.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #pragma once
18 #include "Compiler/CISACodeGen/Platform.hpp"
19 #include "Compiler/CodeGenPublic.h"
20 #include "common/LLVMWarningsPush.hpp"
21 #include <llvm/IR/Function.h>
22 #include <llvm/IR/Instruction.h>
23 #include <llvm/IR/IntrinsicInst.h>
24 #include "common/LLVMWarningsPop.hpp"
25 #include "Compiler/CISACodeGen/helper.h"
26 #include "GenISAIntrinsics/GenIntrinsicInst.h"
27 #include "common/Types.hpp"
28 #include "Probe/Assertion.h"
29 
30 namespace IGC
31 {
32 
33     class PayloadMapping
34     {
35         friend class CoalescingEngine;
36     public:
37         void ValidateNumberofSources(EOPCODE opCode, bool isCube, uint& numberofSrcs);
38 
39         typedef llvm::DenseMap<std::pair<const llvm::Instruction*, uint>, llvm::Value*> PayloadMappingCache;
40 
41     protected:
PayloadMapping()42         PayloadMapping() : m_CodeGenContext(nullptr) {}
PayloadMapping(CodeGenContext * ctx)43         PayloadMapping(CodeGenContext* ctx) : m_CodeGenContext(ctx) {}
44 
45         /// ------------------------------
46         uint GetNumPayloadElements(const llvm::Instruction* inst);
47         uint GetNumPayloadElements_URBWrite(const llvm::GenIntrinsicInst* inst);
48         uint GetNumPayloadElements_RTWrite(const llvm::GenIntrinsicInst* inst);
49         uint GetNumPayloadElements_DSRTWrite(const llvm::GenIntrinsicInst* inst);
50         uint GetNumPayloadElements_LDMS(const llvm::GenIntrinsicInst* inst);
51         uint GetNonAdjustedNumPayloadElements_Sample(const llvm::SampleIntrinsic* inst);
52         uint GetNumPayloadElements_Sample(const llvm::SampleIntrinsic* inst);
53 
54         /// ------------------------------
55         /// \brief Get the mapping from the payload element (at position index)
56         /// to intrinsic argument value. Indexing is zero based.
57         llvm::Value* GetPayloadElementToValueMapping(const llvm::Instruction* inst, uint index);
58         llvm::Value* GetPayloadElementToValueMapping_URBWrite(const llvm::GenIntrinsicInst* inst, uint index);
59         llvm::Value* GetPayloadElementToValueMapping_RTWrite(const llvm::GenIntrinsicInst* inst, const uint index);
60         llvm::Value* GetPayloadElementToValueMapping_DSRTWrite(const llvm::GenIntrinsicInst* inst, const uint index);
61         uint GetNonAdjustedPayloadElementIndexToValueIndexMapping_sample(const llvm::SampleIntrinsic* inst, uint index);
62         llvm::Value* GetPayloadElementToValueMapping_LDMS(const llvm::SamplerLoadIntrinsic* inst, const uint index);
63         llvm::Value* GetNonAdjustedPayloadElementToValueMapping_sample(const llvm::SampleIntrinsic* inst, const uint index);
64         llvm::Value* GetPayloadElementToValueMapping_sample(const llvm::SampleIntrinsic* inst, const uint index);
65 
66         //Handling of non-homogeneous payloads (RT write)
67         const llvm::Instruction* GetSupremumOfNonHomogeneousPart(
68             const llvm::Instruction* inst1,
69             const llvm::Instruction* inst2);
70         int GetRightReservedOffset(const llvm::Instruction* inst, SIMDMode simdMode);
71         int GetLeftReservedOffset(const llvm::Instruction* inst, SIMDMode simdMode);
72         bool HasNonHomogeneousPayloadElements(const llvm::Instruction* inst);
73         const llvm::Instruction* GetSupremumOfNonHomogeneousPart_RTWrite(
74             const llvm::Instruction* inst1,
75             const llvm::Instruction* inst2);
76         template <typename T>
77         int GetLeftReservedOffset_RTWrite(const T* inst, SIMDMode simdMode);
78         template <typename T>
79         int GetRightReservedOffset_RTWrite(const T* inst, SIMDMode simdMode);
80         template <typename T>
81         bool HasNonHomogeneousPayloadElements_RTWrite(const T* inst);
82 
83         /// ------------------------------
84         bool IsUndefOrZeroImmediate(const llvm::Value* value);
85         bool IsZeroLOD(const llvm::SampleIntrinsic* inst);
86         bool DoPeelFirstElement(const llvm::Instruction* inst);
87 
DoesAllowSplit(const llvm::Instruction * inst)88         bool DoesAllowSplit(const llvm::Instruction* inst)
89         {
90             const llvm::GenIntrinsicInst* intrinsicInst = llvm::dyn_cast<llvm::GenIntrinsicInst>(inst);
91             IGC_ASSERT(intrinsicInst);
92             if (llvm::dyn_cast<llvm::SampleIntrinsic>(inst))
93             {
94                 return true;
95             }
96             return false;
97         }
98 
99     private:
100         CodeGenContext* m_CodeGenContext;
101         PayloadMappingCache m_PayloadMappingCache;
102 
103     };
104 
105 } //End namespace IGC
106