File: CrossPhaseConstProp.cpp

package info (click to toggle)
intel-graphics-compiler2 2.16.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 106,644 kB
  • sloc: cpp: 805,640; lisp: 287,672; ansic: 16,414; python: 3,952; yacc: 2,588; lex: 1,666; pascal: 313; sh: 186; makefile: 35
file content (94 lines) | stat: -rw-r--r-- 3,652 bytes parent folder | download
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
/*========================== begin_copyright_notice ============================

Copyright (C) 2020-2021 Intel Corporation

SPDX-License-Identifier: MIT

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

#include "Compiler/CISACodeGen/CrossPhaseConstProp.hpp"
#include "LLVMWarningsPush.hpp"
#include "llvm/Pass.h"
#include "LLVMWarningsPop.hpp"
#include "Compiler/CISACodeGen/PixelShaderCodeGen.hpp"
#include "Compiler/CISACodeGen/helper.h"
#include "Compiler/MetaDataUtilsWrapper.h"
using namespace llvm;
namespace {
class CrossPhaseConstProp : public FunctionPass {
public:
  static char ID; // Pass identification, replacement for typeid

  CrossPhaseConstProp(IGC::PSSignature *signature = nullptr);

  bool runOnFunction(Function &F) override;

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<IGC::MetaDataUtilsWrapper>();
    AU.setPreservesCFG();
  }

private:
  IGC::PSSignature *m_signature;
};
} // namespace

#define PASS_FLAG "igc-crossphaseconstprop"
#define PASS_DESCRIPTION "Special const prop for multirate shading"
#define PASS_CFG_ONLY false
#define PASS_ANALYSIS false
IGC_INITIALIZE_PASS_BEGIN(CrossPhaseConstProp, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
IGC_INITIALIZE_PASS_DEPENDENCY(MetaDataUtilsWrapper)
IGC_INITIALIZE_PASS_END(CrossPhaseConstProp, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)

CrossPhaseConstProp::CrossPhaseConstProp(IGC::PSSignature *signature) : FunctionPass(ID), m_signature(signature) {
  initializeCrossPhaseConstPropPass(*PassRegistry::getPassRegistry());
}

char CrossPhaseConstProp::ID = 0;

FunctionPass *IGC::createCrossPhaseConstPropPass(IGC::PSSignature *signature) {
  return new CrossPhaseConstProp(signature);
}

bool CrossPhaseConstProp::runOnFunction(Function &F) {
  IGC::IGCMD::MetaDataUtils *pMdUtils = getAnalysis<IGC::MetaDataUtilsWrapper>().getMetaDataUtils();
  if (!IGC::isEntryFunc(pMdUtils, &F) || m_signature == nullptr) {
    return false;
  }

  std::vector<Instruction *> instructionsToRemove;
  bool isCoarse = IGC::isCoarsePhaseFunction(&F);
  bool isPerPixel = IGC::isPixelPhaseFunction(&F);
  if (isCoarse || isPerPixel) {
    for (auto &BB : F) {
      for (auto &I : BB) {
        if (GenIntrinsicInst *inst = dyn_cast<GenIntrinsicInst>(&I)) {
          GenISAIntrinsic::ID IID = inst->getIntrinsicID();
          if (isPerPixel && IID == GenISAIntrinsic::GenISA_PHASE_INPUT) {
            unsigned int index = (unsigned int)cast<llvm::ConstantInt>(inst->getOperand(0))->getZExtValue();
            auto constantOutput = m_signature->PSConstantOutput.find(index);
            if (constantOutput != m_signature->PSConstantOutput.end()) {
              inst->replaceAllUsesWith(ConstantFP::get(
                  inst->getType(), APFloat(inst->getType()->getFltSemantics(),
                                           APInt(inst->getType()->getScalarSizeInBits(), constantOutput->second))));
              instructionsToRemove.push_back(inst);
            }
          } else if (isCoarse && IID == GenISAIntrinsic::GenISA_PHASE_OUTPUT) {
            if (auto fpValue = dyn_cast<ConstantFP>(inst->getArgOperand(0))) {
              unsigned int index = (unsigned int)cast<llvm::ConstantInt>(inst->getArgOperand(1))->getZExtValue();
              m_signature->PSConstantOutput[index] = fpValue->getValueAPF().bitcastToAPInt().getLimitedValue();
              instructionsToRemove.push_back(inst);
            }
          }
        }
      }
    }

    for (auto inst : instructionsToRemove) {
      inst->eraseFromParent();
    }
  }

  return instructionsToRemove.size() > 0;
}