[llvm] 04d4130 - Support converting pointers from opaque to typed

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 6 09:39:50 PDT 2022


Author: Chris Bieneman
Date: 2022-06-06T11:36:52-05:00
New Revision: 04d4130a513783eecbec426c8151c1d2fe086430

URL: https://github.com/llvm/llvm-project/commit/04d4130a513783eecbec426c8151c1d2fe086430
DIFF: https://github.com/llvm/llvm-project/commit/04d4130a513783eecbec426c8151c1d2fe086430.diff

LOG: Support converting pointers from opaque to typed

Using the pointer type analysis we can re-constitute typed pointers and
populate the correct types in the bitcasts throughout the IR.

This doesn't yet handle all cases, but this should be illustrative as
to the dirction and feasability of
the solution.

Reviewed By: pete

Differential Revision: https://reviews.llvm.org/D122270

Added: 
    llvm/test/tools/dxil-dis/opaque-gep.ll
    llvm/test/tools/dxil-dis/opaque-pointers.ll

Modified: 
    llvm/lib/Target/DirectX/DXILPrepare.cpp
    llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt
    llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp
    llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp
    llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index 5da9f12117a40..73420e3094f5d 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -94,8 +94,10 @@ class DXILPrepareModule : public ModulePass {
     Builder.SetInsertPoint(&Inst);
     // This code only gets hit in opaque-pointer mode, so the type of the
     // pointer doesn't matter.
-    return Builder.Insert(CastInst::Create(Instruction::BitCast, Operand,
-                                           Builder.getInt8PtrTy()));
+    PointerType *PtrTy = cast<PointerType>(Operand->getType());
+    return Builder.Insert(
+        CastInst::Create(Instruction::BitCast, Operand,
+                         Builder.getInt8PtrTy(PtrTy->getAddressSpace())));
   }
 
 public:

diff  --git a/llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt b/llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt
index a6864f0024945..3a48942239bc4 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt
+++ b/llvm/lib/Target/DirectX/DXILWriter/CMakeLists.txt
@@ -1,3 +1,5 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../)
+
 add_llvm_component_library(LLVMDXILBitWriter
   DXILBitcodeWriter.cpp
   DXILValueEnumerator.cpp

diff  --git a/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp
index 260242ebeb62d..f575a3a9d4bf9 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp
+++ b/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp
@@ -12,6 +12,7 @@
 
 #include "DXILBitcodeWriter.h"
 #include "DXILValueEnumerator.h"
+#include "PointerTypeAnalysis.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Bitcode/BitcodeCommon.h"
 #include "llvm/Bitcode/BitcodeReader.h"
@@ -88,6 +89,10 @@ class DXILBitcodeWriter {
     FUNCTION_INST_GEP_ABBREV,
   };
 
+  // Cache some types
+  Type *I8Ty;
+  Type *I8PtrTy;
+
   /// The stream created and owned by the client.
   BitstreamWriter &Stream;
 
@@ -117,14 +122,23 @@ class DXILBitcodeWriter {
   /// The start bit of the identification block.
   uint64_t BitcodeStartBit;
 
+  /// This maps values to their typed pointers
+  PointerTypeMap PointerMap;
+
 public:
   /// Constructs a ModuleBitcodeWriter object for the given Module,
   /// writing to the provided \p Buffer.
   DXILBitcodeWriter(const Module &M, SmallVectorImpl<char> &Buffer,
                     StringTableBuilder &StrtabBuilder, BitstreamWriter &Stream)
-      : Stream(Stream), StrtabBuilder(StrtabBuilder), M(M), VE(M, true),
-        Buffer(Buffer), BitcodeStartBit(Stream.GetCurrentBitNo()) {
+      : I8Ty(Type::getInt8Ty(M.getContext())),
+        I8PtrTy(TypedPointerType::get(I8Ty, 0)), Stream(Stream),
+        StrtabBuilder(StrtabBuilder), M(M), VE(M, I8PtrTy), Buffer(Buffer),
+        BitcodeStartBit(Stream.GetCurrentBitNo()),
+        PointerMap(PointerTypeAnalysis::run(M)) {
     GlobalValueId = VE.getValues().size();
+    // Enumerate the typed pointers
+    for (auto El : PointerMap)
+      VE.EnumerateType(El.second);
   }
 
   /// Emit the current module to the bitstream.
@@ -329,6 +343,9 @@ class DXILBitcodeWriter {
   unsigned getEncodedSyncScopeID(SyncScope::ID SSID) { return unsigned(SSID); }
 
   unsigned getEncodedAlign(MaybeAlign Alignment) { return encode(Alignment); }
+
+  unsigned getTypeID(Type *T, const Value *V = nullptr);
+  unsigned getTypeID(Type *T, const Function *F);
 };
 
 } // namespace dxil
@@ -532,6 +549,22 @@ unsigned DXILBitcodeWriter::getEncodedBinaryOpcode(unsigned Opcode) {
   }
 }
 
+unsigned DXILBitcodeWriter::getTypeID(Type *T, const Value *V) {
+  if (!T->isOpaquePointerTy())
+    return VE.getTypeID(T);
+  auto It = PointerMap.find(V);
+  if (It != PointerMap.end())
+    return VE.getTypeID(It->second);
+  return VE.getTypeID(I8PtrTy);
+}
+
+unsigned DXILBitcodeWriter::getTypeID(Type *T, const Function *F) {
+  auto It = PointerMap.find(F);
+  if (It != PointerMap.end())
+    return VE.getTypeID(It->second);
+  return VE.getTypeID(T);
+}
+
 unsigned DXILBitcodeWriter::getEncodedRMWOperation(AtomicRMWInst::BinOp Op) {
   switch (Op) {
   default:
@@ -993,7 +1026,6 @@ void DXILBitcodeWriter::writeTypeTable() {
     case Type::BFloatTyID:
     case Type::X86_AMXTyID:
     case Type::TokenTyID:
-    case Type::DXILPointerTyID:
       llvm_unreachable("These should never be used!!!");
       break;
     case Type::VoidTyID:
@@ -1031,25 +1063,46 @@ void DXILBitcodeWriter::writeTypeTable() {
       Code = bitc::TYPE_CODE_INTEGER;
       TypeVals.push_back(cast<IntegerType>(T)->getBitWidth());
       break;
-    case Type::PointerTyID: {
-      PointerType *PTy = cast<PointerType>(T);
+    case Type::DXILPointerTyID: {
+      TypedPointerType *PTy = cast<TypedPointerType>(T);
       // POINTER: [pointee type, address space]
       Code = bitc::TYPE_CODE_POINTER;
-      TypeVals.push_back(VE.getTypeID(PTy->getNonOpaquePointerElementType()));
+      TypeVals.push_back(getTypeID(PTy->getElementType()));
       unsigned AddressSpace = PTy->getAddressSpace();
       TypeVals.push_back(AddressSpace);
       if (AddressSpace == 0)
         AbbrevToUse = PtrAbbrev;
       break;
     }
+    case Type::PointerTyID: {
+      PointerType *PTy = cast<PointerType>(T);
+      // POINTER: [pointee type, address space]
+      Code = bitc::TYPE_CODE_POINTER;
+      // Emitting an empty struct type for the opaque pointer's type allows
+      // this to be order-independent. Non-struct types must be emitted in
+      // bitcode before they can be referenced.
+      if (PTy->isOpaquePointerTy()) {
+        TypeVals.push_back(false);
+        Code = bitc::TYPE_CODE_OPAQUE;
+        writeStringRecord(Stream, bitc::TYPE_CODE_STRUCT_NAME,
+                          "dxilOpaquePtrReservedName", StructNameAbbrev);
+      } else {
+        TypeVals.push_back(getTypeID(PTy->getNonOpaquePointerElementType()));
+        unsigned AddressSpace = PTy->getAddressSpace();
+        TypeVals.push_back(AddressSpace);
+        if (AddressSpace == 0)
+          AbbrevToUse = PtrAbbrev;
+      }
+      break;
+    }
     case Type::FunctionTyID: {
       FunctionType *FT = cast<FunctionType>(T);
       // FUNCTION: [isvararg, retty, paramty x N]
       Code = bitc::TYPE_CODE_FUNCTION;
       TypeVals.push_back(FT->isVarArg());
-      TypeVals.push_back(VE.getTypeID(FT->getReturnType()));
+      TypeVals.push_back(getTypeID(FT->getReturnType()));
       for (Type *PTy : FT->params())
-        TypeVals.push_back(VE.getTypeID(PTy));
+        TypeVals.push_back(getTypeID(PTy));
       AbbrevToUse = FunctionAbbrev;
       break;
     }
@@ -1059,7 +1112,7 @@ void DXILBitcodeWriter::writeTypeTable() {
       TypeVals.push_back(ST->isPacked());
       // Output all of the element types.
       for (Type *ElTy : ST->elements())
-        TypeVals.push_back(VE.getTypeID(ElTy));
+        TypeVals.push_back(getTypeID(ElTy));
 
       if (ST->isLiteral()) {
         Code = bitc::TYPE_CODE_STRUCT_ANON;
@@ -1084,7 +1137,7 @@ void DXILBitcodeWriter::writeTypeTable() {
       // ARRAY: [numelts, eltty]
       Code = bitc::TYPE_CODE_ARRAY;
       TypeVals.push_back(AT->getNumElements());
-      TypeVals.push_back(VE.getTypeID(AT->getElementType()));
+      TypeVals.push_back(getTypeID(AT->getElementType()));
       AbbrevToUse = ArrayAbbrev;
       break;
     }
@@ -1094,7 +1147,7 @@ void DXILBitcodeWriter::writeTypeTable() {
       // VECTOR [numelts, eltty]
       Code = bitc::TYPE_CODE_VECTOR;
       TypeVals.push_back(VT->getElementCount().getKnownMinValue());
-      TypeVals.push_back(VE.getTypeID(VT->getElementType()));
+      TypeVals.push_back(getTypeID(VT->getElementType()));
       break;
     }
     }
@@ -1151,7 +1204,7 @@ void DXILBitcodeWriter::writeModuleInfo() {
   };
   for (const GlobalVariable &GV : M.globals()) {
     UpdateMaxAlignment(GV.getAlign());
-    MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getValueType()));
+    MaxGlobalType = std::max(MaxGlobalType, getTypeID(GV.getValueType(), &GV));
     if (GV.hasSection()) {
       // Give section names unique ID's.
       unsigned &Entry = SectionMap[std::string(GV.getSection())];
@@ -1187,7 +1240,8 @@ void DXILBitcodeWriter::writeModuleInfo() {
   // Emit abbrev for globals, now that we know # sections and max alignment.
   unsigned SimpleGVarAbbrev = 0;
   if (!M.global_empty()) {
-    // Add an abbrev for common globals with no visibility or thread localness.
+    // Add an abbrev for common globals with no visibility or thread
+    // localness.
     auto Abbv = std::make_shared<BitCodeAbbrev>();
     Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_GLOBALVAR));
     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
@@ -1222,7 +1276,7 @@ void DXILBitcodeWriter::writeModuleInfo() {
     //             linkage, alignment, section, visibility, threadlocal,
     //             unnamed_addr, externally_initialized, dllstorageclass,
     //             comdat]
-    Vals.push_back(VE.getTypeID(GV.getValueType()));
+    Vals.push_back(getTypeID(GV.getValueType(), &GV));
     Vals.push_back(
         GV.getType()->getAddressSpace() << 2 | 2 |
         (GV.isConstant() ? 1 : 0)); // HLSL Change - bitwise | was used with
@@ -1258,7 +1312,7 @@ void DXILBitcodeWriter::writeModuleInfo() {
     // FUNCTION:  [type, callingconv, isproto, linkage, paramattrs, alignment,
     //             section, visibility, gc, unnamed_addr, prologuedata,
     //             dllstorageclass, comdat, prefixdata, personalityfn]
-    Vals.push_back(VE.getTypeID(F.getFunctionType()));
+    Vals.push_back(getTypeID(F.getFunctionType(), &F));
     Vals.push_back(F.getCallingConv());
     Vals.push_back(F.isDeclaration());
     Vals.push_back(getEncodedLinkage(F));
@@ -1286,7 +1340,7 @@ void DXILBitcodeWriter::writeModuleInfo() {
   // Emit the alias information.
   for (const GlobalAlias &A : M.aliases()) {
     // ALIAS: [alias type, aliasee val#, linkage, visibility]
-    Vals.push_back(VE.getTypeID(A.getValueType()));
+    Vals.push_back(getTypeID(A.getValueType(), &A));
     Vals.push_back(VE.getValueID(A.getAliasee()));
     Vals.push_back(getEncodedLinkage(A));
     Vals.push_back(getEncodedVisibility(A));
@@ -1303,7 +1357,7 @@ void DXILBitcodeWriter::writeValueAsMetadata(
     const ValueAsMetadata *MD, SmallVectorImpl<uint64_t> &Record) {
   // Mimic an MDNode with a value as one operand.
   Value *V = MD->getValue();
-  Record.push_back(VE.getTypeID(V->getType()));
+  Record.push_back(getTypeID(V->getType()));
   Record.push_back(VE.getValueID(V));
   Stream.EmitRecord(bitc::METADATA_VALUE, Record, 0);
   Record.clear();
@@ -1907,7 +1961,7 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
     // If we need to switch types, do so now.
     if (V->getType() != LastTy) {
       LastTy = V->getType();
-      Record.push_back(VE.getTypeID(LastTy));
+      Record.push_back(getTypeID(LastTy));
       Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record,
                         CONSTANTS_SETTYPE_ABBREV);
       Record.clear();
@@ -2042,7 +2096,7 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
         if (Instruction::isCast(CE->getOpcode())) {
           Code = bitc::CST_CODE_CE_CAST;
           Record.push_back(getEncodedCastOpcode(CE->getOpcode()));
-          Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+          Record.push_back(getTypeID(C->getOperand(0)->getType()));
           Record.push_back(VE.getValueID(C->getOperand(0)));
           AbbrevToUse = CONSTANTS_CE_CAST_Abbrev;
         } else {
@@ -2061,9 +2115,9 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
         const auto *GO = cast<GEPOperator>(C);
         if (GO->isInBounds())
           Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
-        Record.push_back(VE.getTypeID(GO->getSourceElementType()));
+        Record.push_back(getTypeID(GO->getSourceElementType()));
         for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
-          Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
+          Record.push_back(getTypeID(C->getOperand(i)->getType()));
           Record.push_back(VE.getValueID(C->getOperand(i)));
         }
         break;
@@ -2076,16 +2130,16 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
         break;
       case Instruction::ExtractElement:
         Code = bitc::CST_CODE_CE_EXTRACTELT;
-        Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        Record.push_back(getTypeID(C->getOperand(0)->getType()));
         Record.push_back(VE.getValueID(C->getOperand(0)));
-        Record.push_back(VE.getTypeID(C->getOperand(1)->getType()));
+        Record.push_back(getTypeID(C->getOperand(1)->getType()));
         Record.push_back(VE.getValueID(C->getOperand(1)));
         break;
       case Instruction::InsertElement:
         Code = bitc::CST_CODE_CE_INSERTELT;
         Record.push_back(VE.getValueID(C->getOperand(0)));
         Record.push_back(VE.getValueID(C->getOperand(1)));
-        Record.push_back(VE.getTypeID(C->getOperand(2)->getType()));
+        Record.push_back(getTypeID(C->getOperand(2)->getType()));
         Record.push_back(VE.getValueID(C->getOperand(2)));
         break;
       case Instruction::ShuffleVector:
@@ -2097,7 +2151,7 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
           Code = bitc::CST_CODE_CE_SHUFFLEVEC;
         } else {
           Code = bitc::CST_CODE_CE_SHUFVEC_EX;
-          Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+          Record.push_back(getTypeID(C->getOperand(0)->getType()));
         }
         Record.push_back(VE.getValueID(C->getOperand(0)));
         Record.push_back(VE.getValueID(C->getOperand(1)));
@@ -2106,7 +2160,7 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
       case Instruction::ICmp:
       case Instruction::FCmp:
         Code = bitc::CST_CODE_CE_CMP;
-        Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        Record.push_back(getTypeID(C->getOperand(0)->getType()));
         Record.push_back(VE.getValueID(C->getOperand(0)));
         Record.push_back(VE.getValueID(C->getOperand(1)));
         Record.push_back(CE->getPredicate());
@@ -2114,7 +2168,7 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
       }
     } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
       Code = bitc::CST_CODE_BLOCKADDRESS;
-      Record.push_back(VE.getTypeID(BA->getFunction()->getType()));
+      Record.push_back(getTypeID(BA->getFunction()->getType()));
       Record.push_back(VE.getValueID(BA->getFunction()));
       Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock()));
     } else {
@@ -2157,7 +2211,7 @@ bool DXILBitcodeWriter::pushValueAndType(const Value *V, unsigned InstID,
   // Make encoding relative to the InstID.
   Vals.push_back(InstID - ValID);
   if (ValID >= InstID) {
-    Vals.push_back(VE.getTypeID(V->getType()));
+    Vals.push_back(getTypeID(V->getType(), V));
     return true;
   }
   return false;
@@ -2190,7 +2244,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
       Code = bitc::FUNC_CODE_INST_CAST;
       if (!pushValueAndType(I.getOperand(0), InstID, Vals))
         AbbrevToUse = (unsigned)FUNCTION_INST_CAST_ABBREV;
-      Vals.push_back(VE.getTypeID(I.getType()));
+      Vals.push_back(getTypeID(I.getType(), &I));
       Vals.push_back(getEncodedCastOpcode(I.getOpcode()));
     } else {
       assert(isa<BinaryOperator>(I) && "Unknown instruction!");
@@ -2213,7 +2267,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
     AbbrevToUse = (unsigned)FUNCTION_INST_GEP_ABBREV;
     auto &GEPInst = cast<GetElementPtrInst>(I);
     Vals.push_back(GEPInst.isInBounds());
-    Vals.push_back(VE.getTypeID(GEPInst.getSourceElementType()));
+    Vals.push_back(getTypeID(GEPInst.getSourceElementType()));
     for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
       pushValueAndType(I.getOperand(i), InstID, Vals);
     break;
@@ -2294,7 +2348,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
   case Instruction::Switch: {
     Code = bitc::FUNC_CODE_INST_SWITCH;
     const SwitchInst &SI = cast<SwitchInst>(I);
-    Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
+    Vals.push_back(getTypeID(SI.getCondition()->getType()));
     pushValue(SI.getCondition(), InstID, Vals);
     Vals.push_back(VE.getValueID(SI.getDefaultDest()));
     for (auto Case : SI.cases()) {
@@ -2304,7 +2358,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
   } break;
   case Instruction::IndirectBr:
     Code = bitc::FUNC_CODE_INST_INDIRECTBR;
-    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+    Vals.push_back(getTypeID(I.getOperand(0)->getType()));
     // Encode the address operand as relative, but not the basic blocks.
     pushValue(I.getOperand(0), InstID, Vals);
     for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i)
@@ -2321,7 +2375,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
     Vals.push_back(II->getCallingConv() | 1 << 13);
     Vals.push_back(VE.getValueID(II->getNormalDest()));
     Vals.push_back(VE.getValueID(II->getUnwindDest()));
-    Vals.push_back(VE.getTypeID(FTy));
+    Vals.push_back(getTypeID(FTy));
     pushValueAndType(Callee, InstID, Vals);
 
     // Emit value #'s for the fixed parameters.
@@ -2352,7 +2406,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
     // negative valued IDs.  This is most common for PHIs, so we use
     // signed VBRs.
     SmallVector<uint64_t, 128> Vals64;
-    Vals64.push_back(VE.getTypeID(PN.getType()));
+    Vals64.push_back(getTypeID(PN.getType()));
     for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
       pushValueSigned(PN.getIncomingValue(i), InstID, Vals64);
       Vals64.push_back(VE.getValueID(PN.getIncomingBlock(i)));
@@ -2366,7 +2420,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
   case Instruction::LandingPad: {
     const LandingPadInst &LP = cast<LandingPadInst>(I);
     Code = bitc::FUNC_CODE_INST_LANDINGPAD;
-    Vals.push_back(VE.getTypeID(LP.getType()));
+    Vals.push_back(getTypeID(LP.getType()));
     Vals.push_back(LP.isCleanup());
     Vals.push_back(LP.getNumClauses());
     for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) {
@@ -2382,8 +2436,8 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
   case Instruction::Alloca: {
     Code = bitc::FUNC_CODE_INST_ALLOCA;
     const AllocaInst &AI = cast<AllocaInst>(I);
-    Vals.push_back(VE.getTypeID(AI.getAllocatedType()));
-    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+    Vals.push_back(getTypeID(AI.getAllocatedType()));
+    Vals.push_back(getTypeID(I.getOperand(0)->getType()));
     Vals.push_back(VE.getValueID(I.getOperand(0))); // size.
     using APV = AllocaPackedValues;
     unsigned Record = 0;
@@ -2406,7 +2460,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
       if (!pushValueAndType(I.getOperand(0), InstID, Vals)) // ptr
         AbbrevToUse = (unsigned)FUNCTION_INST_LOAD_ABBREV;
     }
-    Vals.push_back(VE.getTypeID(I.getType()));
+    Vals.push_back(getTypeID(I.getType()));
     Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment()) + 1);
     Vals.push_back(cast<LoadInst>(I).isVolatile());
     if (cast<LoadInst>(I).isAtomic()) {
@@ -2468,7 +2522,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
     Vals.push_back(VE.getAttributeListID(CI.getAttributes()));
     Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()) |
                    unsigned(CI.isMustTailCall()) << 14 | 1 << 15);
-    Vals.push_back(VE.getTypeID(FTy));
+    Vals.push_back(getTypeID(FTy, CI.getCalledFunction()));
     pushValueAndType(CI.getCalledOperand(), InstID, Vals); // Callee
 
     // Emit value #'s for the fixed parameters.
@@ -2489,9 +2543,9 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID,
   }
   case Instruction::VAArg:
     Code = bitc::FUNC_CODE_INST_VAARG;
-    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); // valistty
-    pushValue(I.getOperand(0), InstID, Vals);                 // valist.
-    Vals.push_back(VE.getTypeID(I.getType()));                // restype.
+    Vals.push_back(getTypeID(I.getOperand(0)->getType())); // valistty
+    pushValue(I.getOperand(0), InstID, Vals);              // valist.
+    Vals.push_back(getTypeID(I.getType()));                // restype.
     break;
   }
 
@@ -2582,9 +2636,6 @@ void DXILBitcodeWriter::writeUseList(UseListOrder &&Order) {
 }
 
 void DXILBitcodeWriter::writeUseListBlock(const Function *F) {
-  assert(VE.shouldPreserveUseListOrder() &&
-         "Expected to be preserving use-list order");
-
   auto hasMore = [&]() {
     return !VE.UseListOrders.empty() && VE.UseListOrders.back().F == F;
   };
@@ -2667,8 +2718,8 @@ void DXILBitcodeWriter::writeFunction(const Function &F) {
 
   if (NeedsMetadataAttachment)
     writeFunctionMetadataAttachment(F);
-  if (VE.shouldPreserveUseListOrder())
-    writeUseListBlock(&F);
+
+  writeUseListBlock(&F);
   VE.purgeFunction();
   Stream.ExitBlock();
 }
@@ -2896,8 +2947,7 @@ void DXILBitcodeWriter::write() {
   writeFunctionLevelValueSymbolTable(M.getValueSymbolTable());
 
   // Emit module-level use-lists.
-  if (VE.shouldPreserveUseListOrder())
-    writeUseListBlock(nullptr);
+  writeUseListBlock(nullptr);
 
   // Emit function bodies.
   for (const Function &F : M)

diff  --git a/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp b/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp
index 286b2c8a20af1..69c3d56ae2fb2 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp
+++ b/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.cpp
@@ -358,15 +358,10 @@ static UseListOrderStack predictUseListOrder(const Module &M) {
   return Stack;
 }
 
-static bool isIntOrIntVectorValue(const std::pair<const Value *, unsigned> &V) {
-  return V.first->getType()->isIntOrIntVectorTy();
-}
-
-ValueEnumerator::ValueEnumerator(const Module &M,
-                                 bool ShouldPreserveUseListOrder)
-    : ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
-  if (ShouldPreserveUseListOrder)
-    UseListOrders = predictUseListOrder(M);
+ValueEnumerator::ValueEnumerator(const Module &M, Type *PrefixType) {
+  EnumerateType(PrefixType);
+  
+  UseListOrders = predictUseListOrder(M);
 
   // Enumerate the global variables.
   for (const GlobalVariable &GV : M.globals()) {
@@ -393,9 +388,6 @@ ValueEnumerator::ValueEnumerator(const Module &M,
     EnumerateType(GIF.getValueType());
   }
 
-  // Remember what is the cutoff between globalvalue's and other constants.
-  unsigned FirstConstant = Values.size();
-
   // Enumerate the global variable initializers and attributes.
   for (const GlobalVariable &GV : M.globals()) {
     if (GV.hasInitializer())
@@ -499,9 +491,6 @@ ValueEnumerator::ValueEnumerator(const Module &M,
       }
   }
 
-  // Optimize constant ordering.
-  OptimizeConstants(FirstConstant, Values.size());
-
   // Organize metadata ordering.
   organizeMetadata();
 }
@@ -579,38 +568,6 @@ void ValueEnumerator::print(raw_ostream &OS, const MetadataMapType &Map,
   }
 }
 
-/// OptimizeConstants - Reorder constant pool for denser encoding.
-void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {
-  if (CstStart == CstEnd || CstStart + 1 == CstEnd)
-    return;
-
-  if (ShouldPreserveUseListOrder)
-    // Optimizing constants makes the use-list order 
diff icult to predict.
-    // Disable it for now when trying to preserve the order.
-    return;
-
-  std::stable_sort(Values.begin() + CstStart, Values.begin() + CstEnd,
-                   [this](const std::pair<const Value *, unsigned> &LHS,
-                          const std::pair<const Value *, unsigned> &RHS) {
-                     // Sort by plane.
-                     if (LHS.first->getType() != RHS.first->getType())
-                       return getTypeID(LHS.first->getType()) <
-                              getTypeID(RHS.first->getType());
-                     // Then by frequency.
-                     return LHS.second > RHS.second;
-                   });
-
-  // Ensure that integer and vector of integer constants are at the start of the
-  // constant pool.  This is important so that GEP structure indices come before
-  // gep constant exprs.
-  std::stable_partition(Values.begin() + CstStart, Values.begin() + CstEnd,
-                        isIntOrIntVectorValue);
-
-  // Rebuild the modified portion of ValueMap.
-  for (; CstStart != CstEnd; ++CstStart)
-    ValueMap[Values[CstStart].first] = CstStart + 1;
-}
-
 /// EnumerateValueSymbolTable - Insert all of the values in the specified symbol
 /// table into the values table.
 void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
@@ -1098,9 +1055,6 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
     ValueMap[&BB] = BasicBlocks.size();
   }
 
-  // Optimize the constant layout.
-  OptimizeConstants(FirstFuncConstantID, Values.size());
-
   // Add the function's parameter attributes so they are available for use in
   // the function's instruction.
   EnumerateAttributes(F.getAttributes());

diff  --git a/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.h b/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.h
index c4a842bc5b38d..6cf339b7a5cd1 100644
--- a/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.h
+++ b/llvm/lib/Target/DirectX/DXILWriter/DXILValueEnumerator.h
@@ -106,8 +106,6 @@ class ValueEnumerator {
   };
   SmallDenseMap<unsigned, MDRange, 1> FunctionMDInfo;
 
-  bool ShouldPreserveUseListOrder;
-
   using AttributeGroupMapType = DenseMap<IndexAndAttrSet, unsigned>;
   AttributeGroupMapType AttributeGroupMap;
   std::vector<IndexAndAttrSet> AttributeGroups;
@@ -141,7 +139,7 @@ class ValueEnumerator {
   unsigned FirstInstID;
 
 public:
-  ValueEnumerator(const Module &M, bool ShouldPreserveUseListOrder);
+  ValueEnumerator(const Module &M, Type *PrefixType);
   ValueEnumerator(const ValueEnumerator &) = delete;
   ValueEnumerator &operator=(const ValueEnumerator &) = delete;
 
@@ -164,8 +162,6 @@ class ValueEnumerator {
 
   unsigned numMDs() const { return MDs.size(); }
 
-  bool shouldPreserveUseListOrder() const { return ShouldPreserveUseListOrder; }
-
   unsigned getTypeID(Type *T) const {
     TypeMapType::const_iterator I = TypeMap.find(T);
     assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
@@ -242,8 +238,9 @@ class ValueEnumerator {
   void purgeFunction();
   uint64_t computeBitsRequiredForTypeIndicies() const;
 
+  void EnumerateType(Type *T);
+
 private:
-  void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
 
   /// Reorder the reachable metadata.
   ///
@@ -298,7 +295,6 @@ class ValueEnumerator {
   void EnumerateFunctionLocalListMetadata(unsigned F, const DIArgList *Arglist);
   void EnumerateNamedMDNode(const NamedMDNode *NMD);
   void EnumerateValue(const Value *V);
-  void EnumerateType(Type *T);
   void EnumerateOperandType(const Value *V);
   void EnumerateAttributes(AttributeList PAL);
 

diff  --git a/llvm/test/tools/dxil-dis/opaque-gep.ll b/llvm/test/tools/dxil-dis/opaque-gep.ll
new file mode 100644
index 0000000000000..fd3f608fac015
--- /dev/null
+++ b/llvm/test/tools/dxil-dis/opaque-gep.ll
@@ -0,0 +1,22 @@
+; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+target triple = "dxil-unknown-unknown"
+
+define i32 @fn(ptr %0)  {
+  %2 = getelementptr i32, ptr %0, i32 4
+  %3 = load i32, ptr %2
+  ret i32 %3
+}
+
+; CHECK:        define i32 @fn(i32*) 
+; CHECK-NEXT:   %2 = getelementptr i32, i32* %0, i32 4
+; CHECK-NEXT:   %3 = load i32, i32* %2, align 4
+
+define i32 @fn2(ptr addrspace(1) %0)  {
+  %2 = getelementptr i32, ptr addrspace(1) %0, i32 4
+  %3 = load i32, ptr addrspace(1) %2
+  ret i32 %3
+}
+
+; CHECK:        define i32 @fn2(i32 addrspace(1)*) 
+; CHECK-NEXT:   %2 = getelementptr i32, i32 addrspace(1)* %0, i32 4
+; CHECK-NEXT:   %3 = load i32, i32 addrspace(1)* %2, align 4

diff  --git a/llvm/test/tools/dxil-dis/opaque-pointers.ll b/llvm/test/tools/dxil-dis/opaque-pointers.ll
new file mode 100644
index 0000000000000..4e63b23ab1650
--- /dev/null
+++ b/llvm/test/tools/dxil-dis/opaque-pointers.ll
@@ -0,0 +1,59 @@
+; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
+target triple = "dxil-unknown-unknown"
+
+define i64 @test(ptr %p) {
+  store i32 0, ptr %p
+  %v = load i64, ptr %p
+  ret i64 %v
+}
+
+; CHECK: define i64 @test(i8* %p) {
+; CHECK-NEXT: %1 = bitcast i8* %p to i32*
+; CHECK-NEXT: store i32 0, i32* %1, align 4
+; CHECK-NEXT: %2 = bitcast i8* %p to i64*
+; CHECK-NEXT: %3 = load i64, i64* %2, align 8
+
+define i64 @test2(ptr %p) {
+  store i64 0, ptr %p
+  %v = load i64, ptr %p
+  ret i64 %v
+}
+
+; CHECK: define i64 @test2(i64* %p) {
+; CHECK-NEXT: store i64 0, i64* %p, align 8
+; CHECK-NEXT: %v = load i64, i64* %p, align 8
+
+define i64 @test3(ptr addrspace(1) %p) {
+  store i32 0, ptr addrspace(1) %p
+  %v = load i64, ptr addrspace(1) %p
+  ret i64 %v
+}
+
+; CHECK: define i64 @test3(i8 addrspace(1)* %p) {
+; CHECK-NEXT: %1 = bitcast i8 addrspace(1)* %p to i32 addrspace(1)*
+; CHECK-NEXT: store i32 0, i32 addrspace(1)* %1, align 4
+; CHECK-NEXT: %2 = bitcast i8 addrspace(1)* %p to i64 addrspace(1)*
+; CHECK-NEXT: %3 = load i64, i64 addrspace(1)* %2, align 8
+
+define i64 @test4(ptr addrspace(1) %p) {
+  store i64 0, ptr addrspace(1) %p
+  %v = load i64, ptr addrspace(1) %p
+  ret i64 %v
+}
+
+; CHECK: define i64 @test4(i64 addrspace(1)* %p) {
+; CHECK-NEXT: store i64 0, i64 addrspace(1)* %p, align 8
+; CHECK-NEXT: %v = load i64, i64 addrspace(1)* %p, align 8
+
+
+define i64 @test5(ptr %p) {
+  %casted = addrspacecast ptr %p to ptr addrspace(1)
+  store i64 0, ptr addrspace(1) %casted
+  %v = load i64, ptr addrspace(1) %casted
+  ret i64 %v
+}
+
+; CHECK: define i64 @test5(i8* %p) {
+; CHECK-NEXT: %casted = addrspacecast i8* %p to i64 addrspace(1)*
+; CHECK-NEXT: store i64 0, i64 addrspace(1)* %casted, align 8
+; CHECK-NEXT: %v = load i64, i64 addrspace(1)* %casted, align 8


        


More information about the llvm-commits mailing list