20
20
#include " SPIRVSubtarget.h"
21
21
#include " SPIRVTargetMachine.h"
22
22
#include " SPIRVUtils.h"
23
+ #include " llvm/IR/TypedPointerType.h"
23
24
24
25
using namespace llvm ;
25
26
SPIRVGlobalRegistry::SPIRVGlobalRegistry (unsigned PointerSize)
@@ -420,9 +421,10 @@ Register
420
421
SPIRVGlobalRegistry::getOrCreateConstNullPtr (MachineIRBuilder &MIRBuilder,
421
422
SPIRVType *SpvType) {
422
423
const Type *LLVMTy = getTypeForSPIRVType (SpvType);
423
- const PointerType *LLVMPtrTy = cast<PointerType >(LLVMTy);
424
+ const TypedPointerType *LLVMPtrTy = cast<TypedPointerType >(LLVMTy);
424
425
// Find a constant in DT or build a new one.
425
- Constant *CP = ConstantPointerNull::get (const_cast <PointerType *>(LLVMPtrTy));
426
+ Constant *CP = ConstantPointerNull::get (PointerType::get (
427
+ LLVMPtrTy->getElementType (), LLVMPtrTy->getAddressSpace ()));
426
428
Register Res = DT.find (CP, CurMF);
427
429
if (!Res.isValid ()) {
428
430
LLT LLTy = LLT::pointer (LLVMPtrTy->getAddressSpace (), PointerSize);
@@ -517,6 +519,13 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
517
519
LLT RegLLTy = LLT::pointer (MRI->getType (ResVReg).getAddressSpace (), 32 );
518
520
MRI->setType (Reg, RegLLTy);
519
521
assignSPIRVTypeToVReg (BaseType, Reg, MIRBuilder.getMF ());
522
+ } else {
523
+ // Our knowledge about the type may be updated.
524
+ // If that's the case, we need to update a type
525
+ // associated with the register.
526
+ SPIRVType *DefType = getSPIRVTypeForVReg (ResVReg);
527
+ if (!DefType || DefType != BaseType)
528
+ assignSPIRVTypeToVReg (BaseType, Reg, MIRBuilder.getMF ());
520
529
}
521
530
522
531
// If it's a global variable with name, output OpName for it.
@@ -705,33 +714,37 @@ SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
705
714
}
706
715
return getOpTypeFunction (RetTy, ParamTypes, MIRBuilder);
707
716
}
708
- if (auto PType = dyn_cast<PointerType>(Ty)) {
709
- SPIRVType *SpvElementType;
710
- // At the moment, all opaque pointers correspond to i8 element type.
711
- // TODO: change the implementation once opaque pointers are supported
712
- // in the SPIR-V specification.
713
- SpvElementType = getOrCreateSPIRVIntegerType (8 , MIRBuilder);
714
- // Get access to information about available extensions
715
- const SPIRVSubtarget *ST =
716
- static_cast <const SPIRVSubtarget *>(&MIRBuilder.getMF ().getSubtarget ());
717
- auto SC = addressSpaceToStorageClass (PType->getAddressSpace (), *ST);
718
- // Null pointer means we have a loop in type definitions, make and
719
- // return corresponding OpTypeForwardPointer.
720
- if (SpvElementType == nullptr ) {
721
- if (!ForwardPointerTypes.contains (Ty))
722
- ForwardPointerTypes[PType] = getOpTypeForwardPointer (SC, MIRBuilder);
723
- return ForwardPointerTypes[PType];
724
- }
725
- // If we have forward pointer associated with this type, use its register
726
- // operand to create OpTypePointer.
727
- if (ForwardPointerTypes.contains (PType)) {
728
- Register Reg = getSPIRVTypeID (ForwardPointerTypes[PType]);
729
- return getOpTypePointer (SC, SpvElementType, MIRBuilder, Reg);
730
- }
731
-
732
- return getOrCreateSPIRVPointerType (SpvElementType, MIRBuilder, SC);
717
+ unsigned AddrSpace = 0xFFFF ;
718
+ if (auto PType = dyn_cast<TypedPointerType>(Ty))
719
+ AddrSpace = PType->getAddressSpace ();
720
+ else if (auto PType = dyn_cast<PointerType>(Ty))
721
+ AddrSpace = PType->getAddressSpace ();
722
+ else
723
+ report_fatal_error (" Unable to convert LLVM type to SPIRVType" , true );
724
+ SPIRVType *SpvElementType;
725
+ // At the moment, all opaque pointers correspond to i8 element type.
726
+ // TODO: change the implementation once opaque pointers are supported
727
+ // in the SPIR-V specification.
728
+ SpvElementType = getOrCreateSPIRVIntegerType (8 , MIRBuilder);
729
+ // Get access to information about available extensions
730
+ const SPIRVSubtarget *ST =
731
+ static_cast <const SPIRVSubtarget *>(&MIRBuilder.getMF ().getSubtarget ());
732
+ auto SC = addressSpaceToStorageClass (AddrSpace, *ST);
733
+ // Null pointer means we have a loop in type definitions, make and
734
+ // return corresponding OpTypeForwardPointer.
735
+ if (SpvElementType == nullptr ) {
736
+ if (!ForwardPointerTypes.contains (Ty))
737
+ ForwardPointerTypes[Ty] = getOpTypeForwardPointer (SC, MIRBuilder);
738
+ return ForwardPointerTypes[Ty];
739
+ }
740
+ // If we have forward pointer associated with this type, use its register
741
+ // operand to create OpTypePointer.
742
+ if (ForwardPointerTypes.contains (Ty)) {
743
+ Register Reg = getSPIRVTypeID (ForwardPointerTypes[Ty]);
744
+ return getOpTypePointer (SC, SpvElementType, MIRBuilder, Reg);
733
745
}
734
- llvm_unreachable (" Unable to convert LLVM type to SPIRVType" );
746
+
747
+ return getOrCreateSPIRVPointerType (SpvElementType, MIRBuilder, SC);
735
748
}
736
749
737
750
SPIRVType *SPIRVGlobalRegistry::restOfCreateSPIRVType (
@@ -1139,11 +1152,13 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
1139
1152
SPIRV::StorageClass::StorageClass SC) {
1140
1153
const Type *PointerElementType = getTypeForSPIRVType (BaseType);
1141
1154
unsigned AddressSpace = storageClassToAddressSpace (SC);
1142
- Type *LLVMTy =
1143
- PointerType::get (const_cast <Type *>(PointerElementType), AddressSpace);
1155
+ Type *LLVMTy = TypedPointerType::get (const_cast <Type *>(PointerElementType),
1156
+ AddressSpace);
1157
+ // check if this type is already available
1144
1158
Register Reg = DT.find (PointerElementType, AddressSpace, CurMF);
1145
1159
if (Reg.isValid ())
1146
1160
return getSPIRVTypeForVReg (Reg);
1161
+ // create a new type
1147
1162
auto MIB = BuildMI (MIRBuilder.getMBB (), MIRBuilder.getInsertPt (),
1148
1163
MIRBuilder.getDebugLoc (),
1149
1164
MIRBuilder.getTII ().get (SPIRV::OpTypePointer))
@@ -1155,22 +1170,10 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
1155
1170
}
1156
1171
1157
1172
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType (
1158
- SPIRVType *BaseType, MachineInstr &I, const SPIRVInstrInfo &TII ,
1173
+ SPIRVType *BaseType, MachineInstr &I, const SPIRVInstrInfo &,
1159
1174
SPIRV::StorageClass::StorageClass SC) {
1160
- const Type *PointerElementType = getTypeForSPIRVType (BaseType);
1161
- unsigned AddressSpace = storageClassToAddressSpace (SC);
1162
- Type *LLVMTy =
1163
- PointerType::get (const_cast <Type *>(PointerElementType), AddressSpace);
1164
- Register Reg = DT.find (PointerElementType, AddressSpace, CurMF);
1165
- if (Reg.isValid ())
1166
- return getSPIRVTypeForVReg (Reg);
1167
- MachineBasicBlock &BB = *I.getParent ();
1168
- auto MIB = BuildMI (BB, I, I.getDebugLoc (), TII.get (SPIRV::OpTypePointer))
1169
- .addDef (createTypeVReg (CurMF->getRegInfo ()))
1170
- .addImm (static_cast <uint32_t >(SC))
1171
- .addUse (getSPIRVTypeID (BaseType));
1172
- DT.add (PointerElementType, AddressSpace, CurMF, getSPIRVTypeID (MIB));
1173
- return finishCreatingSPIRVType (LLVMTy, MIB);
1175
+ MachineIRBuilder MIRBuilder (I);
1176
+ return getOrCreateSPIRVPointerType (BaseType, MIRBuilder, SC);
1174
1177
}
1175
1178
1176
1179
Register SPIRVGlobalRegistry::getOrCreateUndef (MachineInstr &I,
0 commit comments