File: MSAAInsertDiscard.cpp

package info (click to toggle)
intel-graphics-compiler 1.0.12504.6-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 83,912 kB
  • sloc: cpp: 910,147; lisp: 202,655; ansic: 15,197; python: 4,025; yacc: 2,241; lex: 1,570; pascal: 244; sh: 104; makefile: 25
file content (130 lines) | stat: -rw-r--r-- 4,444 bytes parent folder | download | duplicates (2)
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
/*========================== begin_copyright_notice ============================

Copyright (C) 2020-2021 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

#include "GenISAIntrinsics/GenIntrinsicInst.h"
#include "MSAAInsertDiscard.hpp"
#include "Compiler/IGCPassSupport.h"
#include "common/LLVMUtils.h"
#include "Compiler/CodeGenPublic.h"
#include "common/LLVMWarningsPush.hpp"
#include "llvmWrapper/IR/DerivedTypes.h"
#include <llvm/Support/CommandLine.h>
#include <llvm/IR/Function.h>
#include <llvm/ADT/SmallVector.h>
#include "common/LLVMWarningsPop.hpp"
#include "Probe/Assertion.h"

using namespace llvm;
using namespace IGC;

// Register pass to igc-opt
#define PASS_FLAG "igc-MSAAInsertDiscard"
#define PASS_DESCRIPTION "Insert discard code for MSAA MSC kernels"
#define PASS_CFG_ONLY false
#define PASS_ANALYSIS true
IGC_INITIALIZE_PASS_BEGIN(MSAAInsertDiscard, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
IGC_INITIALIZE_PASS_DEPENDENCY(CodeGenContextWrapper)
IGC_INITIALIZE_PASS_END(MSAAInsertDiscard, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)

char MSAAInsertDiscard::ID = 0;

MSAAInsertDiscard::MSAAInsertDiscard() : FunctionPass(ID)
{
    done = false;
    m_kernelSize = IGC_GET_FLAG_VALUE(MSAAClearedKernel);
    initializeWorkaroundAnalysisPass(*PassRegistry::getPassRegistry());
};

int MSAAInsertDiscard::getiCMPValue()
{
    switch (m_kernelSize)
    {
    case 2:
        return 3;

    case 4:
        return 255;

    case 8:
    case 16:
        return -1;

    default:
        return 0;
    }
}

void MSAAInsertDiscard::visitCallInst(CallInst& I)
{
    if (done)
        return;

    if (const GenIntrinsicInst * intr = dyn_cast<GenIntrinsicInst>(&I))
    {
        GenISAIntrinsic::ID intrID = intr->getIntrinsicID();
        if (intrID != GenISAIntrinsic::GenISA_ldmsptr)
            return;

        // For the case of m_kernelSize is 2
        // % 6 = call <2 x i32> @llvm.genx.GenISA.ldmcsptr.v2i32.i32.p196608v4f32(
        //         i32 % 4, i32 % 5, i32 0, i32 0,
        //         <4 x float> addrspace(196608) * null, i32 0, i32 0, i32 0)
        // % 7 = extractelement <2 x i32> % 6, i32 0
        // % 8 = icmp eq i32 % 7, 3                     <------- inserted ------->
        // call void @llvm.genx.GenISA.discard(i1 % 8)  <------- inserted ------->
        // % 9 = extractelement <2 x i32> % 6, i32 1
        // % 10 = call fast <4 x float> @llvm.genx.GenISA.ldmsptr.v4f32.p196608v4f32(
        //          i32 0, i32 % 7, i32 % 9, i32 % 4, i32 % 5, i32 0, i32 0,
        //          <4 x float> addrspace(196608) * null, i32 0, i32 0, i32 0)

        GenIntrinsicInst* ldmcs = nullptr;
        Value* extractData1 = I.getOperand(1);
        Value* extractData2 = I.getOperand(2);
        Value* mcsData = nullptr;
        Value* iCmpEq = nullptr;
        if (ExtractElementInst * extractInst1 = dyn_cast<ExtractElementInst>(extractData1))
        {
            mcsData = extractInst1->getOperand(0);
            ldmcs = dyn_cast<GenIntrinsicInst>(mcsData);

            IGC_ASSERT(ldmcs != NULL);
            if (m_kernelSize == 16) {
                // insert before current ldmsptr
                m_builder->SetInsertPoint(&I);
                Value* andValue = m_builder->CreateAnd(extractData1, extractData2);
                iCmpEq = m_builder->CreateICmpEQ(andValue,
                    m_builder->getInt32(getiCMPValue()));
            }
            else {
                // insert before the 2nd extractelement
                m_builder->SetInsertPoint(dyn_cast<ExtractElementInst>(extractData2));
                iCmpEq = m_builder->CreateICmpEQ(extractData1,
                    m_builder->getInt32(getiCMPValue()));
            }

            Function* func_discard =
                llvm::GenISAIntrinsic::getDeclaration(
                    I.getParent()->getParent()->getParent(),
                    GenISAIntrinsic::GenISA_discard);
            m_builder->CreateCall(func_discard, { iCmpEq });

            done = true;
        }
    }
}

bool MSAAInsertDiscard::runOnFunction(Function& F)
{
    m_pCtxWrapper = &getAnalysis<CodeGenContextWrapper>();
    CodeGenContext* cgCtx = m_pCtxWrapper->getCodeGenContext();
    IRBuilder<> builder(F.getContext());
    m_builder = &builder;
    visit(F);
    DumpLLVMIR(cgCtx, "AfterMSAAInsertDiscard");
    return true;
}