Skip to content

Commit 7272c89

Browse files
dmitryryinteligcbot
authored andcommitted
Support more vector instructions in InstRebuilder.
1 parent 9e0096b commit 7272c89

File tree

6 files changed

+142
-12
lines changed

6 files changed

+142
-12
lines changed

IGC/VectorCompiler/include/vc/Utils/General/InstRebuilder.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ SPDX-License-Identifier: MIT
1313

1414
#include <llvm/ADT/ArrayRef.h>
1515
#include <llvm/IR/Instructions.h>
16+
#include <llvm/IR/IntrinsicInst.h>
1617
#include <llvm/IR/Use.h>
1718
#include <llvm/Support/Casting.h>
1819

@@ -246,12 +247,20 @@ class InstructionRebuilder {
246247
return Replace;
247248
}
248249

250+
static std::vector<llvm::Value *>
251+
getOrigOperands(llvm::Instruction &OrigInst) {
252+
if (llvm::isa<llvm::IntrinsicInst>(OrigInst)) {
253+
auto &OrigIntr = llvm::cast<llvm::IntrinsicInst>(OrigInst);
254+
return {OrigIntr.arg_begin(), OrigIntr.arg_end()};
255+
}
256+
return {OrigInst.value_op_begin(), OrigInst.value_op_end()};
257+
}
258+
249259
// Takes arguments of the original instruction (OrigInst.User) and rewrites
250260
// the required ones with new values according to info in \p OrigInst
251261
static std::vector<llvm::Value *>
252262
createNewOperands(const InstToRebuild &OrigInst) {
253-
std::vector<llvm::Value *> NewOperands{OrigInst.User->value_op_begin(),
254-
OrigInst.User->value_op_end()};
263+
auto NewOperands = getOrigOperands(*OrigInst.User);
255264
for (auto &&OpReplacement :
256265
zip(OrigInst.OperandNos, OrigInst.NewOperands)) {
257266
int OperandNo = std::get<0>(OpReplacement);

IGC/VectorCompiler/include/vc/Utils/General/Types.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ SPDX-License-Identifier: MIT
1111

1212
#include <llvm/IR/DerivedTypes.h>
1313

14+
#include "llvmWrapper/IR/DerivedTypes.h"
15+
1416
namespace vc {
1517

1618
// Returns potentially new pointer type with the provided \p AddrSpace
@@ -20,6 +22,16 @@ inline llvm::PointerType *changeAddrSpace(llvm::PointerType *OrigTy,
2022
return llvm::PointerType::get(OrigTy->getElementType(), AddrSpace);
2123
}
2224

25+
// Changes addrspace inside a vector of pointers type.
26+
IGCLLVM::FixedVectorType *changeAddrSpace(IGCLLVM::FixedVectorType *OrigTy,
27+
int AddrSpace);
28+
29+
// Change addrspace of a pointer or a vector of pointers type.
30+
llvm::Type *changeAddrSpace(llvm::Type *OrigTy, int AddrSpace);
31+
32+
// Get addrspace of a pointer or a vector of pointers type.
33+
int getAddrSpace(llvm::Type *PtrOrPtrVec);
34+
2335
} // namespace vc
2436

2537
#endif // VC_UTILS_GENERAL_TYPES_H

IGC/VectorCompiler/lib/GenXOpts/CMTrans/CMABI.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ SPDX-License-Identifier: MIT
5858
#include "llvm/IR/IRBuilder.h"
5959
#include "llvm/IR/InstIterator.h"
6060
#include "llvm/IR/InstVisitor.h"
61+
#include "llvm/IR/IntrinsicInst.h"
6162
#include "llvm/IR/Intrinsics.h"
6263
#include "llvm/IR/Module.h"
6364
#include "llvm/InitializePasses.h"
@@ -541,8 +542,13 @@ bool CMABI::runOnSCC(CallGraphSCC &SCC) {
541542
// change will stop.
542543
static bool isRebuildTerminal(const Instruction &Inst) {
543544
// Result of a load inst is no longer a pointer so here propogation will stop.
544-
return isa<LoadInst>(Inst) || isa<AddrSpaceCastInst>(Inst) ||
545-
isa<StoreInst>(Inst);
545+
if (isa<LoadInst>(Inst) || isa<AddrSpaceCastInst>(Inst) ||
546+
isa<StoreInst>(Inst))
547+
return true;
548+
if (!isa<IntrinsicInst>(Inst))
549+
return false;
550+
auto IID = cast<IntrinsicInst>(Inst).getIntrinsicID();
551+
return IID == Intrinsic::masked_gather || IID == Intrinsic::masked_scatter;
546552
}
547553

548554
// Replaces uses of global variables with the corresponding allocas inside a

IGC/VectorCompiler/lib/Utils/General/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ set(GENERAL_UTILS_SOURCES
1010
BiF.cpp
1111
InstRebuilder.cpp
1212
BreakConst.cpp
13+
Types.cpp
1314
)
1415

1516
add_library(VCGeneralUtils ${GENERAL_UTILS_SOURCES})

IGC/VectorCompiler/lib/Utils/General/InstRebuilder.cpp

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,52 @@ SPDX-License-Identifier: MIT
1212
#include "Probe/Assertion.h"
1313
#include "llvmWrapper/Support/Alignment.h"
1414

15+
#include <llvm/ADT/ArrayRef.h>
1516
#include <llvm/IR/InstVisitor.h>
17+
#include <llvm/IR/IntrinsicInst.h>
18+
19+
#include <algorithm>
20+
#include <iterator>
1621

1722
using namespace llvm;
1823
using namespace vc;
1924

25+
// Define intrinsic return type based on its arguments types.
26+
static Type *getIntrinsicRetTypeBasedOnArgs(Intrinsic::ID IID,
27+
ArrayRef<Type *> ArgTys,
28+
LLVMContext &C) {
29+
switch (IID) {
30+
case Intrinsic::masked_gather:
31+
// "Pass through" operand.
32+
return ArgTys[3];
33+
case Intrinsic::masked_scatter:
34+
return Type::getVoidTy(C);
35+
default:
36+
IGC_ASSERT_MESSAGE(0, "unsupported intrinsic");
37+
return nullptr;
38+
}
39+
}
40+
41+
// Emits list of overloaded types for the provided intrinsic. Takes all the
42+
// types that may take part in overloading: return type, types of arguments.
43+
static std::vector<Type *>
44+
getIntrinsicOverloadedTypes(Intrinsic::ID IID, Type *RetTy,
45+
ArrayRef<Type *> ArgTys) {
46+
IGC_ASSERT_MESSAGE(RetTy, "wrong argument");
47+
// FIXME: generalize for any ID using IntrinsicInfoTable.
48+
switch (IID) {
49+
case Intrinsic::masked_gather:
50+
// Loaded value type and pointer operand type.
51+
return {RetTy, ArgTys[0]};
52+
case Intrinsic::masked_scatter:
53+
// Value and pointer types.
54+
return {ArgTys[0], ArgTys[1]};
55+
default:
56+
IGC_ASSERT_MESSAGE(0, "unsupported intrinsic");
57+
return {};
58+
}
59+
}
60+
2061
namespace {
2162
class cloneInstWithNewOpsImpl
2263
: public InstVisitor<cloneInstWithNewOpsImpl, Instruction *> {
@@ -61,18 +102,17 @@ class cloneInstWithNewOpsImpl
61102
// type addrspace corresponds with this operand.
62103
CastInst *visitBitCastInst(BitCastInst &OrigCast) {
63104
Value &NewOp = getSingleNewOperand();
64-
if (isa<PointerType>(OrigCast.getType()))
65-
return visitPointerBitCastInst(OrigCast);
105+
// If the operand changed addrspace the bitcast type should change it too.
106+
if (OrigCast.getType()->isPtrOrPtrVectorTy())
107+
return visitPtrOrPtrVectorBitCastInst(OrigCast);
66108
return new BitCastInst{&NewOp, OrigCast.getType()};
67109
}
68110

69-
CastInst *visitPointerBitCastInst(BitCastInst &OrigCast) {
111+
CastInst *visitPtrOrPtrVectorBitCastInst(BitCastInst &OrigCast) {
70112
Value &NewOp = getSingleNewOperand();
71-
auto NewOpAS = cast<PointerType>(NewOp.getType())->getAddressSpace();
72-
// If the operand changed addrspace the bitcast type should change it too.
73-
return new BitCastInst{
74-
&NewOp,
75-
changeAddrSpace(cast<PointerType>(OrigCast.getType()), NewOpAS)};
113+
auto NewOpAS = getAddrSpace(NewOp.getType());
114+
return new BitCastInst{&NewOp,
115+
changeAddrSpace(OrigCast.getType(), NewOpAS)};
76116
}
77117

78118
CastInst *visitAddrSpaceCastInst(AddrSpaceCastInst &OrigCast) {
@@ -89,6 +129,24 @@ class cloneInstWithNewOpsImpl
89129
return SelectInst::Create(NewOperands[0], NewOperands[1], NewOperands[2]);
90130
}
91131

132+
IntrinsicInst *visitIntrinsicInst(IntrinsicInst &OrigIntrinsic) {
133+
auto IID = OrigIntrinsic.getIntrinsicID();
134+
if (IID != Intrinsic::masked_gather && IID != Intrinsic::masked_scatter) {
135+
IGC_ASSERT_MESSAGE(0, "yet unsupported instruction");
136+
return nullptr;
137+
}
138+
std::vector<Type *> ArgTys;
139+
std::transform(NewOperands.begin(), NewOperands.end(),
140+
std::back_inserter(ArgTys),
141+
[](Value *Operand) { return Operand->getType(); });
142+
auto *RetTy =
143+
getIntrinsicRetTypeBasedOnArgs(IID, ArgTys, OrigIntrinsic.getContext());
144+
auto OverloadedTys = getIntrinsicOverloadedTypes(IID, RetTy, ArgTys);
145+
auto *Decl = Intrinsic::getDeclaration(OrigIntrinsic.getModule(), IID,
146+
OverloadedTys);
147+
return cast<IntrinsicInst>(CallInst::Create(Decl, NewOperands));
148+
}
149+
92150
private:
93151
Value &getSingleNewOperand() {
94152
IGC_ASSERT_MESSAGE(
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*========================== begin_copyright_notice ============================
2+
3+
Copyright (C) 2021 Intel Corporation
4+
5+
SPDX-License-Identifier: MIT
6+
7+
============================= end_copyright_notice ===========================*/
8+
9+
#include "vc/Utils/General/Types.h"
10+
11+
#include "Probe/Assertion.h"
12+
13+
#include <llvm/Support/Casting.h>
14+
15+
using namespace llvm;
16+
17+
IGCLLVM::FixedVectorType *vc::changeAddrSpace(IGCLLVM::FixedVectorType *OrigTy,
18+
int AddrSpace) {
19+
IGC_ASSERT_MESSAGE(OrigTy, "wrong argument");
20+
auto *PointeeTy = OrigTy->getElementType()->getPointerElementType();
21+
auto EC = OrigTy->getElementCount();
22+
return IGCLLVM::FixedVectorType::get(
23+
llvm::PointerType::get(PointeeTy, AddrSpace), EC);
24+
}
25+
26+
Type *vc::changeAddrSpace(Type *OrigTy, int AddrSpace) {
27+
IGC_ASSERT_MESSAGE(OrigTy, "wrong argument");
28+
IGC_ASSERT_MESSAGE(
29+
OrigTy->isPtrOrPtrVectorTy(),
30+
"wrong argument: pointer or vector of pointers type is expected");
31+
if (OrigTy->isPointerTy())
32+
return changeAddrSpace(cast<PointerType>(OrigTy), AddrSpace);
33+
return changeAddrSpace(cast<IGCLLVM::FixedVectorType>(OrigTy), AddrSpace);
34+
}
35+
36+
int vc::getAddrSpace(Type *PtrOrPtrVec) {
37+
IGC_ASSERT_MESSAGE(PtrOrPtrVec, "wrong argument");
38+
IGC_ASSERT_MESSAGE(
39+
PtrOrPtrVec->isPtrOrPtrVectorTy(),
40+
"wrong argument: pointer or vector of pointers type is expected");
41+
if (PtrOrPtrVec->isPointerTy())
42+
return PtrOrPtrVec->getPointerAddressSpace();
43+
return PtrOrPtrVec->getVectorElementType()->getPointerAddressSpace();
44+
}

0 commit comments

Comments
 (0)