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 /// GenXRematerialization
11 /// ---------------------
12 ///
13 /// This pass performs rematerialization to reduce register pressure.
14 ///
15 //===----------------------------------------------------------------------===//
16 #include "GenX.h"
17 #include "GenXBaling.h"
18 #include "GenXLiveness.h"
19 #include "GenXModule.h"
20 #include "GenXNumbering.h"
21 #include "GenXPressureTracker.h"
22 #include "GenXUtil.h"
23 #include "llvm/Pass.h"
24 #include "Probe/Assertion.h"
25
26 using namespace llvm;
27 using namespace genx;
28
29 namespace {
30
31 class GenXRematerialization : public FGPassImplInterface,
32 public IDMixin<GenXRematerialization> {
33 GenXBaling *Baling = nullptr;
34 GenXLiveness *Liveness = nullptr;
35 GenXNumbering *Numbering = nullptr;
36 bool Modified = false;
37
38 public:
GenXRematerialization()39 explicit GenXRematerialization() {}
getPassName()40 static StringRef getPassName() { return "GenX rematerialization pass"; }
41 static void getAnalysisUsage(AnalysisUsage &AU);
42 bool runOnFunctionGroup(FunctionGroup &FG) override;
43
44 private:
45 void remat(Function *F, PressureTracker &RP);
46 };
47
48 } // namespace
49
50 namespace llvm {
51 void initializeGenXRematerializationWrapperPass(PassRegistry &);
52 using GenXRematerializationWrapper =
53 FunctionGroupWrapperPass<GenXRematerialization>;
54 } // namespace llvm
55 INITIALIZE_PASS_BEGIN(GenXRematerializationWrapper,
56 "GenXRematerializationWrapper",
57 "GenXRematerializationWrapper", false, false)
INITIALIZE_PASS_DEPENDENCY(GenXGroupBalingWrapper)58 INITIALIZE_PASS_DEPENDENCY(GenXGroupBalingWrapper)
59 INITIALIZE_PASS_DEPENDENCY(GenXLivenessWrapper)
60 INITIALIZE_PASS_DEPENDENCY(GenXNumberingWrapper)
61 INITIALIZE_PASS_END(GenXRematerializationWrapper,
62 "GenXRematerializationWrapper",
63 "GenXRematerializationWrapper", false, false)
64
65 ModulePass *llvm::createGenXRematerializationWrapperPass() {
66 initializeGenXRematerializationWrapperPass(*PassRegistry::getPassRegistry());
67 return new GenXRematerializationWrapper;
68 }
69
getAnalysisUsage(AnalysisUsage & AU)70 void GenXRematerialization::getAnalysisUsage(AnalysisUsage &AU) {
71 AU.addRequired<GenXGroupBaling>();
72 AU.addRequired<GenXLiveness>();
73 AU.addRequired<GenXNumbering>();
74 AU.addPreserved<GenXModule>();
75 AU.addPreserved<FunctionGroupAnalysis>();
76 AU.setPreservesCFG();
77 }
78
runOnFunctionGroup(FunctionGroup & FG)79 bool GenXRematerialization::runOnFunctionGroup(FunctionGroup &FG) {
80 if (skipOptWithLargeBlock(FG))
81 return false;
82
83 Modified = false;
84 Baling = &getAnalysis<GenXGroupBaling>();
85 Liveness = &getAnalysis<GenXLiveness>();
86 Numbering = &getAnalysis<GenXNumbering>();
87 const auto &DL = FG.getModule()->getDataLayout();
88 PressureTracker RP(DL, FG, Liveness);
89 for (auto fgi = FG.begin(), fge = FG.end(); fgi != fge; ++fgi)
90 remat(*fgi, RP);
91 return Modified;
92 }
93
remat(Function * F,PressureTracker & RP)94 void GenXRematerialization::remat(Function *F, PressureTracker &RP) {
95 // Collect rematerialization candidates.
96 std::vector<Use *> Candidates;
97 for (auto &BB : F->getBasicBlockList()) {
98 for (auto &Inst : BB.getInstList()) {
99 // (1) upward cast
100 if (auto CI = dyn_cast<CastInst>(&Inst)) {
101 if (CI->getOpcode() != Instruction::UIToFP &&
102 CI->getOpcode() != Instruction::SIToFP)
103 continue;
104 if (!CI->getType()->isVectorTy())
105 continue;
106 if (CI->getSrcTy()->getScalarSizeInBits() >=
107 CI->getDestTy()->getScalarSizeInBits())
108 continue;
109 if (Inst.isUsedOutsideOfBlock(&BB) || Inst.getNumUses() <= 2)
110 continue;
111 LiveRange *LR = Liveness->getLiveRangeOrNull(CI);
112 if (!LR || LR->value_size() != 1)
113 continue;
114 IGC_ASSERT(LR->value_begin()->getValue() == CI);
115 unsigned B = Numbering->getNumber(CI);
116 for (auto &U : CI->uses()) {
117 auto UI = U.getUser();
118 unsigned E = Numbering->getNumber(UI);
119 if (E > B && RP.intersectWithRedRegion(B, E))
120 Candidates.push_back(&U);
121 }
122 }
123 }
124 }
125
126 // Do rematerialization.
127 for (auto U : Candidates) {
128 Instruction *Inst = cast<Instruction>(U->get());
129 Instruction *UI = cast<Instruction>(U->getUser());
130 Instruction *Clone = Inst->clone();
131 Clone->insertBefore(UI);
132 U->set(Clone);
133 Modified = true;
134 }
135 }
136