File: GenXPostLegalization.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 (155 lines) | stat: -rw-r--r-- 5,099 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
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
150
151
152
153
154
155
/*========================== begin_copyright_notice ============================

Copyright (C) 2017-2022 Intel Corporation

SPDX-License-Identifier: MIT

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

//
/// GenXPostLegalization
/// --------------------
///
/// GenXPostLegalization is a function pass run after legalization with the
/// following purposes:
///
/// 1. It inserts a constant load for most constants that are not representable
///    as a constant operand in GenX code. See the GenXConstants section below.
//     (in the file GenXConstants.cpp)
///
/// 2. It calls GenXVectorDecomposer to perform vector decomposition. See the
///    GenXVectorDecomposer section below.
//     (in the file GenXVectorDecomposer.h)
///
/// Both of these things are done here because the results of them (constant
/// loads and decomposed vector operations) may benefit from CSE run after
/// this pass.
///
//===----------------------------------------------------------------------===//
#include "GenX.h"
#include "GenXBaling.h"
#include "GenXConstants.h"
#include "GenXSubtarget.h"
#include "GenXTargetMachine.h"
#include "GenXUtil.h"
#include "GenXVectorDecomposer.h"
#include "vc/Utils/GenX/BreakConst.h"

#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"

#define DEBUG_TYPE "GENX_POST_LEGALIZATION"

#include <set>

using namespace llvm;
using namespace genx;
using namespace GenXIntrinsic::GenXRegion;
using namespace vc;

namespace {

// GenXPostLegalization : post-legalization pass
class GenXPostLegalization : public FunctionPass {
  VectorDecomposer VD;
  const DataLayout *DL = nullptr;
  const GenXSubtarget *ST = nullptr;
public:
  static char ID;
  explicit GenXPostLegalization() : FunctionPass(ID) { }
  StringRef getPassName() const override {
    return "GenX post-legalization pass";
  }
  void getAnalysisUsage(AnalysisUsage &AU) const override;
  bool runOnFunction(Function &F) override;
};

} // end namespace llvm


char GenXPostLegalization::ID = 0;
namespace llvm { void initializeGenXPostLegalizationPass(PassRegistry &); }
INITIALIZE_PASS_BEGIN(GenXPostLegalization, "GenXPostLegalization",
                      "GenXPostLegalization", false, false)
INITIALIZE_PASS_END(GenXPostLegalization, "GenXPostLegalization",
                    "GenXPostLegalization", false, false)

FunctionPass *llvm::createGenXPostLegalizationPass() {
  initializeGenXPostLegalizationPass(*PassRegistry::getPassRegistry());
  return new GenXPostLegalization;
}

void GenXPostLegalization::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<TargetPassConfig>();
  AU.setPreservesCFG();
}

/***********************************************************************
 * GenXPostLegalization::runOnFunction : process one function
 */
bool GenXPostLegalization::runOnFunction(Function &F)
{
  DL = &F.getParent()->getDataLayout();
  ST = &getAnalysis<TargetPassConfig>()
            .getTM<GenXTargetMachine>()
            .getGenXSubtarget();

  bool Modified = false;
  Modified |= vc::breakConstantExprs(&F, vc::LegalizationStage::Legalized);

  for (Function::iterator fi = F.begin(), fe = F.end(); fi != fe; ++fi) {
    BasicBlock *BB = &*fi;
    for (BasicBlock::iterator bi = BB->begin(), be = BB->end(); bi != be; ++bi) {
      Instruction *Inst = &*bi;
      switch (vc::getAnyIntrinsicID(Inst)) {
      default:
        // Lower non-simple constant operands.
        Modified |= loadNonSimpleConstants(Inst, *ST, *DL, nullptr);
        break;
      case Intrinsic::fma:
        Modified |= loadConstants(Inst, *ST, *DL);
        break;
      }

      // If this is a wrregion with constant input, or phi node input, give it
      // to the vector decomposer. (We could just give it all wrregions, but we
      // are trying to minimize the amount of work it has to do.)
      if (!ST->disableVectorDecomposition()) {
        if (GenXIntrinsic::isWrRegion(Inst)) {
          if (isa<Constant>(Inst->getOperand(0)))
            VD.addStartWrRegion(Inst);
          else if (isa<PHINode>(Inst->getOperand(0)))
            VD.addStartWrRegion(Inst);
        }
      }
    }
  }
  // Run the vector decomposer for this function.
  Modified |= VD.run(*DL);
  // Cleanup region reads and writes.
  Modified |= simplifyRegionInsts(&F, DL, ST);
  // Cleanup redundant global loads.
  Modified |= cleanupLoads(&F);
  // Cleanup constant loads.
  Modified |= cleanupConstantLoads(&F);
  // Legalize constants in return.
  for (auto FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
    BasicBlock *BB = &*FI;
    for (auto BI = BB->begin(), BE = BB->end(); BI != BE; ++BI) {
      Instruction *Inst = &*BI;
      if (isa<ReturnInst>(Inst)) {
        Modified |= loadNonSimpleConstants(Inst, *ST, *DL, nullptr);
        Modified |= loadConstants(Inst, *ST, *DL);
      }
    }
  }

  return Modified;
}