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;
}
|