Explorar o código

MergeGepUse improvements (#4784)

- Added a comment warning  about using MergeGepUse while iterating.
- Changed MergeGepUse to return bool for whether anything actually changed.
- Adding GEP's user to worklist, even when GEP and GEP's source pointer GEP cannot be merged.
Adam Yang %!s(int64=2) %!d(string=hai) anos
pai
achega
0392e60dbc
Modificáronse 2 ficheiros con 18 adicións e 3 borrados
  1. 7 1
      include/dxc/DXIL/DxilUtil.h
  2. 11 2
      lib/DXIL/DxilUtilDbgInfoAndMisc.cpp

+ 7 - 1
include/dxc/DXIL/DxilUtil.h

@@ -61,7 +61,13 @@ namespace dxilutil {
                                    llvm::Type *Ty, DxilTypeSystem &typeSys);
   llvm::Type *GetArrayEltTy(llvm::Type *Ty);
   bool HasDynamicIndexing(llvm::Value *V);
-  void MergeGepUse(llvm::Value *V);
+
+  // Cleans up unnecessary chains of GEPs and bitcasts left over from certain
+  // optimizations. This function is NOT safe to call while iterating
+  // instructions either forward or backward. If V happens to be a GEP or
+  // bitcast, the function may delete V, instructions preceding V it, and
+  // instructions following V.
+  bool MergeGepUse(llvm::Value *V);
 
   // Find alloca insertion point, given instruction
   llvm::Instruction *FindAllocaInsertionPt(llvm::Instruction* I); // Considers entire parent function

+ 11 - 2
lib/DXIL/DxilUtilDbgInfoAndMisc.cpp

@@ -108,7 +108,8 @@ namespace hlsl {
 
 namespace dxilutil {
 
-void MergeGepUse(Value *V) {
+bool MergeGepUse(Value *V) {
+  bool changed = false;
   SmallVector<Value *, 16> worklist;
   auto addUsersToWorklist = [&worklist](Value *V) {
     if (!V->user_empty()) {
@@ -125,6 +126,7 @@ void MergeGepUse(Value *V) {
     V = worklist.pop_back_val();
     if (BitCastOperator *BCO = dyn_cast<BitCastOperator>(V)) {
       if (Value *NewV = dxilutil::TryReplaceBaseCastWithGep(V)) {
+        changed = true;
         worklist.push_back(NewV);
       } else {
         // merge any GEP users of the untranslated bitcast
@@ -137,8 +139,13 @@ void MergeGepUse(Value *V) {
         if (Value *newGEP = MergeGEP(prevGEP, GEP)) {
           worklist.push_back(newGEP);
           // delete prevGEP if no more users
-          if (prevGEP->user_empty() && isa<GetElementPtrInst>(prevGEP))
+          if (prevGEP->user_empty() && isa<GetElementPtrInst>(prevGEP)) {
             cast<GetElementPtrInst>(prevGEP)->eraseFromParent();
+            changed = true;
+          }
+        }
+        else {
+          addUsersToWorklist(GEP);
         }
       } else {
         // nothing to merge yet, add GEP users
@@ -146,6 +153,8 @@ void MergeGepUse(Value *V) {
       }
     }
   }
+
+  return changed;
 }
 
 std::unique_ptr<llvm::Module> LoadModuleFromBitcode(llvm::MemoryBuffer *MB,